Hear2Text

API reference

Every endpoint in v1.0.0, generated from the OpenAPI document the API is tested against.

Base URL https://heartotext.com/api/public/v1. Every request needs Authorization: Bearer h2t_live_… unless the operation says otherwise. This page is generated from the OpenAPI 3.1 document, which is the same file our contract test validates real responses against — if something here is wrong, the build is red.

GET/me

The calling key, its plan and its limits

A projection of the account's entitlements. The numbers here are the ones that actually bind a request -- the same ceilings the apps are held to -- so a client can decide whether to send a recording before sending it.

StatusMeaning
200The account behind this key.
401No key, an unreadable key, a revoked key, or a token from somewhere else.
403The key is real but may not do this: no active subscription, a missing scope, a restricted account, a workspace the key is not pinned to.
429Too many requests in one of the windows. Wait `Retry-After` seconds. The daily fair-use allowance is not one of them: a recording over it is accepted and then fails with `failure_reason: quota_exceeded`.

GET/languages

The language codes a create accepts

ISO codes only. Numeric identifiers never cross this boundary, in either direction, so a row being renumbered in our database cannot break your integration.

StatusMeaning
200Every language this API accepts.
401No key, an unreadable key, a revoked key, or a token from somewhere else.
403The key is real but may not do this: no active subscription, a missing scope, a restricted account, a workspace the key is not pinned to.
429Too many requests in one of the windows. Wait `Retry-After` seconds. The daily fair-use allowance is not one of them: a recording over it is accepted and then fails with `failure_reason: quota_exceeded`.

GET/openapi.json

This document, as JSON

Unauthenticated -- the description of the API is not a secret, and a code generator should not need a key to read it.

StatusMeaning
200The OpenAPI 3.1 description of this API.

GET/postman.json

This API as a Postman collection

The same endpoints as a Postman v2.1 collection, generated from this document. Unauthenticated, for the same reason the document is.

StatusMeaning
200A Postman v2.1 collection.

POST/transcriptions

Start a recording

Send either a `file` (multipart) or a `url` (JSON or multipart), never both-or-neither. The recording is queued immediately and the response describes it in its `queued` state; poll it until it is `completed`. Send an `Idempotency-Key`. A retry of the same key with the same body replays the stored answer instead of starting a second recording.

ParameterInRequiredDescription
Idempotency-KeyheadernoA unique string you choose per logical create, 255 characters or fewer. A replay with the same body returns the first answer and `Idempotency-Replayed: true`; the same key with a different body is a 409. Keys are remembered for 24 hours and are scoped to one API key.
StatusMeaning
201The recording, queued.
401No key, an unreadable key, a revoked key, or a token from somewhere else.
403The key is real but may not do this: no active subscription, a missing scope, a restricted account, a workspace the key is not pinned to.
409The request cannot be answered in the account's current state: the concurrency ceiling is full, an `Idempotency-Key` was reused or is still in flight, or the recording has not finished yet.
413The request body is over what the server accepts at all. A file that arrives but is over the per-file ceiling is a 422 `validation_failed` naming `file` instead.
422The request could not be accepted as sent.
429Too many requests in one of the windows. Wait `Retry-After` seconds. The daily fair-use allowance is not one of them: a recording over it is accepted and then fails with `failure_reason: quota_exceeded`.

GET/transcriptions

The recordings this key can see

Newest first. A key pinned to a workspace sees that workspace only; an unpinned key sees the personal space.

ParameterInRequiredDescription
limitquerynoPage size. 1-1000.
cursorquerynoThe `next_cursor` of the previous page. Opaque -- do not parse it, and do not construct one.
statusquerynoKeep only recordings in this state.
StatusMeaning
200One page of recordings.
401No key, an unreadable key, a revoked key, or a token from somewhere else.
403The key is real but may not do this: no active subscription, a missing scope, a restricted account, a workspace the key is not pinned to.
422The request could not be accepted as sent.
429Too many requests in one of the windows. Wait `Retry-After` seconds. The daily fair-use allowance is not one of them: a recording over it is accepted and then fails with `failure_reason: quota_exceeded`.

GET/transcriptions/{id}

One recording, with its progress

The endpoint you poll. `progress` is filled in while the recording is being worked on and is the only endpoint that reports it per-recording.

ParameterInRequiredDescription
idpathyesThe recording's public identifier, as returned on create.
StatusMeaning
200The recording.
401No key, an unreadable key, a revoked key, or a token from somewhere else.
403The key is real but may not do this: no active subscription, a missing scope, a restricted account, a workspace the key is not pinned to.
404No such recording, or not one this key can see.
429Too many requests in one of the windows. Wait `Retry-After` seconds. The daily fair-use allowance is not one of them: a recording over it is accepted and then fails with `failure_reason: quota_exceeded`.

DELETE/transcriptions/{id}

Delete a recording

