Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/speech-to-text/batch/output.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Transcription jobs are processed asynchronously. You can check the status of a j

:::tip
You can also configure notifications to be sent to a webhook when a job is completed. See [Notifications](/speech-to-text/batch/notifications) for more details.
<br/>
To get a transcript in a single blocking call instead of polling, see [Synchronous transcription](/speech-to-text/batch/synchronous).
Comment on lines +26 to +27

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two small things on this tip block:

  1. Avoid <br/> inside an admonition. It's fragile MDX — the new sentence hangs in the tip without paragraph spacing. Cleaner as two separate paragraphs (blank line between them), or split into two admonitions: :::info for "you can also block with synchronous mode" (a routing hint rather than a tip), and keep :::tip for the notifications mention.

  2. The intro at line 22 ("Transcription jobs are processed asynchronously…") now reads as half-true given this PR ships a blocking option. Suggest softening to "Transcription jobs are processed asynchronously by default…" or rephrasing to acknowledge both polling and the new synchronous option.

(Refs: style guide — admonition usage; AI-readability — opening sentence names the subject accurately.)

:::

## Check single job status
Expand Down
4 changes: 4 additions & 0 deletions docs/speech-to-text/batch/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ export default {
type: "doc",
id: "speech-to-text/batch/output",
},
{
type: "doc",
id: "speech-to-text/batch/synchronous",
},
{
type: "doc",
id: "speech-to-text/batch/limits",
Expand Down
120 changes: 120 additions & 0 deletions docs/speech-to-text/batch/synchronous.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
description: 'Block for a transcript in a single request instead of polling for job status.'

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personal opinion, but I find something like this clearer:

Suggested change
description: 'Block for a transcript in a single request instead of polling for job status.'
description: Wait for a transcription job to finish synchronously via HTTP

---
Comment on lines +1 to +3

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing title: in the frontmatter — only description: is set. The style guide requires both title and description on every page (AI-readability standards). Docusaurus falls back to the H1, so the page currently renders fine, but explicit frontmatter keeps search, retrieval, and page metadata consistent across the site.

Suggest:

---
title: Synchronous transcription
description: Block for a transcript in a single request instead of polling for job status.
---


# Synchronous transcription

The `wait` query parameter blocks a request until the job reaches a terminal state, so you can get a transcript in one call instead of polling. It applies to job creation, job status, and transcript retrieval.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's good to spell out the full breadth of the feature from the top for clarity. Maybe something like this:

Suggested change
The `wait` query parameter blocks a request until the job reaches a terminal state, so you can get a transcript in one call instead of polling. It applies to job creation, job status, and transcript retrieval.
The `wait` query parameter lets you block a job request until either:
- The job enters a terminal state (`done` or `rejected`)
- The specified number of seconds elapses.
This allows you to avoid polling the API for job completion. The `wait` parameter can be used for several endpoints: i.e. creating a job, fetching job details, and fetching the full transcript.


:::info
`wait` is available on SaaS on Cloud only. It is not available on on-prem deployments.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me this sounds like we'll never offer it, what do you think?

Suggested change
`wait` is available on SaaS on Cloud only. It is not available on on-prem deployments.
`wait` is available on SaaS on Cloud only. It is not currently available on on-prem deployments.

:::

`wait` takes a number of seconds and is capped server-side. If the job has not finished when `wait` elapses, the request returns the current state and you retry to keep waiting.

## Create a job and wait for the transcript

Pass `wait` to `POST /jobs` to block until the job finishes. Add `format` to choose the embedded transcript format (`json-v2`, `txt`, or `srt`; defaults to `json-v2`).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Pass `wait` to `POST /jobs` to block until the job finishes. Add `format` to choose the embedded transcript format (`json-v2`, `txt`, or `srt`; defaults to `json-v2`).
Pass the `wait` query parameter to `POST /jobs` to block until the job finishes. Add `format` to choose the embedded transcript format (`json-v2`, `txt`, or `srt`; defaults to `json-v2`).


```bash
API_KEY="YOUR_API_KEY"
PATH_TO_FILE="example.wav"

# Create a job and block for up to 60 seconds for a plain-text transcript
curl -L -X POST "https://eu1.asr.api.speechmatics.com/v2/jobs/?wait=60&format=txt" \
-H "Authorization: Bearer ${API_KEY}" \
-F data_file=@${PATH_TO_FILE} \
-F config='{"type": "transcription","transcription_config": { "model": "enhanced", "language": "en" }}'
```

The response is always HTTP 201. When `wait` is set, it includes a `status` field reporting the outcome. On `done`, the transcript is embedded under a key named after the requested format. For `format=txt` (and `srt`) the value is a string:

```json
{
"id": "a1b2c3d4e5",
"status": "done",
"txt": "Welcome to Speechmatics..."
}
```

For the default `format=json-v2`, the value is a nested object with the same shape as the [transcript endpoint](/api-ref/batch/get-the-transcript-for-a-transcription-job) response, not a string. The `results` array is abbreviated below:

```json
{
"id": "uwcl3jevp3",
"status": "done",
"json-v2": {
"format": "2.9",
"job": {
"created_at": "2026-06-23T13:33:24.230Z",
"data_name": "example.wav",
"duration": 10,
"id": "uwcl3jevp3"
},
"metadata": {
"created_at": "2026-06-23T13:33:24.879071Z",
"transcription_config": { "language": "en", "model": "enhanced" },
"type": "transcription"
},
"results": [
{
"alternatives": [
{ "confidence": 1.0, "content": "I", "language": "en", "speaker": "UU" }
],
"start_time": 1.5,
"end_time": 1.79,
"type": "word"
}
]
}
}
```

If the job is still running when `wait` elapses, `status` is `created` and no transcript is embedded:

```json
{
"id": "a1b2c3d4e5",
"status": "created"
}
```

`status` reports the outcome of the wait, which is distinct from the [job lifecycle status](/speech-to-text/batch/output#check-single-job-status):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused about this, I thought status would always return the current status of the job? Or is it just in the case of created after wait that it may be different?


| `status` | Meaning |
|---|---|
| `created` | Created and still running, or `wait` elapsed before it finished. Retry to get the result. |
| `done` | Finished. The transcript is embedded under the requested format key when available. |
| `rejected` | The job could not be processed. |
| `deleted` | The job was deleted before it could finish. |

The embedded transcript is best-effort. If `status` is `done` but no transcript key is present, fetch it from the transcript endpoint.

## Wait when checking job status

Pass `wait` to `GET /jobs/{jobid}` to block until the job reaches a terminal state.

```bash
# Wait up to 30 seconds for the job to reach a terminal state
curl -L -X GET "https://eu1.asr.api.speechmatics.com/v2/jobs/${JOB_ID}?wait=30" \
-H "Authorization: Bearer ${API_KEY}"
```

The response is always HTTP 200 with the job in its current state. If the job is still running when `wait` elapses, retry to keep waiting.

## Wait for the transcript

Pass `wait` to `GET /jobs/{jobid}/transcript` to block until the transcript is ready.

```bash
# Wait up to 30 seconds for the transcript, then return it as plain text
curl -L -X GET "https://eu1.asr.api.speechmatics.com/v2/jobs/${JOB_ID}/transcript?wait=30&format=txt" \
-H "Authorization: Bearer ${API_KEY}"
```

If the transcript becomes ready within `wait`, the response is HTTP 200 with the transcript. Otherwise it returns the usual HTTP 404, and you retry to keep waiting.

## Next steps

- [Output formats](/speech-to-text/batch/output) — load and process the transcript.
- [API reference](/api-ref/batch/create-a-new-job) — full request and response details.
57 changes: 57 additions & 0 deletions spec/batch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,26 @@ paths:
**Note**: Only available for on-prem

JSON dictionary of processing settings for the job worker. Currently supports `parallel_engines` (integer), which controls the number of engines the worker can use in parallel for this job, and `user_id` (string), which is the user id for this job. Example: `{"parallel_engines": 4}`
- name: wait
in: query
type: integer
required: false
description: >-
**Note**: Only available on SaaS on Cloud.

Number of seconds to block until the job reaches a terminal state before responding. Capped server-side. When set, the response includes a `status` field reporting the outcome, and on `done` the transcript is embedded under the requested `format` key when available. When omitted, the request returns as soon as the job is created and `status` is not included.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remember correctly there is a possibility of timeout if someone specifies a very long wait time (like several hours). Is it worth communicating an upper limit either in the spec or in the doc page?

- name: format
in: query
type: string
required: false
enum:
- json-v2
- txt
- srt
description: >-
**Note**: Only available on SaaS on Cloud, and only applies when `wait` is set.

Format of the transcript embedded in the response when the job finishes within `wait`. Defaults to `json-v2`.
responses:
"201":
description: OK
Expand Down Expand Up @@ -159,6 +179,14 @@ paths:
required: true
type: string
x-example: a1b2c3d4e5
- name: wait
in: query
type: integer
required: false
description: >-
**Note**: Only available on SaaS on Cloud.

Number of seconds to block until the job reaches a terminal state before responding. Capped server-side. The response is always returned with HTTP 200 in the job's current state; if the job is still running when `wait` elapses, retry to keep waiting.
responses:
"200":
description: OK
Expand Down Expand Up @@ -286,6 +314,14 @@ paths:
- json-v2
- txt
- srt
- name: wait
in: query
type: integer
required: false
description: >-
**Note**: Only available on SaaS on Cloud.

Number of seconds to block until the transcript is ready before responding. Capped server-side. Returns HTTP 200 with the transcript if it becomes ready within `wait`; otherwise returns the usual HTTP 404, and you can retry to keep waiting.
responses:
"200":
description: OK
Expand Down Expand Up @@ -1107,6 +1143,27 @@ definitions:
type: string
description: >-
The unique ID assigned to the job. Keep a record of this for later retrieval of your completed job.
status:
type: string
description: >-
**Note**: Only available on SaaS on Cloud. Present only when the `wait` query parameter is set. Reports the outcome of the wait, which is distinct from the job lifecycle status returned by `GET /jobs/{jobid}`. * `created` - the job was created and is still running, or `wait` elapsed before it finished. * `done` - the job finished; the transcript is embedded under the requested `format` key when available. * `rejected` - the job could not be processed. * `deleted` - the job was deleted before it could finish.
enum:
- created
- done
- rejected
- deleted
json-v2:
description: >-
**Note**: Only available on SaaS on Cloud. The transcript in `json-v2` format, embedded when `status` is `done` and `format` was `json-v2` (the default). Best-effort: if absent, fetch it from `GET /jobs/{jobid}/transcript`.
$ref: "#/definitions/RetrieveTranscriptResponse"
txt:
type: string
description: >-
**Note**: Only available on SaaS on Cloud. The transcript in plain text, embedded when `status` is `done` and `format` was `txt`. Best-effort: if absent, fetch it from `GET /jobs/{jobid}/transcript`.
srt:
type: string
description: >-
**Note**: Only available on SaaS on Cloud. The transcript in SRT format, embedded when `status` is `done` and `format` was `srt`. Best-effort: if absent, fetch it from `GET /jobs/{jobid}/transcript`.
example:
id: a1b2c3d4e5
JobDetails:
Expand Down