# Credits, Rate Limits & Errors



The platform meters credits per successful billed response. Failed calls are free. Credits never expire. Most endpoints cost 1 credit; basic video info is free and full video info costs 1 credit. See [Pricing](/pricing) for packs.

Rate limits [#rate-limits]

| Tier                      | Rate limit                          | Burst Capacity                                          |
| :------------------------ | :---------------------------------- | :------------------------------------------------------ |
| Free (200 signup credits) | 1 req/s, 100 requests per day (UTC) | 20                                                      |
| Starter ($9 pack)         | 300 RPM (5 req/s)                   | 50                                                      |
| Popular ($29 pack)        | 600 RPM (10 req/s)                  | 100                                                     |
| Value ($79 pack)          | 3,000 RPM (50 req/s)                | 300                                                     |
| Reserved / Enterprise     | Written reservation above 3,000 RPM | [Contact us](https://ytapi.dev/contact?utm_source=docs) |

Customer `Cache-Control: no-cache` is ignored. Cache policy is server-side.

Credit Schedule [#credit-schedule]

| API Feature               | Endpoint                                                 | Cost                        |
| :------------------------ | :------------------------------------------------------- | :-------------------------- |
| Transcript                | [`POST /v1/transcripts`](/transcripts/extract)           | <CreditBadge credits={1} /> |
| Basic video info          | [`GET /v1/videos/{id}/basic-info`](/videos/basic-info)   | <CreditBadge credits={0} /> |
| Full video info           | [`GET /v1/videos/{id}/video-info`](/videos/video-info)   | <CreditBadge credits={1} /> |
| Most replayed moments     | [`GET /v1/videos/{id}/heatmap`](/videos/heatmap)         | <CreditBadge credits={1} /> |
| Comments (per page)       | [`GET /v1/videos/{id}/comments`](/videos/comments)       | <CreditBadge credits={1} /> |
| Playlist Details          | [`GET /v1/playlists/{id}`](/playlists/get)               | <CreditBadge credits={1} /> |
| Channel Profile           | [`GET /v1/channels/{id}`](/channels/get)                 | <CreditBadge credits={1} /> |
| Channel Latest            | [`GET /v1/channels/{id}/latest`](/channels/latest)       | <CreditBadge credits={1} /> |
| Channel Playlists         | [`GET /v1/channels/{id}/playlists`](/channels/playlists) | <CreditBadge credits={1} /> |
| Search                    | [`GET /v1/search`](/search/query)                        | <CreditBadge credits={1} /> |
| Search suggestions        | [`GET /v1/search/suggestions`](/search/suggestions)      | <CreditBadge credits={0} /> |
| Batch Processing (Submit) | [`POST /v1/batch`](/batch/run)                           | 1 credit / successful task  |
| Batch Processing (Status) | [`GET /v1/batch/{id}`](/batch/get)                       | <CreditBadge credits={0} /> |

<Callout type="info" title="Batch Pricing Details">
  Batch processing supports asynchronous execution of up to 100 tasks per job across a concurrent worker pool for `transcript` and `basic_info`. Every successfully processed task costs 1 credit. Please note: while individual single `GET /v1/videos/{id}/basic-info` lookups are free, batch processing of `basic_info` is billed at 1 credit per successful task due to high-concurrency server cluster capacity. Failed tasks cost 0 credits.
</Callout>

***

Error Response Format [#error-response-format]

All errors return a standard structured JSON error envelope:

```json
{
  "error": {
    "code": "video_unavailable",
    "message": "This video is unavailable or captions are disabled.",
    "retryable": false
  }
}
```

***

HTTP Status Codes [#http-status-codes]

<Callout type="error" title="400 — Bad Request">
  Missing required parameters (e.g. invalid video ID or empty search query). Check your request payload.
</Callout>

<Callout type="error" title="401 — Unauthorized">
  Missing or invalid API key in `Authorization: Bearer <key>` or `X-API-Key: <key>`. Verify your key in the [Dashboard](https://ytapi.dev/app/api-keys?utm_source=docs).
</Callout>

<Callout type="warn" title="402 — Payment Required">
  Credit balance depleted. Buy a pack in the [billing dashboard](https://ytapi.dev/app/billing?utm_source=docs). Failed requests are still free. Accounts that bought a pack get an email when the balance drops to 10% of their last pack, and another when it reaches 0.
</Callout>

<Callout type="info" title="404 — Not Found">
  Video does not exist, is private or members-only, or captions are unavailable for the requested language. The error `message` says which, e.g. `This video is members-only.`
</Callout>

<Callout type="warn" title="409 — Conflict">
  `idempotency_conflict` (`retryable: false`): the `Idempotency-Key` sent with `POST /v1/batch` was already used for a different request in the last 24 hours. Retrying with the same key returns the same error. Send the new request with a new key. See [Submit batch job](/batch/run).
</Callout>

<Callout type="warn" title="429 — Too Many Requests">
  Rate limit exceeded. Check the `Retry-After` header for seconds until reset. See [Authentication](/authentication) for tier limits. Free keys that reach 100 requests in a day get the code `daily_limit_exceeded`, with `Retry-After` counting down to 00:00 UTC and the `X-RateLimit-Daily-Limit` / `X-RateLimit-Daily-Remaining` headers. Any credit pack removes the daily limit.
</Callout>

<Callout type="error" title="500 — Internal Error">
  Upstream extraction error. Credits are **automatically refunded** for failed requests.
</Callout>
