> ## Documentation Index
> Fetch the complete documentation index at: https://slng.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# How to use Batch API

> Submit audio for asynchronous transcription on the SLNG Batch API using URL input, presigned S3 upload, or inline base64. Supported formats and limits.

This guide covers the three ways to submit audio for batch transcription. For endpoint details and schemas, see the [Batch API reference](https://slng.mintlify.site/api-reference/speechmatics/create-batch-job.md).

> [!NOTE]
>
> The Batch API is served from `https://api.batch.slng.ai`, not `https://api.slng.ai`.

> [!NOTE]
>
> Use presigned upload (Method 2) for files above \~10 MB. Inline base64 (Method 3) is capped by the 10 MB request-body limit.

**Prerequisites:**

* An SLNG API key from [app.slng.ai/api-keys](https://app.slng.ai/api-keys) — a consumer key (`slng_cu_...`) or a batch key (`slng_bt_...`).
* Audio in a supported format: `wav`, `mp3`, `flac`, `aac`, `ogg`, `m4a`, `mp4`, `amr`, `mpeg`

## Authentication

Supply your SLNG API key on every request using either header:

```http theme={null}
Authorization: Bearer slng_cu_...
X-API-Key: slng_cu_...
```

Both headers are equivalent. Consumer (`slng_cu_`) and batch (`slng_bt_`) keys both authenticate; legacy `zpka_` keys are still accepted during migration. Any other value returns **401 Unauthorized**.

## Placeholders

The snippets below use these placeholders. Replace them before running the code.

| Placeholder | Replace with |
| - | - |
| `SLNG_API_KEY` | An SLNG API key (`slng_cu_...` or `slng_bt_...`) from [app.slng.ai/api-keys](https://app.slng.ai/api-keys) |
| `myjob123` / `job8f3a...` | The `job_id` returned by `POST /v1/batch/jobs` (auto-generated if omitted) |
| `<presigned_url>` | The presigned upload URL returned by the `mode: "presign"` flow |
| `audio.wav` / `s3_key` | Your local file path / the S3 key the platform returned at presign time |

***

## Input Methods

### Method 1: URL Input

Provide a publicly accessible HTTPS URL. The system downloads the file. Supports presigned S3/GCS URLs for private files.

```mermaid theme={null}
sequenceDiagram
    participant Client
    participant Batch API
    Client->>Batch API: POST /v1/batch/jobs<br/>JSON: input_url + config
    Note over Batch API: Downloads audio from URL
    Note over Batch API: Queues transcription job
    Batch API-->>Client: 202 – BatchJob, status: QUEUED
```

```bash theme={null}
curl -X POST https://api.batch.slng.ai/v1/batch/jobs \
  -H "Authorization: Bearer SLNG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input_url": "https://example.com/audio.wav",
    "transcription_config": { "language": "en" }
  }'
```

| Field | Type | Required | Description |
| - | - | - | - |
| `input_url` | string | yes | HTTPS URL of the audio file |
| `transcription_config` | object | yes | Transcription settings |
| `job_id` | string | no | Alphanumeric job ID (auto-generated if omitted) |
| `model_code` | string | no | Model to use (default: `slng/speechmatics/batch:15.0.0`) |
| `tracking` | object | no | Title / reference / tags / details for filtering |
| `output_config` | object | no | Output format settings |
| `metadata` | object | no | Arbitrary key-value metadata |

### Method 2: Presigned Upload

Use this method for large files or when you need upload progress tracking. Three steps: request a presigned URL, upload the file directly to S3, then create the job referencing the upload.

```mermaid theme={null}
sequenceDiagram
    participant Client
    participant Batch API
    participant S3
    Client->>Batch API: POST /v1/batch/jobs<br/>JSON: mode=presign + filename
    Batch API-->>Client: 200 – job_id + presigned upload URL
    Client->>S3: PUT presigned URL<br/>binary audio file
    S3-->>Client: 200 OK
    Client->>Batch API: POST /v1/batch/jobs<br/>JSON: job_id + s3_key + config
    Note over Batch API: Queues transcription job
    Batch API-->>Client: 202 – BatchJob, status: QUEUED
```

**1. Request a presigned S3 upload URL**

```bash theme={null}
curl -X POST https://api.batch.slng.ai/v1/batch/jobs \
  -H "Authorization: Bearer SLNG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "presign",
    "filename": "audio.wav",
    "transcription_config": { "language": "en" }
  }'
```

Returns **200 OK** (no job is created yet). The response carries the `job_id`, the validated `transcription_config` (echoed back), the future S3 locations, and an `upload` object with the presigned `PUT` URL plus the headers your upload must send:

```json theme={null}
{
  "job_id": "job8f3a...",
  "transcription_config": { "language": "en", "operating_point": "enhanced", "diarization": "none" },
  "input_s3_uri": "s3://slng-production-batch-input/inputs/job8f3a.../audio.wav",
  "output_s3_prefix": "s3://slng-production-batch-output/outputs/job8f3a.../",
  "upload": {
    "url": "https://slng-production-batch-input.s3.amazonaws.com/...",
    "s3_key": "inputs/job8f3a.../audio.wav",
    "s3_uri": "s3://slng-production-batch-input/inputs/job8f3a.../audio.wav",
    "expires_in": 3600,
    "headers": { "Content-Type": "application/octet-stream" }
  }
}
```

Carry the returned `transcription_config` verbatim into step 3.

**2. Upload the file to the presigned URL**

Send the bytes with the exact headers from `upload.headers` (typically `Content-Type: application/octet-stream`):

```bash theme={null}
curl -X PUT "<presigned_url>" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @audio.wav
```

**3. Create the job**

Reference the `job_id` and `s3_key` from step 1.

```bash theme={null}
curl -X POST https://api.batch.slng.ai/v1/batch/jobs \
  -H "Authorization: Bearer SLNG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "job_id": "job8f3a...",
    "s3_key": "inputs/job8f3a.../audio.wav",
    "transcription_config": { "language": "en" }
  }'
```

### Method 3: Inline base64

Small files only — bounded by the 10 MB request-body cap. Use presigned upload for anything larger.

```bash theme={null}
curl -X POST https://api.batch.slng.ai/v1/batch/jobs \
  -H "Authorization: Bearer SLNG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input_base64": "UklGRiQAAABXQVZFZm10IBAAAAABAAEA...",
    "input_filename": "audio.wav",
    "transcription_config": { "language": "en" }
  }'
```

| Field | Type | Required | Description |
| - | - | - | - |
| `input_base64` | string | yes | Base64-encoded audio (request body capped at 10 MB) |
| `input_filename` | string | yes | Original filename of the encoded audio |
| `transcription_config` | object | yes | Transcription settings |
| `job_id` | string | no | Alphanumeric job ID (auto-generated if omitted) |
| `model_code` | string | no | Model to use (default: `slng/speechmatics/batch:15.0.0`) |
| `metadata` | object | no | Arbitrary key-value metadata |

***

## Job Lifecycle

After submission, a job moves through these statuses:

`QUEUED` → `IN_PROGRESS` → `DECODING` → `POST_PROCESSING` → `DONE` / `FAILED`

A successfully deleted job moves to `DELETED` (terminal).

Poll `GET /v1/batch/jobs/{jobId}` until the status reaches `DONE` or `FAILED`. The response includes the full job record (config, timestamps, `error_message` on failures); see the [API reference](https://slng.mintlify.site/api-reference/speechmatics/get-batch-job.md) for the schema.

```mermaid theme={null}
sequenceDiagram
    participant Client
    participant Batch API
    Client->>Batch API: GET /v1/batch/jobs/{jobId}
    Batch API-->>Client: status: IN_PROGRESS
    Note over Client: Wait and retry
    Client->>Batch API: GET /v1/batch/jobs/{jobId}
    Batch API-->>Client: status: DONE
    Client->>Batch API: GET /v1/batch/jobs/{jobId}/files
    Batch API-->>Client: Presigned download URLs<br/>(JSON, TXT, SRT transcripts)
```

```bash theme={null}
curl https://api.batch.slng.ai/v1/batch/jobs/myjob123 \
  -H "Authorization: Bearer SLNG_API_KEY"
```

Once `DONE`, retrieve the transcripts:

```bash theme={null}
curl https://api.batch.slng.ai/v1/batch/jobs/myjob123/files \
  -H "Authorization: Bearer SLNG_API_KEY"
```

Response shape:

```json theme={null}
{
  "job_id": "myjob123",
  "inputs": [
    { "key": "inputs/myjob123.wav", "s3_uri": "s3://...", "download_url": "https://..." }
  ],
  "outputs": [
    { "format": "json", "key": "outputs/myjob123.json", "s3_uri": "s3://...", "download_url": "https://..." },
    { "format": "txt",  "key": "outputs/myjob123.txt",  "s3_uri": "s3://...", "download_url": "https://..." },
    { "format": "srt",  "key": "outputs/myjob123.srt",  "s3_uri": "s3://...", "download_url": "https://..." }
  ]
}
```

Each output entry carries a `format` field: `json`, `txt`, or `srt`. Download URLs are presigned and expire after \~1 hour.

To list jobs instead of polling a single one, use `GET /v1/batch/jobs`. It supports pagination (`page`, `page_size`) plus filtering by `status`, `model_code`, and submission date range, and sorting by `submitted_at`, `status`, or `model_code`. See the [API reference](https://slng.mintlify.site/api-reference/speechmatics/list-batch-jobs.md) for the full parameter list.

### Delete a job

```bash theme={null}
curl -X DELETE https://api.batch.slng.ai/v1/batch/jobs/myjob123 \
  -H "Authorization: Bearer SLNG_API_KEY"
```

Returns **204 No Content** on success, **404** if the job is unknown or already deleted. Removes the DB record and S3 inputs/outputs.

***

## Errors

All error responses share the same envelope:

```json theme={null}
{ "error": "Short, user-presentable description." }
```

| Status | When |
| - | - |
| 400 | Bad request — invalid input, malformed JSON, non-alphanumeric `job_id`, `s3_key` outside `inputs/<job_id>/` |
| 401 | Missing / invalid / revoked API key |
| 402 | Insufficient balance |
| 404 | Unknown `job_id` |
| 409 | `DELETE` while the job is not in a terminal status (`DONE` / `FAILED`) |
| 413 | Request body exceeds 10 MB — use presigned upload |
| 429 | Rate limited — retry after the delay in the `Retry-After` header |
| 502 | Auth backend unavailable — transient, retry |

***

## Example: full workflow (presigned upload)

```bash theme={null}
# 1. Request presigned URL
step1=$(curl -s -X POST https://api.batch.slng.ai/v1/batch/jobs \
  -H "Authorization: Bearer $SLNG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode":"presign","filename":"audio.wav","transcription_config":{"language":"en"}}')
job_id=$(echo "$step1" | jq -r .job_id)
upload_url=$(echo "$step1" | jq -r .upload.url)
s3_key=$(echo "$step1" | jq -r .upload.s3_key)

# 2. Upload the file directly to S3
curl -X PUT "$upload_url" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @audio.wav

# 3. Create the job referencing the uploaded key
curl -X POST https://api.batch.slng.ai/v1/batch/jobs \
  -H "Authorization: Bearer $SLNG_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"job_id\":\"$job_id\",\"s3_key\":\"$s3_key\",\"transcription_config\":{\"language\":\"en\"}}"

# 4. Poll status
until [ "$(curl -s -H "Authorization: Bearer $SLNG_API_KEY" \
    https://api.batch.slng.ai/v1/batch/jobs/$job_id | jq -r .status)" = "DONE" ]; do
  sleep 5
done

# 5. Fetch transcript URLs
curl -s -H "Authorization: Bearer $SLNG_API_KEY" \
  https://api.batch.slng.ai/v1/batch/jobs/$job_id/files
```

***

## Transcription Config

| Field | Type | Default | Description |
| - | - | - | - |
| `language` | string | `en` | Language code for the audio |
| `operating_point` | string | `enhanced` | Accuracy level: `standard` or `enhanced` |
| `diarization` | string | `none` | Speaker separation: `none`, `speaker`, or `channel` |
| `domain` | string | — | Domain-specific language model |
| `output_locale` | string | — | Locale for formatting (dates, numbers) |
| `enable_entities` | boolean | — | Detect and format entities (dates, times, addresses) |
| `additional_vocab` | array | — | Custom words to improve recognition |

Example with diarization and the default enhanced operating point:

```json theme={null}
{
  "transcription_config": {
    "language": "en",
    "operating_point": "enhanced",
    "diarization": "speaker"
  }
}
```

***

## Limits

| Limit | Value |
| - | - |
| Max request body | 10 MB |
| Presigned upload URL expiry | 1 hour |
| Supported audio formats | wav, mp3, flac, aac, ogg, m4a, mp4, amr, mpeg |
| URL input scheme | HTTPS only |

For files larger than 10 MB, use the presigned upload flow (Method 2) — the file goes directly to S3, bypassing the request-body cap.

***

## Next Steps

> **[Batch API reference](https://slng.mintlify.site/api-reference/speechmatics/create-batch-job.md)**
>
> Endpoint details, request schemas, and response formats

> **[Getting started](https://slng.mintlify.site/getting-started.md)**
>
> Set up your SLNG key and make your first request


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.