---
name: gettranscribe-api
description: >-
  Integrate the GetTranscribe REST API to queue video transcriptions via async
  jobs, poll job status, fetch transcripts, manage folders, and resolve download
  URLs. Use when building agents or apps that call api.gettranscribe.ai.
---

# GetTranscribe API — Agent Integration Skill

## When to use

Use this skill whenever you need to call the GetTranscribe HTTP API for:

- Transcribing Instagram, TikTok, YouTube, Facebook, X, Pinterest, Google Drive, or direct video URLs
- Polling async job status
- Reading finished transcripts
- Organizing work into folders
- Resolving a direct media download URL without creating a transcription

Human docs: https://www.gettranscribe.ai/api-documentation/documentation

## Base URL and auth

```
Base URL: https://api.gettranscribe.ai
Auth header (required): x-api-key: YOUR_API_KEY
```

- Create a permanent API key in the product: https://www.gettranscribe.ai/api-documentation/authentication
- Prefer `x-api-key` for integrations (documented public auth).
- JSON bodies need `Content-Type: application/json`.
- Feathers-style query params use `$limit`, `$skip`, `$sort[field]`.

## Critical rule: always create via jobs

**Do not** use synchronous `POST /transcriptions` for new transcriptions.

Always:

1. `POST /transcription-jobs` → receive a `pending` job (`201`)
2. Poll `GET /transcription-jobs/{id}` until `status` is `completed` or `failed`
3. On `completed`, read `transcription_id`
4. `GET /transcriptions/{transcription_id}` for the full transcript text and media URLs

Why: jobs are processed by background workers. Sync create is not the supported integration path.

## End-to-end transcription workflow

### 1) Create transcription job

`POST /transcription-jobs`

```bash
curl -X POST https://api.gettranscribe.ai/transcription-jobs \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "url": "https://www.instagram.com/p/DWy1RmFAGjF/",
    "model": "accurate",
    "language": "en",
    "source": "api"
  }'
```

Body fields:

| Field | Required | Notes |
| --- | --- | --- |
| `url` | yes | Public video URL |
| `folder_id` | no | Folder to store the finished transcription |
| `model` | no | `accurate` (default), `fast`, `quality`, `speakers` |
| `language` | no | ISO-639-1 (`en`, `es`, …) |
| `prompt` | no | Context / names / jargon. Ignored for `speakers` |
| `source` | no | For API clients send `"api"` |

Live create response shape (`201`, status `pending`):

```json
{
  "id": 22539,
  "user_id": 2,
  "folder_id": null,
  "transcription_id": null,
  "url": "https://www.instagram.com/p/DWy1RmFAGjF/",
  "language": "en",
  "prompt": null,
  "model": "accurate",
  "source": "api",
  "status": "pending",
  "error_message": null,
  "error_code": null,
  "platform": "instagram",
  "thumbnail_url": "https://...",
  "generated_title": "...",
  "consumption_type": "subscription",
  "client_origin": "api",
  "processing_scope": "production",
  "started_at": null,
  "created_at": "2026-07-22T23:59:03.826Z",
  "updated_at": "2026-07-22T23:59:03.826Z"
}
```

### 2) Get one transcription job (poll)

`GET /transcription-jobs/{id}`

```bash
curl -X GET https://api.gettranscribe.ai/transcription-jobs/22539 \
  -H "x-api-key: YOUR_API_KEY"
```

Statuses:

| Status | Meaning |
| --- | --- |
| `pending` | Queued |
| `processing` | Worker running (`progress_message` may be set) |
| `completed` | Done — use `transcription_id` |
| `failed` | Read `error_message` / `error_code` |

Live completed response (same job after workers finished):

```json
{
  "id": 22539,
  "status": "completed",
  "transcription_id": 233504,
  "platform": "instagram",
  "model": "accurate",
  "language": "en",
  "source": "api",
  "generated_title": "Strategic AI Marketing for Doctors: Attract Patients Online",
  "started_at": "2026-07-22T23:59:08.546Z",
  "created_at": "2026-07-22T23:59:03.826Z",
  "updated_at": "2026-07-22T23:59:22.384Z"
}
```

