Skip to content
Transcriber Tests

GEThttps://core-api.heysadie.ai/transcriber-banks/{id}/turns

id windowDays kind tag limit cursor format success data columns key transcriberId name role flag organizationId tenantId callId assistantId messageIndex bankId heardText expectedText errorTags comment audio startSeconds endSeconds evaluation controlForTurnId fullCallRunId tieBreak reason label review calibration createdBy createdAt updatedAt liveTranscriber evaluationProgress stage done total tenant assistant attempts turnId sttModel text error match wer notes identicalToProduction audioSeconds leader transcriberIds tieBreakPick nextCursor metadata timestamp version path code message details field

List a bank's turn-by-turn table

The bank's flagged and control turns created in the last `windowDays`, newest first, as a table. - `columns` lists the cells of a row in order: each candidate by position, then each live transcriber as production. Fill a cell from `attempts[column.key]`: a tick when `match` is true, else its `text` and `wer`. No key means no attempt yet. - `leader.transcriberIds` names the candidates that got the line right; `tieBreakPick` and `reason` explain a tie the LLM judge broke. - `flag.evaluation` and `flag.evaluationProgress` show turns still being scored. Filter by `kind` or an error `tag`. Paginate with `limit` and `cursor`: send `nextCursor` back as `cursor` until it is null. With `format=csv`, one row per turn and column for every turn of the window matching `kind` and `tag`, up to 5000 turns. Errors: 404 RESOURCE_NOT_FOUND when the bank is not in the organization.

Try it in the API Explorer

Example request

Terminal
curl "https://core-api.heysadie.ai/transcriber-banks/TRANSCRIBER_BANK_ID/turns" \
  -H "Authorization: ApiKey YOUR_API_KEY"

Authentication

Authenticate with an API key in the Authorization header using the ApiKey scheme. See Authentication for how keys work and where to get them.

Authorizationstringrequired

API key in the ApiKey scheme: ApiKey YOUR_API_KEY. Tenant keys authorize their own tenant; organization keys can act on any tenant in the organization.

X-Tenant-Idstring (uuid)optional

Required when authenticating with an organization key: it selects the tenant the request acts on. Omit with tenant keys.

Request

Path parameters

idstringrequired

A live bank of the organization

Query parameters

windowDaysstringoptional

Days back from now, by turn creation, the scores cover. 1 to 90, default 30

kindstringoptional

flagged or control. Default: both

tagstringoptional

Turns whose error tags include this one

limitstringoptional

Page size, 1 to 200, default 50. Ignored by csv

cursorstringoptional

`nextCursor` of the previous page. Ignored by csv, which exports every turn of the window matching `kind` and `tag`, up to 5000

formatstringoptional

json (default) or csv. csv answers a `text/csv` attachment, one row per flattened record, for a spreadsheet

Responses

200A page of the turn-by-turn table. With `format=csv`, a UTF-8 CSV attachment instead
successbooleanrequired

true on every 2xx

dataobjectoptional

The result

Show 3 child properties
columnsobject[]required

The bank's candidates by position, then the live transcribers of the page's turns as production, by name. Render one cell per column from `attempts[column.key]`

Show 4 item properties
keystringrequired

`<role>:<transcriberId>`, a key of each row's `attempts`

transcriberIdstringrequired

The column's transcriber

namestringrequired

Its display name, for the header

roleenumrequired

candidate: a transcriber under test. production: a live transcriber, scored on its stored call text

Allowed values:"candidate""production"
dataobject[]required

Newest turn first

Show 5 item properties
flagobjectrequired

A tested caller line: a flag, a control sampled with one, or a line of a full-call run

Show 25 child properties
idstringrequired

Turn id

organizationIdstringrequired

The organization that owns the turn

tenantIdstringrequired

The tenant the call belongs to

callIdstringrequired

The call the line is from

assistantIdstring | nullrequired

The assistant that took the call. Null when the call names none

messageIndexstring (integer) | integerrequired

Index of the line in the call's messages, as GET /turn-flags/calls/:callId/lines lists it

bankIdstring | nullrequired

The bank the turn belongs to. Null while it is in no bank, and then no candidate replays it

kindenumrequired

flagged: a person flagged the line as wrong and typed what was said. control: an unflagged caller line of the same call, sampled with a flag, whose expected text is the live transcriber's own. full_call: a caller line replayed by a full-call run, listed under that run

Allowed values:"flagged""control""full_call"
heardTextstringrequired

What the live transcriber wrote for the line on the call, frozen when the turn was created

expectedTextstring | nullrequired

What the caller said, word for word: typed for a flag, the heard text for a control. A full-call turn carries the expected text of a flag on the same line, else null

errorTagsstring[]required

Tags on what went wrong, e.g. `name` or `spelling`. Empty on controls and full-call turns

commentstring | nullrequired

The flagger's note. Null when none

audioobjectrequired

