API Documentation

Integrate video transcription into your application with our RESTful API. Upload media files, monitor processing status, and retrieve transcriptions programmatically.

1

Upload Video

POST /jobs to create, then stream your file

2

Process

We extract audio and transcribe automatically

3

Get Results

GET /jobs/:id to retrieve your transcription

Authentication

All API requests require authentication using your API key. Include it in the Authorization header using the Bearer scheme. You can find your API key in your dashboard settings.

Required Header
Authorization: Bearer <your-api-key>
Keep your API key secure — never expose it in client-side code

Base URLs

The API is split across two endpoints: the Core API for job management and the Upload API for streaming media files.

Core API
https://kopia.ai/api/v1
Upload API
https://upload.kopia.ai
OpenAPI
https://kopia.ai/api/v1/openapi.json

Job Workflow

There are two ways to start a transcription depending on what you have available: upload raw media files, or provide a public HTTPS URL that points to the file. Both flows create a job and then let you track completion via polling or webhooks.

1) Create a job from a URL

Call POST /jobs/from-url with a public HTTPS link. We ingest and kick off transcription immediately.

Create job from URL (example)
curl -X POST "https://kopia.ai/api/v1/jobs/from-url" \
  -H "Authorization: Bearer <api-key>" \
  -H "Content-Type: application/json" \
  -d '{ "mediaUrl": "https://example.com/media.mp4", "removeFillerWords": true }'

2) Wait for completion

Either poll GET /jobs/:id until the job reaches completed status, or provide a webhook URL when creating the job to receive a completion notification (see Webhooks).

Poll job status (example)
curl -X GET "https://kopia.ai/api/v1/jobs/<jobId>" \
  -H "Authorization: Bearer <api-key>"

Upload API

Stream raw media files directly to storage. Use the Upload API base URL for all upload endpoints.

POST/v1/jobs/:id/upload

Upload a media file for processing. The request body should be the raw binary file content. After upload, the job enters the processing queue automatically.

Parameters

:idstringrequiredThe job ID returned from POST /jobs
AuthorizationBearer <api-key>required
Content-Typevideo/mp4, audio/mpeg, etc.required

No request body required

Accepted auth headers: Authorization: Bearer <api-key> or X-API-KEY
Files over 5 GB return HTTP 413 (Payload Too Large)
Supported formats: MP4, MOV, AVI, MP3, WAV, M4A, WEBM

Core API

Manage transcription jobs, check processing status, and retrieve results. Generate translations of your transcriptions into multiple languages. Use the Core API base URL for all endpoints in this section.

POST/jobs

Create a new transcription job. Returns a job object with pending status and a unique ID for subsequent operations.

{
  "language": "en",
  "removeFillerWords": true
}
languagestring
ISO 639-1 language code (e.g., 'en', 'es', 'fr'). Omit for auto-detection.
See supported transcription languages
enGlobal English
autoAuto-detect
en_auAustralian English
en_ukBritish English
en_usUS English
esSpanish
frFrench
deGerman
itItalian
ptPortuguese
nlDutch
hiHindi
jaJapanese
zhChinese
fiFinnish
koKorean
plPolish
ruRussian
trTurkish
ukUkrainian
viVietnamese
afAfrikaans
sqAlbanian
amAmharic
arArabic
hyArmenian
asAssamese
azAzerbaijani
baBashkir
euBasque
beBelarusian
bnBengali
bsBosnian
brBreton
bgBulgarian
myBurmese
caCatalan
hrCroatian
csCzech
daDanish
etEstonian
foFaroese
glGalician
kaGeorgian
elGreek
guGujarati
htHaitian
haHausa
hawHawaiian
heHebrew
huHungarian
isIcelandic
idIndonesian
jwJavanese
knKannada
kkKazakh
kmKhmer
loLao
laLatin
lvLatvian
lnLingala
ltLithuanian
lbLuxembourgish
mkMacedonian
mgMalagasy
msMalay
mlMalayalam
mtMaltese
miMaori
mrMarathi
mnMongolian
neNepali
noNorwegian
nnNorwegian Nynorsk
ocOccitan
paPanjabi
psPashto
faPersian
roRomanian
saSanskrit
srSerbian
snShona
sdSindhi
siSinhala
skSlovak
slSlovenian
soSomali
suSundanese
swSwahili
svSwedish
tlTagalog
tgTajik
taTamil
ttTatar
teTelugu
thThai
boTibetan
tkTurkmen
urUrdu
uzUzbek
cyWelsh
yiYiddish
yoYoruba
removeFillerWordsboolean
When true, filler words are removed from English transcripts. Default is false.
POST/jobs/from-url