Polling guidance:

- Poll every 2–5 seconds
- Stop on `completed` or `failed`
- Typical short Instagram/TikTok jobs finish in ~10–30s (varies by length/queue)

### 3) List transcription jobs

`GET /transcription-jobs`

```bash
curl -G "https://api.gettranscribe.ai/transcription-jobs" \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode '$limit=20' \
  --data-urlencode '$skip=0' \
  --data-urlencode '$sort[created_at]=-1' \
  --data-urlencode 'status=completed'
```

Response envelope: `{ total, limit, skip, data: Job[] }`.

### 4) Get finished transcription

`GET /transcriptions/{id}`

```bash
curl -X GET https://api.gettranscribe.ai/transcriptions/233504 \
  -H "x-api-key: YOUR_API_KEY"
```

Important fields (live `GET /transcriptions/{id}`):

- `transcription` — full transcript text
- `original_transcription` — raw text before formatting
- `download_audio_url` — time-limited signed S3 URL when audio is stored
- `download_video_url` — often the original page URL, not always a direct MP4
- `thumbnail_url` — may be a signed S3 URL
- `duration_seconds`, `word_count`, `char_count`
- `platform`, `author`, `channel`, `generated_title`, `language`
- `transcription_segments` / `transcription_words` — timing arrays (may be empty depending on model/pipeline)

List vs get:

- `GET /transcriptions` is a **lightweight index** (no full `transcription` text)
- Always use get-by-id for the transcript body

### 5) List transcriptions

`GET /transcriptions`

```bash
curl -G "https://api.gettranscribe.ai/transcriptions" \
  -H "x-api-key: YOUR_API_KEY" \
  --data-urlencode '$limit=20' \
  --data-urlencode '$sort[created_at]=-1'
```

Optional filters used in docs: `folder_id`, `platform`.

Response: `{ total, limit, skip, data: [...] }` — metadata only.

## Folders

Service path: `/transcriptions-folders`

### Create folder

`POST /transcriptions-folders` → `201`

```bash
curl -X POST https://api.gettranscribe.ai/transcriptions-folders \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{"name":"YouTube Videos","parent_id":null}'
```

Live create shape:

```json
{
  "id": 1639,
  "name": "API Skill Probe Temp",
  "user_id": 2,
  "parent_id": null,
  "created_at": "2026-07-22T23:59:00.000Z",
  "updated_at": "2026-07-22T23:59:00.000Z",
  "deleted_at": null
}
```

### Get folder

`GET /transcriptions-folders/{id}` → `200`

Live example:

```json
{
  "id": 1606,
  "name": "Ads",
  "user_id": 2,
  "parent_id": 1605,
  "created_at": "2026-07-12T04:04:32.021Z",
  "updated_at": "2026-07-12T04:04:32.021Z",
  "deleted_at": null
}
```

`parent_id` is `null` for root folders.

### List folders

`GET /transcriptions-folders` → `{ total, limit, skip, data }`

### Update folder

`PATCH /transcriptions-folders/{id}` with `{ "name": "..." }` and/or `parent_id`.

## Download video URL (no transcription)

`POST /download-video` → `201`

Resolves a fresh direct media URL + thumbnail. Does **not** create a transcription. Requires wallet balance (small debit on success).

```bash
curl -X POST https://api.gettranscribe.ai/download-video \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{"url":"https://www.instagram.com/p/DWy1RmFAGjF/"}'
```

Live shape:

```json
{
  "id": 127,
  "url": "https://www.instagram.com/p/DWy1RmFAGjF/",
  "platform": "instagram",
  "user_id": 2,
  "download_url": "https://...cdninstagram.com/...mp4...",
  "thumbnail": "https://...cdninstagram.com/...",
  "created_at": "2026-07-22T23:59:03.304Z",
  "updated_at": "2026-07-22T23:59:03.304Z",
  "deleted_at": null
}
```

`download_url` / `thumbnail` expire — call again for a fresh link.