The line's place in the call recording. Transcribers hear it with 0.75 s more on each side, so play `startSeconds - 0.75` to `endSeconds + 0.75`, clamped to the recording, to hear what they heard

Show 2 child properties
startSecondsnumberrequired

Where the line starts, in seconds from the recording start

endSecondsnumberrequired

Where the line ends, in seconds from the recording start

evaluationenumrequired

pending: candidate attempts are queued and not all reported, or the turn was created in no bank. scored: every transcriber its job asked for returned an attempt (a failed attempt counts), or it joined a bank that owed it no attempt. failed: its job ended without an attempt from every transcriber it asked for. A turn taken out of a bank keeps its evaluation, and a backfill does not move a scored turn back to pending: watch `evaluationProgress` for that work

Allowed values:"pending""scored""failed"
controlForTurnIdstring | nullrequired

On a control, the flag it was sampled for. Deleting or moving that flag deletes or moves the control. Null otherwise

fullCallRunIdstring | nullrequired

On a full-call turn, its run. Null otherwise

tieBreakobject | nullrequired

When two or more candidates match the expected text with different raw text (casing, punctuation), the one an LLM judge found fits the venue best. Null otherwise

Show 2 child properties
transcriberIdstringrequired

The candidate whose text the judge picked

reasonstringrequired

The judge's one-sentence reason

labelenum | nullrequired

On a full-call turn where the candidate differs from production, its label: decided by the expected-text matches where the line has expected text, else by the LLM judge. candidate_right: the candidate has what the caller said and production does not. production_right: production has it and the candidate does not. same_meaning: they differ in a way that does not matter. both_wrong: neither has it. Null otherwise or until the analysis labels it

Allowed values:"candidate_right""production_right""same_meaning""both_wrong"
reviewenum | nullrequired

On a full-call turn, a person's verdict from POST /full-call-runs/:id/reviews, in the same values as `label`. It counts only on differing turns, and outranks the label in `fixed` and `introduced` only where the line has no expected text. Null until reviewed

Allowed values:"candidate_right""production_right""same_meaning""both_wrong"
calibrationbooleanrequired

On a full-call turn, whether production is also replayed on it to measure replay against the live text. False otherwise

createdBystring | nullrequired

Who made it, as the creating request named them in an `X-On-Behalf-Of` header. Null when it sent none

createdAtstring (date-time) | string (date) | number | nullrequired

When it was created, UTC

updatedAtstring (date-time) | string (date) | number | nullrequired

When it last changed, UTC

liveTranscriberobject | nullrequired

The transcriber the turn's call ran on, recorded when the turn was created. Its stored text is the turn's production attempt. Null when unknown

Show 2 child properties
idstringrequired

Transcriber id, as GET /transcribers lists it

namestringrequired

The transcriber's display name

evaluationProgressobject | nullrequired

The newest open transcribe job holding the turn, for a progress bar. Null when no open job holds it (scored, failed or never queued), and on the POST /turn-flags response, which is written before its job is queued: read the turn again to see it

Show 3 child properties
stageenumrequired

waiting: the job is queued or dispatched and no worker has started it. scoring: a worker is running it

Allowed values:"waiting""scoring"
donestring (integer) | integerrequired

Transcriptions the job has finished, over every clip and transcriber it holds, not this turn's alone. 0 until the worker first reports

totalstring (integer) | integerrequired

Transcriptions the job holds in all

tenantobjectrequired

A tenant of the organization

Show 2 child properties
idstringrequired

Tenant id

namestringrequired

The tenant's name

assistantobject | nullrequired

The assistant that took the call. Null when the call names none

Show 2 child properties
idstringrequired

Assistant id

namestringrequired

The assistant's name

attemptsmap<string, object>required

Every candidate and production attempt of the turn, keyed `<role>:<transcriberId>`. A column with no key here has no attempt yet

Show 11 map values
turnIdstringrequired

The turn the attempt is on

transcriberIdstringrequired

The transcriber that made the attempt

roleenumrequired

candidate: a transcriber under test, replayed on the clip. production: the live transcriber's stored text from the call, never replayed, at no cost. calibration: the live transcriber replayed on the clip, on a full-call run's calibration sample

Allowed values:"candidate""production""calibration"
sttModelstringrequired

Provider and model, e.g. "deepgram/nova-3". Display only

textstring | nullrequired

The transcript. Null when the attempt failed

errorstring | nullrequired

Why the attempt failed. Null when it succeeded. A failed attempt counts in `errors`, not `scored`

matchboolean | nullrequired

Whether the text equals the expected text after normalizing (lowercase, punctuation dropped except in-word apostrophes, whitespace collapsed; digits and number words stay distinct). Null when the turn has no expected text or the attempt failed

wernumber | nullrequired

Word error rate against the expected text: word edits divided by the expected word count, 0 for a match, can exceed 1. Null when there is no expected text or text

notesenum[]required