Create a new transcription job from a public HTTPS media URL.

{
  "mediaUrl": "https://example.com/media.mp4",
  "language": "en",
  "removeFillerWords": true,
  "webhookUrl": "https://your-server.com/webhooks/transcription"
}
mediaUrlstringrequired
Public HTTPS URL for the media file
languagestring
ISO 639-1 language code (e.g., 'en', 'es', 'fr'). Omit for auto-detection.
removeFillerWordsboolean
When true, filler words are removed from English transcripts. Default is false.
webhookUrlstring
Webhook URL for completion callbacks
Only HTTPS URLs are accepted
Redirects are rejected
Files over 5 GB are rejected
Media longer than 5 hours is rejected
GET/jobs

List all jobs for the authenticated user with optional filtering and pagination. Results are sorted by creation date (newest first).

Parameters

offsetintegerNumber of items to skip (default: 0)
limitintegerItems per page (default: 50, max: 100)
statusstringFilter by status: pending, uploaded, queued, processing, completed, failed
typestringFilter by type: audio, video
createdFromstringFilter jobs created after this date (ISO 8601)
createdTostringFilter jobs created before this date (ISO 8601)
sortstringSort field: createdAt, updatedAt (default: createdAt)
orderstringSort order: asc, desc (default: desc)

No request body required

GET/jobs/:id

Retrieve details for a specific job including status, metadata, and transcription results (when completed).

Parameters

:idstringrequiredThe job ID (e.g., job_1234567890)

No request body required

DELETE/jobs/:id

Permanently delete a job and all associated data including the uploaded media file and transcription results. This action cannot be undone.

Parameters

:idstringrequiredThe job ID to delete

No request body required

GET/jobs/:id/translations

List existing translations for a job.

Parameters

:idstringrequiredThe job ID

No request body required

POST/jobs/:id/translations

Create translations for a completed job. Translates the original transcript into one or more target languages.

Parameters

:idstringrequiredThe job ID (must have status 'completed')
{
  "languages": ["es", "fr", "de"],
  "formal": true
}
languagesarray
Array of target language codes (e.g., ['es', 'fr', 'de' ]). Required, must contain at least one language.
See supported transcription languages
enEnglish
esSpanish
frFrench
deGerman
ptPortuguese (Brazil)
itItalian
nlDutch
ruRussian
koKorean
arArabic
hiHindi
trTurkish
viVietnamese
zh-HansChinese Simplified
jaJapanese
plPolish
ukUkrainian
faPersian
bnBangla
thThai
idIndonesian
elGreek
csCzech
roRomanian
huHungarian
svSwedish
daDanish
fiFinnish
nbNorwegian Bokmål
heHebrew
urUrdu
caCatalan
hrCroatian
bgBulgarian
skSlovak
ltLithuanian
slSlovenian
etEstonian
lvLatvian
sr-LatnSerbian (Latin)
zh-HantChinese Traditional
taTamil
teTelugu
mrMarathi
guGujarati
knKannada
mlMalayalam
paPunjabi
filFilipino
afAfrikaans
sqAlbanian
amAmharic
hyArmenian
asAssamese
azAzerbaijani (Latin)
baBashkir
euBasque
bhoBhojpuri
brxBodo
bsBosnian (Latin)
yueCantonese (Traditional)
hneChhattisgarhi
lzhChinese (Literary)
snchiShona
prsDari
dvDivehi
doiDogri
foFaroese
fjFijian
fr-caFrench (Canada)
glGalician
kaGeorgian
htHaitian Creole
haHausa
mwwHmong Daw (Latin)
isIcelandic
igIgbo
iktInuinnaqtun
iuInuktitut
iu-LatnInuktitut (Latin)
gaIrish
ksKashmiri
kkKazakh
kmKhmer
rwKinyarwanda
tlh-LatnKlingon
tlh-PiqdKlingon (plqaD)
gomKonkani
kuKurdish (Central)
kmrKurdish (Northern)
kyKyrgyz (Cyrillic)
loLao
dsbLower Sorbian
lugLuganda
mkMacedonian
maiMaithili
mgMalagasy
msMalay (Latin)
mtMaltese
mniManipuri
miMaori
mn-CyrlMongolian (Cyrillic)
mn-MongMongolian (Traditional)
myMyanmar
neNepali
nyaNyanja
orOdia
psPashto
pt-ptPortuguese (Portugal)
otqQueretaro Otomi
runRundi
smSamoan (Latin)
sr-CyrlSerbian (Cyrillic)
stSesotho
nsoSesotho sa Leboa
tnSetswana
sdSindhi
siSinhala
soSomali (Arabic)
swSwahili (Latin)
tyTahitian
ttTatar (Latin)
boTibetan
tiTigrinya
toTongan
tkTurkmen (Latin)
hsbUpper Sorbian
ugUyghur (Arabic)
uzUzbek (Latin)
cyWelsh
xhXhosa
yoYoruba
yuaYucatec Maya
zuZulu
formalboolean
Use formal/polite tone. Optional, defaults to false.
Job must have status 'completed' before creating translations
Each language creates a separate translation object with its own status
Translation status flows: requested → processing → completed/failed
If a translation already exists for a language, it will be returned instead of recreated
DELETE/jobs/:id/translations/:translationId

