# YouTube Transcript API

Beta

Returns the timed transcript of a public YouTube video, short or live replay: the creator's manual captions when they exist, otherwise YouTube's auto-generated track, in the language you ask for. Videos without any caption track are transcribed from their audio with speech-to-text. Accepts every YouTube URL form (watch, youtu.be, shorts, live, embed, music.) or a bare 11-character video ID.

[Get 100 free credits](https://staging-fly.socialtap.dev/signup/?next=%2Fplayground%2F%3Fendpoint%3Dyoutube.transcript) · [API reference](https://staging-fly.socialtap.dev/docs/reference/youtube/transcript/index.md) · [Try it](https://staging-fly.socialtap.dev/playground/?endpoint=youtube.transcript)

- **Price**: From **1 credit** per request, up to 122 credits$0.75–$1.45 per 1,000 requests
- **Request**: `GET /v1/youtube/transcript`One API key, one JSON schema
- **Input**: `url`e.g. `https://www.youtube.com/watch?v=dQw4w9WgXcQ`
- **Measured**: p50 511 ms · 96.5% success

Use cases

## What teams build with it. From one request.

- Summarize or search video content with LLMs
- Build subtitle and translation tools
- Index a channel's back catalog for RAG
- Repurpose videos into articles and posts

What you get

## Transcripts in one schema. The same on every platform.

- **`platform`string**: Platform the media is hosted on.
- **`id`string**: Platform-native ID of the post (equals post.id).
- **`url`string**: Canonical URL of the post.
- **`language`string**: BCP-47 language of the returned transcript; null when unknown.
- **`source`string**: captions = platform caption track; asr = speech-to-text on the audio. New values may be added.
- **`is_auto_generated`boolean**: True when the track was machine-generated (platform auto-captions or ASR).
- **`available_languages`string\[\]**: BCP-47 caption languages the platform offers for this post; \[\] if none or not listed.
- **`duration_ms`integer**: Media duration in milliseconds; null when unknown.

Every field, its type and when it is `null`: [the response reference](https://staging-fly.socialtap.dev/docs/reference/youtube/transcript/index.md#response) and the [transcript schema](https://staging-fly.socialtap.dev/resources/transcript/index.md).

## Example request

cURL:

```shell
curl -G 'https://staging-fly.socialtap.dev/v1/youtube/transcript' \
  --data-urlencode 'url=dQw4w9WgXcQ' \
  -H "x-api-key: $SOCIALTAP_API_KEY"
```

Node.js:

```javascript
const params = new URLSearchParams({
  url: "dQw4w9WgXcQ",
});
const res = await fetch(`https://staging-fly.socialtap.dev/v1/youtube/transcript?${params}`, {
  headers: { "x-api-key": process.env.SOCIALTAP_API_KEY ?? "" },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const { data, meta } = body;
console.log(data, meta.credits_charged);
```

Python:

```python
import os

import requests

res = requests.get(
    "https://staging-fly.socialtap.dev/v1/youtube/transcript",
    params={"url": "dQw4w9WgXcQ"},
    headers={"x-api-key": os.environ["SOCIALTAP_API_KEY"]},
)
body = res.json()
if not res.ok:
    raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
data, meta = body["data"], body["meta"]
print(data, meta["credits_charged"])
```

Go:

```go
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"net/url"
	"os"
)

func main() {
	q := url.Values{}
	q.Set("url", "dQw4w9WgXcQ")
	req, err := http.NewRequest("GET", "https://staging-fly.socialtap.dev/v1/youtube/transcript?"+q.Encode(), nil)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("x-api-key", os.Getenv("SOCIALTAP_API_KEY"))
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()
	var body struct {
		Data  json.RawMessage `json:"data"`
		Meta  map[string]any  `json:"meta"`
		Error *struct {
			Code    string `json:"code"`
			Message string `json:"message"`
		} `json:"error"`
	}
	if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
		log.Fatal(err)
	}
	if body.Error != nil {
		log.Fatalf("%s: %s", body.Error.Code, body.Error.Message)
	}
	fmt.Println(string(body.Data), body.Meta["credits_charged"])
}
```

200 OK:

```json
{
  "data": {
    "available_languages": [
      "en",
      "de-DE",
      "ja"
    ],
    "duration_ms": 213000,
    "id": "dQw4w9WgXcQ",
    "is_auto_generated": false,
    "language": "en",
    "platform": "youtube",
    "platform_specific": {},
    "segments": [
      {
        "end_ms": 3040,
        "start_ms": 1360,
        "text": "[♪♪♪]"
      },
      {
        "end_ms": 21880,
        "start_ms": 18640,
        "text": "♪ We're no strangers to love ♪"
      },
      {
        "end_ms": 26960,
        "start_ms": 22640,
        "text": "♪ You know the rules and so do I ♪"
      }
    ],
    "source": "captions",
    "text": "[♪♪♪] ♪ We're no strangers to love ♪ ♪ You know the rules and so do I ♪ ♪ A full commitment's what I'm thinking of ♪ ♪ You wouldn't get this from any other guy ♪ ♪ I just wanna tell you how I'm feeling ♪ ♪ Gotta make you understand ♪ ♪ Never gonna give you up ♪ ♪ Never gonna let …",
    "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  },
  "meta": {
    "request_id": "req_3f9c2a7d1e8b4c6a9f0e2d4b6a8c0e1f",
    "platform": "youtube",
    "source": "captions",
    "is_cached": false,
    "credits_charged": 1,
    "latency_ms": 511,
    "fetched_at": "2026-10-25T12:00:00Z",
    "input": {
      "kind": "video",
      "id": "dQw4w9WgXcQ",
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    },
    "credits_remaining": 9999,
    "client_request_id": null,
    "warnings": [],
    "mode": "live"
  }
}
```

Long arrays and strings are shortened for display; real responses are complete.

> [!NOTE]
>
> **Good to know**
>
> - Manual captions are preferred over auto-generated ones; is_auto_generated tells you which you got.
> - Private, members-only, rental and age-restricted videos return private_or_unavailable.

Reliability

## Measured, not promised. Every request counts.

- **p50 latency**: 511 ms
- **p95 latency**: 989 ms
- **Success rate**: 96.5%
- **Requests measured**: 29

**Staging measurements, not production.** Measured on our staging environment, over the 7 days before 2026-10-25. [How it is measured](https://staging-fly.socialtap.dev/status/index.md#method).

Pricing

## Pay per request. Only when it succeeds.

| Source | Price per successful request | Per 1,000 requests |
| --- | --- | --- |
| Captions `captions` | 1 credit | $0.75–$1.45 |
| Speech-to-text `asr` | 2 credits + 2 per started minute of media<br>up to 122 credits (60 started minutes of media) | $1.50–$2.90 + $1.50–$2.90 per started minute of media |

- Failed requests are free: errors cost 0 credits.
- Cache hits are free: responses served from the cache cost 0 credits.
- Credits never expire.
- One credit balance for every endpoint and platform.

[Credit packs](https://staging-fly.socialtap.dev/pricing/index.md) · [How this endpoint is priced](https://staging-fly.socialtap.dev/docs/reference/youtube/transcript/index.md#pricing) · [How credits work](https://staging-fly.socialtap.dev/docs/credits/index.md)

FAQ

## Questions, answered.

**How much does the YouTube Transcript API cost?**

1 credit for captions results (meta.source = captions) and 2 credits + 2 per started minute of media, up to 122 credits (60 started minutes of media) for speech-to-text results (meta.source = asr), charged only for successful requests. SocialTap credits cost $0.75–$1.45 per 1,000 depending on the pack.

**Am I charged for failed requests?**

No. Requests that return an error cost 0 credits. Responses served from the cache are free too.

Same schema, other platforms

## Transcripts everywhere. One parser.

[Facebook Video Transcript APIBetaTranscript`GET /v1/facebook/transcript`From 1 credit](https://staging-fly.socialtap.dev/apis/facebook/transcript/index.md) · [Instagram Reels Transcript APIBetaTranscript`GET /v1/instagram/transcript`From 1 credit](https://staging-fly.socialtap.dev/apis/instagram/transcript/index.md) · [Rumble Transcript APIBetaTranscript`GET /v1/rumble/transcript`From 1 credit](https://staging-fly.socialtap.dev/apis/rumble/transcript/index.md) · [TikTok Transcript APIBetaTranscript`GET /v1/tiktok/transcript`From 1 credit](https://staging-fly.socialtap.dev/apis/tiktok/transcript/index.md)

More YouTube

## YouTube API. 5 endpoints, one key.

[YouTube Comments APIBetaComment`GET /v1/youtube/comments`1 credit / page](https://staging-fly.socialtap.dev/apis/youtube/comments/index.md) · [YouTube Video APIBetaPost`GET /v1/youtube/post`1 credit](https://staging-fly.socialtap.dev/apis/youtube/post/index.md) · [YouTube Channel Videos APIBetaPost`GET /v1/youtube/posts`1 credit / page](https://staging-fly.socialtap.dev/apis/youtube/posts/index.md) · [YouTube Channel APIBetaProfile`GET /v1/youtube/profile`1 credit](https://staging-fly.socialtap.dev/apis/youtube/profile/index.md)

## Start with 100 free credits. No card required.

Test keys answer every endpoint from recorded responses, free, so you can build before you spend. Failed requests are always free.

[Get your API key](https://staging-fly.socialtap.dev/signup/?next=%2Fplayground%2F%3Fendpoint%3Dyoutube.transcript) · [Read the API reference](https://staging-fly.socialtap.dev/docs/reference/youtube/transcript/index.md)

---

[HTML version](https://staging-fly.socialtap.dev/apis/youtube/transcript/) · [Docs index for AI agents](https://staging-fly.socialtap.dev/llms.txt) · [All docs in one file](https://staging-fly.socialtap.dev/llms-full.txt)
