See a job's state and result
GET /v1/jobs/{id}
Poll until status is done or failed. A done job holds its
result; a failed one holds its error.
A job that fails for a reason in the request (an unreadable file, text
that does not match) fails at once with that reason. One that fails on
our side is tried again, up to three times, and goes back to queued
in between. Jobs of a suspended account wait in queued until it is
restored.
Authentication
Send Authorization: Bearer $KEY from your server. Create or rotate keys.
Example request
curl https://play.fellowverse.app/v1/jobs/job_Hk3vQ9xTmP2a \
-H "Authorization: Bearer $KEY"
Example IDs are placeholders. Use the upload or job ID returned by your own request.
Parameters
| Name | In | Required | Type | Description and constraints |
|---|---|---|---|---|
id |
path | Yes | string | The job id returned when the alignment was started. |
Responses
| Status | Meaning |
|---|---|
| 200 | The job. |
| 401 | The key is missing, wrong, revoked, or past the end of its grace period after a roll. The code is api_unauthorized, and the reason says which. |
| 403 | The account is suspended (api_suspended), or a live key was used on an account that has test keys only (api_live_locked). |
| 404 | The upload, job or clip does not exist, or belongs to another account. The codes are api_upload_missing, api_job_missing and api_file_missing. api_off means the request went to an address that does not serve the API; use https://play.fellowverse.app. |
| 500 | Something went wrong on our side. The code is internal. |
200: application/json
| Field | Type | Required | Description and constraints |
|---|---|---|---|
id |
string | Yes | |
kind |
string | Yes | One of alignment. |
status |
string | Yes | One of queued, running, done, failed. |
attempts |
integer | Yes | How many times the job has been started. Minimum: 0. Maximum: 3. |
createdAt |
string | Yes | Format: date-time. |
finishedAt |
string or null | Yes | Format: date-time. |
result |
object | No | Present when the job is done. Times are milliseconds in the file you uploaded. |
result.passage |
object | No | For an alignment sent without text, the passage the recording was found to read. |
result.passage.reference |
string | Yes | |
result.passage.book |
string | Yes | The standard book code. |
result.passage.bookName |
string | Yes | |
result.passage.firstChapter |
integer | Yes | Minimum: 1. |
result.passage.firstVerse |
integer | Yes | Minimum: 1. |
result.passage.lastChapter |
integer | Yes | Minimum: 1. |
result.passage.lastVerse |
integer | Yes | Minimum: 1. |
result.passage.translation |
string | Yes | Always World English Bible (public domain). |
result.durationMs |
integer | Yes | The length of the recording. |
result.matched |
number | Yes | The share of your text's words heard as written. Below 0.5 the job fails, because the audio does not read the text. Minimum: 0.5. Maximum: 1. |
result.speechStartMs |
integer | Yes | Where the text starts being read. |
result.speechEndMs |
integer | Yes | Where the text stops being read. |
result.droppedBefore |
string | Yes | What was heard before the text and left out, such as an announcement. |
result.droppedAfter |
string | Yes | What was heard after the text and left out. |
result.segments |
object[] | Yes | One per section you sent, in the same order. |
result.segments[].id |
string | Yes | Your id for the section, or the verse id, such as PSA.23.1, for a Bible reading. |
result.segments[].reference |
string | No | For a Bible reading, the verse, such as "Psalm 23:1". |
result.segments[].text |
string | No | For a Bible reading, the verse's text. |
result.segments[].startMs |
integer | Yes | |
result.segments[].endMs |
integer | Yes | |
result.segments[].clip |
string | No | The clip's name, when clips were asked for. Fetch it from /v1/jobs/{id}/files/{name}. |
result.words |
object[] | Yes | Every word of your text, in order, with when it is spoken. |
result.words[].text |
string | Yes | |
result.words[].startMs |
integer | Yes | |
result.words[].endMs |
integer | Yes | |
error |
object | No | Present when the job failed. |
error.code |
string | No | A stable code to branch on, such as api_passage_unknown when a recording sent without text is not a Bible reading. Jobs that failed before October 2026 have none. |
error.problem |
string | Yes | What went wrong. |
error.reason |
string | Yes | Why it went wrong. |
error.fix |
string | Yes | What would change the outcome. |
“Required” is relative to the containing object. Optional success results and failure errors depend on the job state.
Errors and limits
JSON errors contain error.code, error.problem, error.reason and error.fix. Handle errors and retries and check test and live limits.
Need the contract? Download OpenAPI. Manage keys and account access in the developer console.