Disclosure: I am involved with EasyDown, the API used in the examples below. This is a practical integration note for developers who need a backend-friendly Bilibili API for supported public URLs.
When someone searches for bilibili api, the intent is often different from a one-off "download Bilibili video" search. They are usually building something: a media ingestion workflow, an internal content tool, a clipping queue, a moderation queue, or a downloader backend that has to turn public URLs into predictable JSON.
This post shows a small Python pattern for parsing public Bilibili URLs with EasyDown and then reading the normalized metadata and media fields your app can use.
The endpoint used below is documented here: EasyDown Bilibili API documentation.
Supported public URL shapes
The Bilibili endpoint supports mainland China Bilibili links such as:
https://www.bilibili.com/video/BV1sW4y197cE/https://www.bilibili.com/video/av45306969/https://b23.tv/INJgdaibilibili.com/bangumi/play/{id}bilibili.com/cheese/play/{id}
It does not cover bilibili.tv or bili.im international links.
Request shape
The request is a server-side POST with a bearer token:
POST https://api.easydown.org/api/v1/platforms/bilibili/parse
Authorization: Bearer <token>
Content-Type: application/json
{
"url": "https://www.bilibili.com/video/BV1sW4y197cE/"
}
Python example
import os
import requests
API_URL = "https://api.easydown.org/api/v1/platforms/bilibili/parse"
def parse_bilibili(public_url: str) -> dict:
token = os.environ["EASYDOWN_API_TOKEN"]
response = requests.post(
API_URL,
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
},
json={"url": public_url},
timeout=60,
)
payload = response.json()
if response.status_code != 200 or payload.get("status") != 200:
raise RuntimeError(payload.get("msg") or "Bilibili parse failed")
return payload["data"]
result = parse_bilibili("https://www.bilibili.com/video/BV1sW4y197cE/")
media = result.get("media", {})
platform_data = result.get("platformData", {})
print({
"title": media.get("title") or platform_data.get("title"),
"thumbnail": media.get("thumbnail") or platform_data.get("pic"),
"duration": media.get("duration"),
"video_count": len(media.get("videos", [])),
"audio_count": len(media.get("audios", [])),
})
In a real app, keep EASYDOWN_API_TOKEN in your backend environment, not in client-side JavaScript.
Fields to store
For most product workflows, I would store a small normalized subset instead of the whole upstream object:
- original public Bilibili URL
- normalized title
- thumbnail URL
- duration
- selected video rendition
- selected audio rendition when the stream is separate
- parse timestamp
- platform response version
That keeps your database stable even if Bilibili exposes extra public fields later.
Error handling
Your app should explain failures in product terms:
- unsupported URL family
- private, deleted, paid, DRM, live, or region-restricted content
- upstream timeout or temporary upstream failure
- expired signed media URL
- authentication or validation error
EasyDown documents that failed requests do not consume credits. A successful parse consumes one credit only after downloadable media is returned.
Pricing check
If you are comparing a hosted Bilibili API with maintaining your own parser, the useful comparison is cost per successful parse plus the engineering time saved on URL normalization, stream refresh, and failure handling.
EasyDown publishes current credit packs and monthly plans on the API pricing page.
Top comments (0)