Permanently delete a translation for a job. This action cannot be undone.

Parameters

:idstringrequiredThe job ID
:translationIdstringrequiredThe translation ID to delete

No request body required

GET/jobs/:id/transcript

Retrieve the transcript for a job. Returns structured JSON by default, or a JSON object with a text property when format=text.

Parameters

:idstringrequiredThe job ID
formatstringOutput format: 'json' (default) or 'text'
languagestringISO 639-1 language code to get original or specific translation transcript. Mutually exclusive with translationId.
translationIdstringSpecific translation ID to retrieve. Mutually exclusive with language parameter.

No request body required

If the job is still processing, the API returns 425 (Too Early) with error code POLICY_VIOLATION and message 'Job is in progress'
If the job failed, the API returns 409 (Conflict) with error code POLICY_VIOLATION and message 'Job failed'
format=text returns JSON `{ "text": "..." }` with `application/json` content type
language parameter can specify a translation language code
translationId parameter to get a specific translation by ID
language and translationId parameters are mutually exclusive
Without language or translationId, returns the original transcript

Webhooks

Receive real-time notifications when your transcription jobs complete. Provide a webhook URL when creating a job, and we'll POST to that URL when the transcription is ready.

Setting Up Webhooks

When creating a job via POST /jobs, include these optional fields:

Request Body with Webhook
{
  "language": "en",
  "removeFillerWords": true,
  "webhookUrl": "https://your-server.com/webhooks/transcription"
}

Additionally, include a secret in the request header for webhook verification:

Required Header for Webhooks
X-Kopia-Webhook-Secret: your-random-secret-key

Webhook Payload

When a job completes, we POST the following JSON payload to your webhook URL:

Webhook Delivery Payload
{
  "jobId": "job_1234567890"
}

Webhook Verification

Verify webhook authenticity by checking the X-Kopia-Webhook-Secret header in the incoming POST request. This header contains the secret you provided when creating the job.

Verification Header in Webhook POST
X-Kopia-Webhook-Secret: your-random-secret-key
Webhooks are only sent when a job reaches completed status
Failed deliveries are retried up to 5 times with exponential backoff
The webhook secret is cleared from our servers after successful delivery
Your endpoint should respond with a 2xx status code to acknowledge receipt

Error Handling

When an error occurs, the API returns a JSON response with a consistent error structure containing a machine-readable code and human-readable message.

Error Response Format
{
  "error": {
    "message": "Error description",
    "code": "ERROR_CODE"
  }
}

Error Codes

UNAUTHORIZEDInvalid or missing API key
VALIDATION_ERRORRequest data is invalid or malformed
NOT_FOUNDThe requested resource does not exist
POLICY_VIOLATIONRequest conflicts with resource state or policy
INTERNAL_ERRORAn unexpected server error occurred