# Getting started

> Create an API key and transcribe your first video link or file with cURL, Python or Node.js.

Canonical: https://transcript1.com/docs/getting-started
Last updated: 2026-10-14

Send requests to `https://api.transcript1.com` with an API key in the `Authorization` header. Follow these steps to create a key, submit media and read a transcript.

## 1. Create an account and an API key

Sign up at [/signup](https://transcript1.com/signup) with an email address, Google or Microsoft. You get 60 free minutes once per account, after email verification. Google and Microsoft signups receive them immediately. No card is needed.

Create an API key on the [API keys page](https://transcript1.com/dashboard/account/tokens) of the dashboard at `/dashboard/account/tokens`. Keys start with `t1_` and are shown once, so copy yours right away. Then export it as `TRANSCRIPT1_API_KEY`:

```bash
export TRANSCRIPT1_API_KEY="t1_..."
```

## 2. Transcribe a video link

YouTube, X, TikTok, Instagram, Facebook, Bluesky, Twitch, Dailymotion, Pinterest, LinkedIn and Snapchat links are supported. See [Sources and options](https://transcript1.com/docs/sources-and-options) for accepted public recorded media and limitations. The API detects the platform from the link; `platform` is optional. This example uses YouTube.

Send the video URL to `POST /v1/transcriptions`. The `wait=60` query parameter holds the request open for up to 60 seconds. The create response does not include the transcript. The Python example reads it in a separate request to `GET /v1/transcriptions/:id?wait=60`. The Node.js SDK reads `TRANSCRIPT1_API_KEY` and does that waiting for you.

### cURL

```bash
curl -X POST "https://api.transcript1.com/v1/transcriptions?wait=60" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://www.youtube.com/watch?v=dQw4w9WgXcQ"}'
```

### Python

```python
import os
import requests

headers = {"Authorization": f"Bearer {os.environ['TRANSCRIPT1_API_KEY']}"}
response = requests.post(
    "https://api.transcript1.com/v1/transcriptions?wait=60",
    headers=headers,
    json={"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"},
)
response.raise_for_status()
transcription = response.json()
while True:
    transcription = requests.get(
        f"https://api.transcript1.com/v1/transcriptions/{transcription['id']}?wait=60",
        headers=headers,
    ).json()
    if transcription["status"] in ("completed", "failed", "canceled"):
        break

if transcription["status"] == "completed":
    print(transcription["transcript"]["text"])
else:
    print(transcription["status"], transcription["error"])
```

### Node.js

Save this example as `index.mjs` (or set `"type": "module"` in `package.json` for a `.js` file) and run it with `node index.mjs`.

```javascript
// npm i @transcript1/sdk
import { Transcript1 } from '@transcript1/sdk';

const t1 = new Transcript1();
const transcription = await t1.transcribe('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
console.log(transcription.transcript.text);
```

By default transcript1 uses usable original-language captions from YouTube, X, TikTok, Bluesky, Dailymotion and LinkedIn when available and falls back to AI transcription otherwise. YouTube and X retain their existing caption behavior. Non-YouTube captions have segment timing only, without word timings. Not every video has a usable track. `source=stt` or speaker labels bypass captions; captions-only never downloads audio or uses STT. See [Sources and options](https://transcript1.com/docs/sources-and-options) to choose.

## 3. Read the result

Check the response status:

- `200` means it reached a final status within the wait (`completed`, `failed` or `canceled`).
- `202` means it is still processing. Fetch it again with `GET /v1/transcriptions/:id?wait=60`, which holds the request for up to 60 seconds, and repeat until `status` is final.

A completed transcription looks like this (shortened):

```json
{
  "id": "tr_8fK2Lm0PqRsTuVwXyZaBcD",
  "object": "transcription",
  "status": "completed",
  "transcript_source": "youtube_captions",
  "language": "en",
  "billed_minutes": 4,
  "transcript": {
    "text": "Welcome back to the channel. Today we are looking at how transcripts are made.",
    "speakers": [],
    "segments": [
      { "start": 0, "end": 4.2, "speaker": null, "language": "en", "text": "Welcome back to the channel." },
      { "start": 4.2, "end": 9.8, "speaker": null, "language": "en", "text": "Today we are looking at how transcripts are made." }
    ]
  }
}
```

`transcript.text` is the whole transcript and `transcript.segments` holds the timed segments, each with `start` and `end` in seconds.

For plain text or subtitles, request one of these formats: `text`, `srt` and `vtt`:

```bash
curl "https://api.transcript1.com/v1/transcriptions/tr_8fK2Lm0PqRsTuVwXyZaBcD?format=srt" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY"
```

That is `GET /v1/transcriptions/:id?format=srt`. Rendered formats are returned only once the transcription is `completed`; before that you get the JSON object back so you can see the status.

## 4. Transcribe a file

To transcribe a local audio or video file, send it as `multipart/form-data` in one request. This works for files up to 95 MB:

```bash
curl -X POST "https://api.transcript1.com/v1/transcriptions?wait=60" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
  -F file=@interview.m4a
```

Larger files, up to 2 GB, are sent in resumable chunks. See [Uploads](https://transcript1.com/docs/uploads).

## Next steps

- [Sources and options](https://transcript1.com/docs/sources-and-options): captions or AI transcription, speaker labels and language.
- [Uploads](https://transcript1.com/docs/uploads): one-shot and chunked file uploads.
- [Webhooks](https://transcript1.com/docs/webhooks): get a signed request when a transcription finishes.
- [MCP server](https://transcript1.com/docs/mcp): use transcript1 from Claude, ChatGPT, Cursor, VS Code and Claude Code.
- [API reference](https://transcript1.com/docs/api-reference): every endpoint and parameter.
