---
title: "Start an audio job"
method: POST
path: "/v1/files/jobs"
tags: ["narrador files"]
---

# Start an audio job

`POST /v1/files/jobs`

## Request

- Base URL: `https://api.narrador.io`
- URL: `https://api.narrador.io/v1/files/jobs`
- Auth: one of:
  - HTTP bearer
  - API key in header `x-api-key`

Starts narrador files processing from an uploaded file or inline text. Returns a `jobId` (snapshot id) to poll. Requires a `nrd_files_` key.

## Request body

- union
  - FilesJobFromUpload: Optional `voiceId`/`accent` (both or neither). When omitted, narrador detects document language when possible (else `en-us`) and picks the first premium public voice for that language (deterministic catalog order), or the first economy voice in the same language if none. Unsupported detected languages or missing catalog voices finish with `failed_file_processing`; pass `voiceId` and `accent` explicitly. JSON bodies on `/v1/files` allow up to 2 MB; larger payloads receive HTTP 413.
    - `fileId` string, uuid, required
    - `fileName` string, required
    - `voiceId` string, uuid
    - `accent` 'af-za' | 'am-et' | 'ar-ae' | 'ar-eg' | 'ar-iq' | 'ar-kw' | 'ar-ma' | 'ar-qa' | 'ar-sa' | 'az-az' | 'bn-bd' | 'bn-in' | 'cmn-cn' | 'ja-jp' | 'jv-id' | 'kk-kz' | 'km-kh' | 'ko-kr' | 'mn-mn' | 'my-mm' | 'ne-np' | 'ps-af' | 'si-lk' | 'so-so' | 'th-th' | 'vi-vn' | 'zh-cn' | 'zh-hk' | 'zh-tw' | 'yue-cn' | 'bg-bg' | 'bs-ba' | 'ca-es' | 'cs-cz' | 'da-dk' | 'de-de' | 'el-gr' | 'et-ee' | 'eu-es' | 'fi-fi' | 'fr-be' | 'fr-ca' | 'fr-ch' | 'fr-fr' | 'ga-ie' | 'hr-hr' | 'hu-hu' | 'hy-am' | 'is-is' | 'it-it' | 'lt-lt' | 'lv-lv' | 'nb-no' | 'nl-be' | 'nl-nl' | 'pl-pl' | 'pt-br' | 'pt-pt' | 'ro-ro' | 'ru-ru' | 'sk-sk' | 'sl-si' | 'sq-al' | 'sr-rs' | 'sv-se' | 'tr-tr' | 'uk-ua' | 'en-au' | 'en-ca' | 'en-gb' | 'en-hk' | 'en-ie' | 'en-in' | 'en-ke' | 'en-nz' | 'en-sg' | 'en-us' | 'en-za' | 'es-ar' | 'es-cl' | 'es-co' | 'es-cr' | 'es-cu' | 'es-do' | 'es-ec' | 'es-es' | 'es-mx' | 'es-pe' | 'es-pr' | 'es-py' | 'es-us' | 'es-ve' | 'gu-in' | 'hi-in' | 'kn-in' | 'ml-in' | 'mr-in' | 'pa-in' | 'ta-in' | 'ta-lk' | 'ta-my' | 'te-in' | 'fa-ir' | 'fil-ph' | 'he-il' | 'id-id' | 'ms-my' | 'mt-mt' | 'sw-ke' | 'ur-pk' | 'zu-za'
    - `callbackUrl` string, uri: Optional https URL on a public host for a single terminal job webhook (see Files job webhooks).
  - FilesJobFromText: Optional `voiceId`/`accent` (both or neither). When omitted, narrador detects document language when possible (else `en-us`) and picks the first premium public voice for that language (deterministic catalog order), or the first economy voice in the same language if none. Unsupported detected languages or missing catalog voices finish with `failed_file_processing`; pass `voiceId` and `accent` explicitly. JSON bodies on `/v1/files` allow up to 2 MB; larger payloads receive HTTP 413.
    - `text` string, required
    - `fileName` string
    - `voiceId` string, uuid
    - `accent` 'af-za' | 'am-et' | 'ar-ae' | 'ar-eg' | 'ar-iq' | 'ar-kw' | 'ar-ma' | 'ar-qa' | 'ar-sa' | 'az-az' | 'bn-bd' | 'bn-in' | 'cmn-cn' | 'ja-jp' | 'jv-id' | 'kk-kz' | 'km-kh' | 'ko-kr' | 'mn-mn' | 'my-mm' | 'ne-np' | 'ps-af' | 'si-lk' | 'so-so' | 'th-th' | 'vi-vn' | 'zh-cn' | 'zh-hk' | 'zh-tw' | 'yue-cn' | 'bg-bg' | 'bs-ba' | 'ca-es' | 'cs-cz' | 'da-dk' | 'de-de' | 'el-gr' | 'et-ee' | 'eu-es' | 'fi-fi' | 'fr-be' | 'fr-ca' | 'fr-ch' | 'fr-fr' | 'ga-ie' | 'hr-hr' | 'hu-hu' | 'hy-am' | 'is-is' | 'it-it' | 'lt-lt' | 'lv-lv' | 'nb-no' | 'nl-be' | 'nl-nl' | 'pl-pl' | 'pt-br' | 'pt-pt' | 'ro-ro' | 'ru-ru' | 'sk-sk' | 'sl-si' | 'sq-al' | 'sr-rs' | 'sv-se' | 'tr-tr' | 'uk-ua' | 'en-au' | 'en-ca' | 'en-gb' | 'en-hk' | 'en-ie' | 'en-in' | 'en-ke' | 'en-nz' | 'en-sg' | 'en-us' | 'en-za' | 'es-ar' | 'es-cl' | 'es-co' | 'es-cr' | 'es-cu' | 'es-do' | 'es-ec' | 'es-es' | 'es-mx' | 'es-pe' | 'es-pr' | 'es-py' | 'es-us' | 'es-ve' | 'gu-in' | 'hi-in' | 'kn-in' | 'ml-in' | 'mr-in' | 'pa-in' | 'ta-in' | 'ta-lk' | 'ta-my' | 'te-in' | 'fa-ir' | 'fil-ph' | 'he-il' | 'id-id' | 'ms-my' | 'mt-mt' | 'sw-ke' | 'ur-pk' | 'zu-za'
    - `callbackUrl` string, uri: Optional https URL on a public host for a single terminal job webhook (see Files job webhooks).

