Capture an HTTP TTS service-frame stream
This is a direct platform HTTP operation.
/http/ttsThis is a direct platform HTTP operation. JavaScript and Python SDK
0.18.0 use Socket.IO and do not call this route. Send it from a
trusted backend with X-Api-Key and the TTS capability.
Send a fresh UUID id, top-level text containing at least one Unicode
letter or number after trimming, and the explicit model key nebula.
For predictable voice selection, send exactly one voice_id or one
voice_references entry, never both. Obtain a voice_id through SDK
listVoices() or list_voices(); no HTTP voice-list operation exists.
The returned UUID identifies one of the seven multilingual voice
profiles. Its physical variants are internal and direct use of a
physical variant UUID is rejected.
If model is omitted, the deployment uses its configured default model
key, falling back to nebula. If the voice selector is omitted, voice
selection is deployment-specific.
The service counts Unicode code points, not UTF-8 bytes or displayed
grapheme clusters. Leading and trailing whitespace is preserved and
counts toward the limit. Inclusive defaults are 500 code points for
free accounts and 1,000 for standard and enterprise accounts. Missing
or unknown tiers use the free limit. Deployments can independently
override these limits with TTS_MAX_INPUT_CHARACTERS_FREE,
TTS_MAX_INPUT_CHARACTERS_STANDARD, and
TTS_MAX_INPUT_CHARACTERS_ENTERPRISE, so this schema intentionally does
not declare a fixed maxLength.
Reference audio must be standard-base64 RIFF/WAVE containing nonempty
mono PCM16 audio, accompanied by its transcript.
An HTTP 200 body is an undelimited sequence of service frames: 16 raw
UUID bytes, one final-flag byte, then 16 kHz PCM16 little-endian bytes.
Ordinary HTTP read boundaries do not preserve service-frame boundaries,
so this body is neither generically decodable raw PCM nor WAV. Save it
only as a protocol capture. Use Socket.IO TTS and the TTS-to-WAV recipe
for playable output.
Apply finite connect, inactivity/read, and overall deadlines. EOF or
cancellation without a boundary-aware final flag is incomplete.
Aborting the HTTP request cancels only its in-flight synthesis. A
failure after bytes were committed ends the partial binary stream; the
service never appends an error JSON document to a binary 200 body.
Keep partial bytes separate from complete output. This operation has no
idempotency contract; use a fresh UUID for an application-approved
retry.
Authorization
ApiKeyAuth In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/octet-stream
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -sS --fail-with-body --connect-timeout 10 --max-time 120 -X POST \ "https://example.com/http/tts" \ -H "Origin: https://example.com" \ -H "Content-Type: application/json" \ --data '{ "id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8", "text": "Hello from HUMAIN Voice", "model": "nebula"}'Undelimited TTS service-frame sequence, not raw PCM or WAV. Ordinary HTTP read chunks are not service-frame boundaries. Only a client with an environment-specific framing mechanism can identify the final flag; EOF alone does not prove completion.
application/octet-stream
Malformed input, including an unparseable request id, or missing/unusable
text or voice reference. These validation failures are non-retryable and
occur before synthesis begins.
Valid text rejected by the TTS content policy is also reported here as
TTS_INPUT_NOT_ALLOWED. It is non-retryable: the same text will not be
accepted, so change the text before sending another request.
A malformed request id is reported as VALIDATION_INVALID_FORMAT,
together with every other malformed-body failure: the id is parsed
during JSON decoding, so an unparseable value fails the whole body rather
than reaching a dedicated check. The request id itself never yields
VALIDATION_INVALID_UUID on this route.
A caller-supplied voice_id IS reported here (SAU-2258): a voice_id
that is not a valid UUID is VALIDATION_INVALID_UUID, and a well-formed
voice_id that does not identify an available voice is
TTS_VOICE_NOT_FOUND. Both are 400 and non-retryable — resending the
same voice_id cannot succeed; fix it or send voice_references
instead. (Voice data that is present but incomplete or corrupt, or a
proven storage/database outage, are server-side conditions reported as
500/503 — see the 500 and 503 responses.)
Text and reference OVERAGES are not here: exceeding the tier character
limit, the reference transcript limit or the reference count is 422,
and an oversized decoded reference is 413.
application/json
Example invalid_body
{
"error": "Invalid request body",
"code": "VALIDATION_INVALID_FORMAT",
"detail": "Invalid request body",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}The request `id` is not a valid UUID, so the body fails to decode
{
"error": "Invalid request body",
"code": "VALIDATION_INVALID_FORMAT",
"detail": "Invalid request body",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}Text is empty or contains only Unicode whitespace
{
"error": "TTS input must contain non-whitespace text",
"code": "VALIDATION_REQUIRED_FIELD",
"detail": "TTS input must contain non-whitespace text",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}voice_id and voice_references were both supplied
{
"error": "voice_id and voice_references are mutually exclusive",
"code": "VALIDATION_INVALID_PARAM",
"detail": "voice_id and voice_references are mutually exclusive",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}An explicit empty array; omit the property instead
{
"error": "voice_references must contain exactly one reference when present; omit the field to use the default voice",
"code": "VALIDATION_INVALID_PARAM",
"detail": "voice_references must contain exactly one reference when present; omit the field to use the default voice",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}Reference audio is not canonical base64 mono PCM16 RIFF/WAVE
{
"error": "voice_references[0].audio is not valid reference audio: audio must be a RIFF/WAVE file",
"code": "VALIDATION_INVALID_FORMAT",
"detail": "voice_references[0].audio is not valid reference audio: audio must be a RIFF/WAVE file",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}Reference transcript is missing or whitespace-only
{
"error": "voice_references[0].text must contain the reference transcript",
"code": "VALIDATION_REQUIRED_FIELD",
"detail": "voice_references[0].text must contain the reference transcript",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}voice_id is present but not a valid UUID
{
"error": "voice_id must be a valid UUID",
"code": "VALIDATION_INVALID_UUID",
"detail": "voice_id must be a valid UUID",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}voice_id is a valid UUID but does not identify an available voice
{
"error": "voice_id does not identify an available voice",
"code": "TTS_VOICE_NOT_FOUND",
"detail": "voice_id does not identify an available voice",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}Text rejected by the TTS content policy
{
"error": "TTS input is not allowed",
"code": "TTS_INPUT_NOT_ALLOWED",
"detail": "TTS input is not allowed",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}Unauthorized
application/json
Example missing_key
{
"error": "Invalid authentication",
"code": "AUTH_UNAUTHORIZED",
"detail": "Invalid authentication",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}The API key does not grant access to the requested voice capability
application/json
Example scope_denied
{
"error": "scope not permitted",
"code": "AUTH_FORBIDDEN",
"detail": "scope not permitted",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}Method not allowed
application/json
Example wrong_method
{
"error": "method not allowed",
"code": "METHOD_NOT_ALLOWED",
"detail": "method not allowed",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}The request body exceeded the configured limit for this route (16 MiB for TTS request bodies). This failure is non-retryable at the same size; send a smaller request.
The request-BODY form of this response carries no data object. The three
audio routes answer an oversized body with the same status and code but DO
include data; see their own 413 documentation.
POST /http/tts also answers this status when a voice reference's DECODED
audio exceeds the deployment's per-reference byte ceiling (default 2 MiB),
and that form DOES carry data with bound
tts_voice_reference_bytes and unit bytes. It is checked from the
base64 length before the payload is decoded, so an oversized reference is
never materialised.
application/json
Example body_too_large
{
"error": "request body too large",
"code": "PAYLOAD_TOO_LARGE",
"detail": "request body too large",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}Decoded reference audio exceeds the per-reference byte ceiling
{
"error": "voice_references[0].audio decodes to 3145728 bytes; limit is 2097152",
"code": "PAYLOAD_TOO_LARGE",
"detail": "voice_references[0].audio decodes to 3145728 bytes; limit is 2097152",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z",
"data": {
"limit": 2097152,
"observed": 3145728,
"unit": "bytes",
"bound": "tts_voice_reference_bytes"
}
}The request parsed correctly and every field is individually valid, but a
SEMANTIC workload unit exceeds its ceiling (RFC 9110 15.5.21). A few
hundred bytes of text can ask for far more synthesis work than its size
suggests, so these bounds cannot be expressed as a byte cap and are
never 413.
data.bound names which ceiling was hit:
tts_input_characters-textis longer than the account tier's character limit (defaults: 500 free, 1,000 standard and enterprise).tts_voice_reference_text_characters-voice_references[0].textis longer than the reference-transcript limit (default 500).tts_voice_reference_count- more than one entry invoice_references; the publishedmaxItemsis 1.tts_voice_reference_duration- the decoded reference audio is longer than the deployment's ceiling (default 15 seconds), which matches the deployed model's own reference limit.data.observedis in whole seconds, rounded up.
Every one of these is checked before any model lookup, admission or charge, so a rejected request consumes no quota and no concurrency slot. Not retryable: resending the identical request cannot succeed.
application/json
Text exceeds the default free-tier runtime limit
{
"error": "TTS input contains 501 characters; limit is 500",
"code": "CHARACTER_COUNT_EXCEEDED",
"detail": "TTS input contains 501 characters; limit is 500",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z",
"data": {
"limit": 500,
"observed": 501,
"unit": "characters",
"bound": "tts_input_characters"
}
}Reference transcript exceeds its own independent limit
{
"error": "voice_references[0].text contains 501 characters; limit is 500",
"code": "CHARACTER_COUNT_EXCEEDED",
"detail": "voice_references[0].text contains 501 characters; limit is 500",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z",
"data": {
"limit": 500,
"observed": 501,
"unit": "characters",
"bound": "tts_voice_reference_text_characters"
}
}More than the published maxItems of 1
{
"error": "voice_references contains 2 references; limit is 1",
"code": "VOICE_REFERENCE_COUNT_EXCEEDED",
"detail": "voice_references contains 2 references; limit is 1",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z",
"data": {
"limit": 1,
"observed": 2,
"unit": "references",
"bound": "tts_voice_reference_count"
}
}Reference clip longer than the deployed model's reference limit
{
"error": "voice_references[0].audio is 16 seconds long; limit is 15",
"code": "AUDIO_DURATION_EXCEEDED",
"detail": "voice_references[0].audio is 16 seconds long; limit is 15",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z",
"data": {
"limit": 15,
"observed": 16,
"unit": "seconds",
"bound": "tts_voice_reference_duration"
}
}The account already has as many concurrent operations of this kind in flight as its plan allows, counted across every server instance (SAU-2181). The limit is per BILLABLE ACCOUNT, so several API keys belonging to one account share a single allowance and creating more keys does not raise it. Each workload has its own allowance, so realtime ASR and TTS do not compete with one another.
This is RETRYABLE and usually clears within seconds, as soon as one of
the account's in-flight operations finishes. Honour the Retry-After
header.
Do not confuse this with the other 429 on these routes: the gateway's
per-key REQUEST-RATE limit reports RATE_LIMIT_EXCEEDED, and the
per-connection HTTP session cap reports SESSION_SLOTS_EXHAUSTED. The
code field distinguishes them. No credit or quota is consumed by a
rejection.
application/json
Example account_concurrency_exhausted
{
"error": "too many concurrent operations for this account",
"code": "CONCURRENCY_LIMIT_EXCEEDED",
"detail": "too many concurrent operations for this account",
"retryable": true,
"timestamp": "2026-01-15T10:30:00Z",
"data": {
"limit": 4,
"observed": 4,
"unit": "operations",
"bound": "account_concurrency_tts"
}
}TTS failed before binary output was committed. If output was already
committed, the partial binary 200 stream ends without an appended JSON
error.
This status carries two distinct codes. TTS_SYNTHESIS_FAILED is the
retryable case: a model-resolution, capacity, or inference failure that a
later attempt may clear. TTS_VOICE_RESOLUTION_FAILED (SAU-2258) is
non-retryable: a resolved voice whose stored data is incomplete or
corrupt (missing audio or transcript, an unusable stored URI, or audio
that is not INT16 PCM), or an unclassified database/storage error.
Resending the identical request cannot fix broken server-side voice data.
Text and voice-REFERENCE validation failures do NOT reach here: they are
reported as 400, 413 or 422 with a specific code before synthesis
begins. A caller-supplied voice_id that is invalid or unknown is also
not here — it is 400 (VALIDATION_INVALID_UUID / TTS_VOICE_NOT_FOUND);
a proven database/storage outage during voice resolution is 503
(SERVER_DEPENDENCY_FAILURE, retryable).
application/json
Retryable model/capacity/inference failure
{
"error": "TTS synthesis failed",
"code": "TTS_SYNTHESIS_FAILED",
"detail": "TTS synthesis failed",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": true,
"timestamp": "2026-01-15T10:30:00Z"
}Resolved voice has incomplete/corrupt stored data (non-retryable)
{
"error": "selected voice could not be resolved",
"code": "TTS_VOICE_RESOLUTION_FAILED",
"detail": "selected voice could not be resolved",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": false,
"timestamp": "2026-01-15T10:30:00Z"
}A required dependency was temporarily unavailable. The response is retryable: the identical request may succeed once that dependency recovers.
TTS_MODERATION_UNAVAILABLE means the content-moderation authority could
not make a decision, so synthesis failed closed. It is deliberately
distinct from TTS_INPUT_NOT_ALLOWED: an infrastructure failure must not
be reported as a policy rejection.
SERVER_DEPENDENCY_FAILURE is a positively-classified transient database
or object-storage outage while resolving voice_id (SAU-2258). It is
distinct from 500 TTS_VOICE_RESOLUTION_FAILED, which identifies broken
server-side voice data that a retry cannot fix. Both checks run before
quota deduction, rate-limit charge or inference, so a retried request is
not double-charged.
application/json
Transient database/storage outage during voice resolution
{
"error": "voice resolution is temporarily unavailable",
"code": "SERVER_DEPENDENCY_FAILURE",
"detail": "voice resolution is temporarily unavailable",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": true,
"timestamp": "2026-01-15T10:30:00Z"
}Content-moderation authority temporarily unavailable
{
"error": "TTS moderation is unavailable",
"code": "TTS_MODERATION_UNAVAILABLE",
"detail": "TTS moderation is unavailable",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": true,
"timestamp": "2026-01-15T10:30:00Z"
}The non-resetting 25-second synthesis deadline elapsed before a complete protocol-final result was available. This response is retryable and is returned only when binary output has not started; otherwise the partial binary stream ends without appended JSON.
application/json
Example deadline_exceeded
{
"error": "TTS synthesis deadline exceeded",
"code": "TTS_DEADLINE_EXCEEDED",
"detail": "TTS synthesis deadline exceeded",
"job_id": "7f51f2c2-e7bc-41c8-a850-f848df2ddfc8",
"retryable": true,
"timestamp": "2026-01-15T10:30:00Z"
}Next steps
The direct HTTP response is an undelimited protocol capture, not recoverable raw PCM or WAV. Do not add a WAV header to it. For playable output, use the released Socket.IO SDK path and add a WAV header only after collecting the SDK’s final decoded PCM payload.