Permanent, and it takes the audio, the transcript and the embeddings with it. Only a recording that has completed or failed can be deleted: one still queued or processing answers 409 `transcription_still_processing`, so wait for it to finish or fail.

ParameterInRequiredDescription
idpathyesThe recording's public identifier, as returned on create.
StatusMeaning
204Deleted. No body.
401No key, an unreadable key, a revoked key, or a token from somewhere else.
403The key is real but may not do this: no active subscription, a missing scope, a restricted account, a workspace the key is not pinned to.
404No such recording, or not one this key can see.
409The request cannot be answered in the account's current state: the concurrency ceiling is full, an `Idempotency-Key` was reused or is still in flight, or the recording has not finished yet.
429Too many requests in one of the windows. Wait `Retry-After` seconds. The daily fair-use allowance is not one of them: a recording over it is accepted and then fails with `failure_reason: quota_exceeded`.

GET/transcriptions/{id}/segments

The transcript, a page at a time

Ordered by offset -- reading order. `speaker` is a diarization label (`A`, `B`, ...) and is stable within one recording only; it does not identify a person and does not carry across recordings.

ParameterInRequiredDescription
idpathyesThe recording's public identifier, as returned on create.
limitquerynoPage size. 1-1000.
cursorquerynoThe `next_cursor` of the previous page. Opaque -- do not parse it, and do not construct one.
StatusMeaning
200One page of transcript.
401No key, an unreadable key, a revoked key, or a token from somewhere else.
403The key is real but may not do this: no active subscription, a missing scope, a restricted account, a workspace the key is not pinned to.
404No such recording, or not one this key can see.
422The request could not be accepted as sent.
429Too many requests in one of the windows. Wait `Retry-After` seconds. The daily fair-use allowance is not one of them: a recording over it is accepted and then fails with `failure_reason: quota_exceeded`.

GET/transcriptions/{id}/export

The transcript as a file

The bytes are streamed back with the right content type -- there is no signed URL to follow, because the files are rendered on demand rather than stored. Only a `completed` recording can be exported.

ParameterInRequiredDescription
idpathyesThe recording's public identifier, as returned on create.
formatqueryyesThe file to build.
languagequerynoAn ISO code, when the transcript exists in more than one language. Defaults to the recording's own.
StatusMeaning
200The file.
401No key, an unreadable key, a revoked key, or a token from somewhere else.
403The key is real but may not do this: no active subscription, a missing scope, a restricted account, a workspace the key is not pinned to.
404No such recording, or not one this key can see.
409The request cannot be answered in the account's current state: the concurrency ceiling is full, an `Idempotency-Key` was reused or is still in flight, or the recording has not finished yet.
422The request could not be accepted as sent.
429Too many requests in one of the windows. Wait `Retry-After` seconds. The daily fair-use allowance is not one of them: a recording over it is accepted and then fails with `failure_reason: quota_exceeded`.

Objects

The shapes the endpoints above return.

Transcription

FieldTypeDescription
idstringThe public identifier. Use it in every other path.
statusstringWhere the recording is. Four words, deliberately fewer than the pipeline has internally: an integration should not have to know which of our jobs currently holds the row.
titlenull | stringYours if you sent one, ours once the recording has been read.
languagenull | stringThe ISO code, once known. Null while auto-detection is pending.
duration_secondsnull | integerLength of the recording, once measured.
created_atstringISO 8601 with offset.
updated_atstringISO 8601 with offset.
sourceobject
workspacenull | stringThe workspace's name when the key is pinned to one, else null.
progressobjectHow far along the recording is, when we can say. `percent` is null and `indeterminate` is true for the stretches we cannot measure.
failure_reasonnull | stringWhy it failed, or null.

Segment

FieldTypeDescription
indexintegerPosition in the recording, zero-based and continuous across pages. Not a database identifier.
startnull | numberSeconds from the start of the recording.
endnull | numberSeconds from the start of the recording.
speakernull | stringA diarization label, stable within this recording only.
textnull | string

Me

FieldTypeDescription
plannull | string
subscription_statusnull | string
limitsobject
usageobject
rate_limitsobject
keyobject

Language

FieldTypeDescription
codestring
namestring

Progress

FieldTypeDescription
stepnull | stringA coarse name for what is happening.
percentnull | number0-100, or null when it cannot be measured.
indeterminateboolean

Error

FieldTypeDescription
errorstringA stable machine-readable code from the catalogue.
messagestring
errorsobjectField-by-field detail, on `validation_failed` only.
docsstringWhere to read about this refusal, on the gating 403s.
requiredstringThe scope the route wanted, on `insufficient_scope`.
scopestring
limitinteger
secondsinteger
workspacestring

Generating a client

Point any OpenAPI generator at the document and it will build you a typed client.

openapi-generator
openapi-generator-cli generate \
  -i https://heartotext.com/api/public/v1/openapi.json \
  -g python \
  -o ./hear2text-client