## User info

`GET /users/{id}` — use the authenticated account’s own user id.

Useful fields: `subscription_plan_name`, `subscription_status`, `minutes_limit`, `messages_limit`, `current_usage_minutes`, `current_usage_messages`, `purchased_minutes_balance`, `balance`.

Do not log or expose Stripe IDs, OTP fields, or other sensitive account internals in user-facing output.

## Agent playbook (copy this flow)

```text
1. Ensure x-api-key is available (never hardcode in source; use env/secret).
2. POST /transcription-jobs with { url, source: "api", optional model/language/folder_id/prompt }.
3. Save job.id from the 201 response.
4. Loop:
     GET /transcription-jobs/{id}
     if status == completed -> break with transcription_id
     if status == failed -> surface error_message and stop
     else sleep 2-5s
5. GET /transcriptions/{transcription_id}
6. Use `transcription` text; optionally use download_audio_url / metadata fields.
```

Pseudo-code:

```python
import os, time, requests

API = "https://api.gettranscribe.ai"
H = {"x-api-key": os.environ["GETTRANSCRIBE_API_KEY"], "Content-Type": "application/json"}

job = requests.post(f"{API}/transcription-jobs", headers=H, json={
    "url": url,
    "model": "accurate",
    "source": "api",
}).json()

while True:
    j = requests.get(f"{API}/transcription-jobs/{job['id']}", headers=H).json()
    if j["status"] == "completed":
        tid = j["transcription_id"]; break
    if j["status"] == "failed":
        raise RuntimeError(j.get("error_message") or "transcription job failed")
    time.sleep(3)

tr = requests.get(f"{API}/transcriptions/{tid}", headers=H).json()
print(tr["transcription"])
```

## Supported platforms (URL `url` field)

Instagram, TikTok, YouTube (watch/shorts/youtu.be), Facebook, X/Twitter, Pinterest, Google Drive file links, and direct media file URLs (e.g. `.mp4`).

## Models

| Value | Use |
| --- | --- |
| `accurate` | Default; timed segments/words when available |
| `fast` | Faster / lighter |
| `quality` | Higher quality profile |
| `speakers` | Diarization-oriented; ignores `prompt` |

## Error handling

- Expect Feathers-style JSON errors with `message`, often `code`, and structured `data`
- Common user-facing failure cases for media: invalid URL, private content, no audio, file too large, insufficient balance/limits
- On job `failed`, prefer `error_message` from the job record
- Never retry endlessly on permanent URL/auth failures

## What agents must not do

- Do not call sync `POST /transcriptions` for new work
- Do not invent endpoints or response fields
- Do not treat list endpoints as full transcript payloads
- Do not treat `download_video_url` on a transcription as always hotlinkable MP4
- Do not commit API keys

## Docs map

| Action | Method | Path | Docs |
| --- | --- | --- | --- |
| Create job | POST | `/transcription-jobs` | `/api-documentation/transcriptions/create` |
| Get job | GET | `/transcription-jobs/{id}` | `/api-documentation/transcription-jobs/get` |
| List jobs | GET | `/transcription-jobs` | `/api-documentation/transcription-jobs/list` |
| Get transcription | GET | `/transcriptions/{id}` | `/api-documentation/transcriptions/get` |
| List transcriptions | GET | `/transcriptions` | `/api-documentation/transcriptions/list` |
| Download URL | POST | `/download-video` | `/api-documentation/download-video/create` |
| Create folder | POST | `/transcriptions-folders` | `/api-documentation/folders/create` |
| Get folder | GET | `/transcriptions-folders/{id}` | `/api-documentation/folders/get` |
| List folders | GET | `/transcriptions-folders` | `/api-documentation/folders/list` |
| Update folder | PATCH | `/transcriptions-folders/{id}` | `/api-documentation/folders/update` |
| Get user | GET | `/users/{id}` | `/api-documentation/user/get` |
| Auth / API keys | — | in-app | `/api-documentation/authentication` |

Examples in this skill were verified live against `https://api.gettranscribe.ai` (July 2026).