On a match, how the raw text still differs from the expected: `case`, `punctuation`, or both. Empty otherwise

Allowed values:"case""punctuation"
identicalToProductionboolean | nullrequired

On a candidate or calibration attempt of a full-call turn, whether its text equals production's, normalized. Null for production attempts, flagged and control turns, and failed attempts

audioSecondsnumberrequired

Seconds of audio the transcriber processed for the attempt. 0 for production attempts, which replay nothing

leaderobjectrequired

Who got this turn right

Show 3 child properties
transcriberIdsstring[]required

The bank's candidates whose attempt matches, by position

tieBreakPickstring | nullrequired

When several match with different raw text, the candidate the judge picked. Null otherwise

reasonstring | nullrequired

The judge's reason for the pick

nextCursorstring | nullrequired

Send as `cursor` for the next page. Null on the last page

metadataobjectoptional

Request metadata

Show 3 child properties
timestampstringrequired

When the server answered, ISO 8601 UTC

versionstringrequired

API version

pathstringoptional

The URL that was requested

400VALIDATION_ERROR: a path id, query parameter or body field broke a rule; `details` lists each `field` and its `message`. A body with a missing field or a JSON type the schema does not allow answers 400 with code INTERNAL_SERVER_ERROR and no `details` instead, so branch on the status
successbooleanrequired

false on every error

errorobjectoptional

What went wrong: a stable `code` to branch on and a human-readable `message`

Show 3 child properties
codeenumrequired

A parameter or body field broke a rule

Allowed values:"VALIDATION_ERROR"
messagestringrequired

Human-readable explanation. Do not parse it; branch on `code`

detailsobject[]optional

One entry per field that failed

Show 2 item properties
fieldstringrequired

The offending field

messagestringrequired

The rule it broke

metadataobjectoptional

Request metadata

Show 3 child properties
timestampstringrequired

When the server answered, ISO 8601 UTC

versionstringrequired

API version

pathstringoptional

The URL that was requested

401UNAUTHORIZED: no valid credentials, or a dashboard token that names no organization. Send `Authorization: ApiKey <organization API key>`
successbooleanrequired

false on every error

errorobjectoptional

What went wrong: a stable `code` to branch on and a human-readable `message`

Show 2 child properties
codeenumrequired

No valid credentials

Allowed values:"UNAUTHORIZED"
messagestringrequired

Human-readable explanation. Do not parse it; branch on `code`

metadataobjectoptional

Request metadata

Show 3 child properties
timestampstringrequired

When the server answered, ISO 8601 UTC

versionstringrequired

API version

pathstringoptional

The URL that was requested

403ORG_SCOPE_REQUIRED: transcriber testing is an organization feature. Use an organization API key without `X-Tenant-Id`, or a dashboard token scoped to the organization. A tenant API key, an organization key sent with `X-Tenant-Id` for one of its tenants, or a token carrying a tenant gets this 403. FORBIDDEN: an organization key sent `X-Tenant-Id` for a tenant outside its organization
successbooleanrequired

false on every error

errorobjectoptional

What went wrong: a stable `code` to branch on and a human-readable `message`

Show 2 child properties
codeenumrequired

ORG_SCOPE_REQUIRED: the credentials carry a tenant scope. FORBIDDEN: an organization key sent `X-Tenant-Id` for a tenant outside its organization

Allowed values:"ORG_SCOPE_REQUIRED""FORBIDDEN"
messagestringrequired

Human-readable explanation. Do not parse it; branch on `code`

metadataobjectoptional

Request metadata

Show 3 child properties
timestampstringrequired

When the server answered, ISO 8601 UTC

versionstringrequired

API version

pathstringoptional

The URL that was requested

404RESOURCE_NOT_FOUND: an id in the path, query or body names nothing in the caller's organization. `message` names what, e.g. "Transcriber bank not found"
successbooleanrequired

false on every error

errorobjectoptional

What went wrong: a stable `code` to branch on and a human-readable `message`

Show 2 child properties
codeenumrequired

An id names nothing the caller can see

Allowed values:"RESOURCE_NOT_FOUND"
messagestringrequired

Human-readable explanation. Do not parse it; branch on `code`

metadataobjectoptional

Request metadata

Show 3 child properties
timestampstringrequired

When the server answered, ISO 8601 UTC

versionstringrequired

API version

pathstringoptional

The URL that was requested

500An unexpected server error
successbooleanrequired

false on every error

errorobjectoptional

What went wrong: a stable `code` to branch on and a human-readable `message`

Show 2 child properties
codeenumrequired

An unexpected server failure

Allowed values:"INTERNAL_SERVER_ERROR"
messagestringrequired

Human-readable explanation. Do not parse it; branch on `code`

metadataobjectoptional

Request metadata

Show 3 child properties
timestampstringrequired

When the server answered, ISO 8601 UTC

versionstringrequired

API version

pathstringoptional

The URL that was requested