## Response `201`

Job created

- FilesJobCreated
  - `jobId` string, uuid
  - `projectId` string, uuid
  - `status` 'idle' | 'processing' | 'processed' | 'failed_file_processing' | 'generating' | 'failed_audio_generation' | 'completed'

## Other responses

- `400`: Invalid JSON body — failed Zod validation (`safeParse`). Returns `{ "error": "Invalid request body.", "details": […] }`.
- `401`: Unauthorized — missing or invalid API key (wrong prefix, revoked, or expired).
- `403`: Forbidden — API key scope does not match the endpoint (e.g. `nrd_x_` key on a narrador files route), insufficient narrador credits for a synchronous operation (e.g. narrador X generate), or other entitlement failure. narrador files jobs that run out of credits finish asynchronously with job status `not-enough-credits` instead of HTTP 403.
- `413`: JSON request body larger than **2mb** (Express body-parser limit on `/v1/files`). Response is the default HTML error page (`PayloadTooLargeError: request entity too large`), not `{ "error": "…" }`. Multipart `POST /v1/files/generate` uses separate file-size limits.
- `429`: Too many requests — API key verification rate limit exceeded (60 requests per 60 seconds per key).

---

[API](https://skmtc.dev/narrador/apis/narrador-api.md) · [All operations](https://skmtc.dev/narrador/apis/narrador-api/llms.txt) · [OpenAPI document](https://skmtc.dev/narrador/apis/narrador-api/revisions/e9f026c76832?raw)
