# How do I track how a Bilibili video's views grow over time?

> Build an hourly view curve for any public Bilibili video by polling its stats with the BV id. Cost for a day, a week or ten videos, and a cron-ready script.

Canonical page: https://okdata.online/answers/bilibili-track-video-views-over-time/

**Short answer: **Poll Bilibili video detail with the BV id on a schedule and store each reading with its timestamp. Each reading costs $0.002, so hourly tracking for a week is $0.336 per video, and ten videos for a week is $3.36. You get views, likes, coins, favorites and danmaku count in every reading.

Your sponsored video goes live on Friday at 8 pm, and the creator promised 300,000 views in the first week. You would like to see the curve, not just the final number: did it take off on Saturday, stall on Monday, get a second wind when it hit the popular board? Bilibili shows only the current count, so the way to get a curve is to read that count on a schedule and keep every reading.

## The endpoint

[Bilibili video detail](/apis/bilibili/videos/get/) returns a video's current numbers by BV id. With `view=full` each reading carries views, likes, comments, shares and favorites, plus coins and danmaku count under `ext`. The response also has `meta.fetched_at`, the time to plot against.

## What a schedule costs

| Plan | Readings | Cost |
|---|---|---|
| Hourly for the first 24 hours | 24 | $0.048 |
| Hourly for 7 days, one video | 168 | $0.336 |
| Hourly for 7 days, ten videos | 1,680 | $3.36 |
| Daily for 30 days, one video | 30 | $0.06 |

A sensible plan is hourly for the first three days and daily after that. Most of a Bilibili video's views arrive early.

## A script for cron

Run it every hour with `0 * * * * python track.py`:

```python
import csv, datetime, os, requests

URL = "https://api.okdata.online/v1/bilibili/videos/get"
H = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
VIDEOS = ["BV1xx411c7mD"]

hour = datetime.datetime.utcnow().strftime("%Y%m%d%H")
with open("views.csv", "a", newline="") as f:
    w = csv.writer(f)
    for bv in VIDEOS:
        # One key per video per hour: if cron retries, the second run replays for free.
        headers = {**H, "Idempotency-Key": f"{bv}-{hour}"}
        body = requests.get(URL, headers=headers, params={"id": bv, "view": "full"}, timeout=60).json()
        if body["code"] != "ok":
            print(bv, body["code"], body["message"])
            continue
        v = body["data"]["item"]
        w.writerow([body["meta"]["fetched_at"], bv, v["metrics"]["views"], v["metrics"]["likes"],
                    v["ext"]["coins"], v["metrics"]["favorites"], v["ext"]["danmaku"]])
```

Open `views.csv` in a spreadsheet and chart views against time, or diff consecutive rows to get views per hour.

## What to expect from the numbers

- Bilibili updates its public counter in batches, so an hour can look flat and the next one jumps. Read trends over several hours, not single steps.
- Polling every minute buys you nothing: the counter does not move that fast, and each reading is a paid call.
- These are the public numbers anyone can see. Completion rate, traffic sources and audience data stay inside the uploader's creator center.
- If the video is taken down, the call returns `not_found` and is not charged.

## Better options in some cases

If you sponsored the video, ask the creator for a creator-center export after a week. It has data no outside reading can match, and the hourly public curve is a good way to check it. Third-party analytics dashboards also chart Bilibili videos if you prefer a ready-made view, and the open-source bilibili-api library can do the same polling for free if you run and maintain it. For tracking a whole set of rivals rather than one video, see the [competitor monitoring guide](/solutions/competitor-monitoring/).

## Endpoints used

- [Bilibili video detail](https://okdata.online/apis/bilibili/videos/get/) `bilibili.videos.get`: $0.002 per call

Updated 2026-11-12
