API documentation

One API for text to speech, speech to text, speech recognition and voice cloning. All endpoints live under a single base URL and share one bearer token.

https://api.nexacalling.com/api/v1

Every response carries an X-Request-ID header, and every error repeats it in the body. It identifies one row in your request log — quote it when contacting support.

Authentication

Create a key on the API keys page and send it as a bearer token.

Authorization: Bearer vp_live_xxxxxxxxxxxx

The secret is shown once, at creation. We store only a prefix and a hash, so it cannot be recovered — if you lose it, revoke the key and create another. Keys are scoped to one organization and can only ever see that organization’s voices, usage and logs.

Quick start

List your voices, then synthesize speech with one. Set VOICE_API_KEY in your environment first.

# 1. List the voices available to you
curl https://api.nexacalling.com/api/v1/voices -H "Authorization: Bearer $VOICE_API_KEY"

# 2. Synthesize speech with one of them
curl -X POST https://api.nexacalling.com/api/v1/text-to-speech \
  -H "Authorization: Bearer $VOICE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"My first request.","voice_id":"voice_xxxxx"}' \
  --output speech.mp3

Text to speech

POST/api/v1/text-to-speechBearer auth
Generates audio from text. Responds with raw audio/mpeg bytes rather than JSON, so write the body straight to a file.

Parameters · JSON body

NameTypeRequiredDescription
textstringRequiredThe text to speak. 1 to 5000 characters. Billed at one unit per character.
voice_idstringRequiredA voice ID from GET /voices. Must belong to your organization or the shared catalogue.

Example request

curl -X POST https://api.nexacalling.com/api/v1/text-to-speech \
  -H "Authorization: Bearer $VOICE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"Hello from the Voice API Platform.","voice_id":"voice_xxxxx"}' \
  --output speech.mp3

Example response

HTTP/1.1 200 OK
Content-Type: audio/mpeg
X-Request-ID: req_k3f9x2mQ7Lp0

<binary audio data>

Example error

{
  "error": {
    "code": "INVALID_REQUEST",
    "message": "text must not be empty.",
    "request_id": "req_k3f9x2mQ7Lp0"
  }
}

Errors

StatusCodeWhen
400INVALID_REQUESTMissing text, empty text, or over 5000 characters.
404NOT_FOUNDNo such voice in your organization.
401INVALID_API_KEYThe key is missing, malformed, unknown or revoked.
403ACCOUNT_SUSPENDEDThe account or organization is suspended.
429RATE_LIMITEDMore than 100 requests in a minute on this key.
502PROVIDER_ERRORSynthesis failed upstream. Safe to retry.

Speech to text

POST/api/v1/speech-to-textBearer auth
Transcribes an uploaded audio file. Synchronous — the transcript comes back on the same request, with no job to poll.

Parameters · multipart/form-data

NameTypeRequiredDescription
filefileRequiredmp3, wav, m4a, webm or ogg, up to 25 MB. Validated by content, not just extension.
languagestringOptionalISO language hint such as 'en'. Omit to detect automatically.

Example request

curl -X POST https://api.nexacalling.com/api/v1/speech-to-text \
  -H "Authorization: Bearer $VOICE_API_KEY" \
  -F "file=@recording.mp3" \
  -F "language=en"

Example response

{
  "text": "Hello, and welcome to the Voice API Platform.",
  "language": "en",
  "request_id": "req_k3f9x2mQ7Lp0"
}

Example error

{
  "error": {
    "code": "UNSUPPORTED_MEDIA_TYPE",
    "message": "That file does not appear to be audio. Accepted formats: mp3, wav, m4a, webm, ogg.",
    "request_id": "req_k3f9x2mQ7Lp0"
  }
}

Errors

StatusCodeWhen
400INVALID_REQUESTNo file was supplied, or the language code is invalid.
413PAYLOAD_TOO_LARGEThe file is larger than 25 MB.
415UNSUPPORTED_MEDIA_TYPEThe file is not mp3, wav, m4a, webm or ogg.
502PROVIDER_ERRORTranscription failed upstream. Safe to retry.
401INVALID_API_KEYThe key is missing, malformed, unknown or revoked.
403ACCOUNT_SUSPENDEDThe account or organization is suspended.
429RATE_LIMITEDMore than 100 requests in a minute on this key.

Speech recognition

POST/api/v1/asrBearer auth
The speech-recognition surface. It accepts the same inputs and returns the same shape as speech-to-text; usage is recorded under ASR so you can bill and report on recognition workloads separately.

Parameters · multipart/form-data

NameTypeRequiredDescription
filefileRequiredmp3, wav, m4a, webm or ogg, up to 25 MB. Validated by content, not just extension.
languagestringOptionalISO language hint such as 'en'. Omit to detect automatically.

Example request

curl -X POST https://api.nexacalling.com/api/v1/asr \
  -H "Authorization: Bearer $VOICE_API_KEY" \
  -F "file=@recording.mp3" \
  -F "language=en"

Example response

{
  "text": "Hello, and welcome to the Voice API Platform.",
  "language": "en",
  "request_id": "req_k3f9x2mQ7Lp0"
}

Example error

{
  "error": {
    "code": "PAYLOAD_TOO_LARGE",
    "message": "Audio must be 25 MB or smaller.",
    "request_id": "req_k3f9x2mQ7Lp0"
  }
}

Errors

StatusCodeWhen
400INVALID_REQUESTNo file was supplied, or the language code is invalid.
413PAYLOAD_TOO_LARGEThe file is larger than 25 MB.
415UNSUPPORTED_MEDIA_TYPEThe file is not mp3, wav, m4a, webm or ogg.
502PROVIDER_ERRORTranscription failed upstream. Safe to retry.
401INVALID_API_KEYThe key is missing, malformed, unknown or revoked.
403ACCOUNT_SUSPENDEDThe account or organization is suspended.
429RATE_LIMITEDMore than 100 requests in a minute on this key.

List voices

GET/api/v1/voicesBearer auth
Returns the shared catalogue plus any voices your organization has cloned. Another organization's voices are never included.

Example request

curl https://api.nexacalling.com/api/v1/voices \
  -H "Authorization: Bearer $VOICE_API_KEY"

Example response

{
  "voices": [
    {
      "id": "voice_c1x2n8fk4p",
      "name": "Narrator",
      "language": "en",
      "type": "PROVIDER",
      "created_at": "2026-08-30T12:00:00.000Z"
    }
  ]
}

Example error

{
  "error": {
    "code": "INVALID_API_KEY",
    "message": "Invalid or revoked API key.",
    "request_id": "req_k3f9x2mQ7Lp0"
  }
}

Errors

StatusCodeWhen
401INVALID_API_KEYThe key is missing, malformed, unknown or revoked.
403ACCOUNT_SUSPENDEDThe account or organization is suspended.
429RATE_LIMITEDMore than 100 requests in a minute on this key.

Clone a voice

POST/api/v1/voices/cloneBearer auth
Creates an instant voice clone from an audio sample. consent is required and must be true: by sending it you confirm you have permission and authorization to use the recording for voice cloning. The confirmation is stored with a timestamp against the voice.

Parameters · multipart/form-data

NameTypeRequiredDescription
namestringRequiredA name for the voice. Up to 64 characters.
consentstringRequiredMust be 'true'. Confirms you are authorized to clone this voice.
filefileRequiredA clear sample of a single speaker. mp3, wav, m4a, webm or ogg, up to 25 MB.
descriptionstringOptionalOptional note, up to 500 characters.

Example request

curl -X POST https://api.nexacalling.com/api/v1/voices/clone \
  -H "Authorization: Bearer $VOICE_API_KEY" \
  -F "name=Narrator" \
  -F "consent=true" \
  -F "file=@sample.mp3"

Example response

{
  "voice": {
    "id": "voice_9k2m4x7qab",
    "name": "Narrator",
    "language": null,
    "type": "CLONED",
    "created_at": "2026-08-30T12:00:00.000Z"
  }
}

Example error

{
  "error": {
    "code": "INVALID_REQUEST",
    "message": "consent: consent must be true. You must confirm you are authorized to clone this voice.",
    "request_id": "req_k3f9x2mQ7Lp0"
  }
}

Errors

StatusCodeWhen
400INVALID_REQUESTMissing name, missing consent, or the clone limit is reached.
403SERVICE_DISABLEDVoice cloning is disabled for this account.
413PAYLOAD_TOO_LARGEThe file is larger than 25 MB.
415UNSUPPORTED_MEDIA_TYPEThe file is not mp3, wav, m4a, webm or ogg.
502PROVIDER_ERRORTranscription failed upstream. Safe to retry.
401INVALID_API_KEYThe key is missing, malformed, unknown or revoked.
403ACCOUNT_SUSPENDEDThe account or organization is suspended.
429RATE_LIMITEDMore than 100 requests in a minute on this key.

Delete a voice

DELETE/api/v1/voices/{id}Bearer auth
Deletes one of your organization's cloned voices. Catalogue voices are shared and cannot be deleted.

Example request

curl -X DELETE https://api.nexacalling.com/api/v1/voices/voice_xxxxx \
  -H "Authorization: Bearer $VOICE_API_KEY"

Example response

{ "deleted": true, "id": "voice_9k2m4x7qab" }

Example error

{
  "error": {
    "code": "NOT_FOUND",
    "message": "Voice not found.",
    "request_id": "req_k3f9x2mQ7Lp0"
  }
}

Errors

StatusCodeWhen
404NOT_FOUNDNo such cloned voice in your organization.
401INVALID_API_KEYThe key is missing, malformed, unknown or revoked.
403ACCOUNT_SUSPENDEDThe account or organization is suspended.
429RATE_LIMITEDMore than 100 requests in a minute on this key.

Usage

Every request is recorded. Billable work also records units. Failed requests are logged but never billed.

EndpointUnit
/text-to-speechOne per character of text submitted
/speech-to-textOne per second of audio, rounded up
/asrOne per second of audio, rounded up
/voices/cloneOne per voice created

Where audio duration cannot be determined, one unit is recorded rather than zero. Your usage and request history are on the usage and requests pages.

Errors

Every error uses one envelope, whatever the status code.

{
  "error": {
    "code": "INVALID_REQUEST",
    "message": "text must not be empty.",
    "request_id": "req_k3f9x2mQ7Lp0"
  }
}
StatusCodeMeaning
400INVALID_REQUESTThe request failed validation.
401INVALID_API_KEYThe key is missing, malformed, unknown or revoked.
403ACCOUNT_SUSPENDEDThe account or organization is suspended.
403SERVICE_DISABLEDAn administrator has disabled this service.
404NOT_FOUNDThe resource does not exist, or is not yours.
413PAYLOAD_TOO_LARGEThe upload exceeds the size cap.
415UNSUPPORTED_MEDIA_TYPEThe file is not an accepted audio format.
429RATE_LIMITEDYou exceeded the per-key rate limit.
500INTERNAL_ERRORSomething failed on our side.
502PROVIDER_ERRORThe voice service failed. Safe to retry.

A resource owned by another organization returns 404, not 403 — a 403 would confirm the ID exists.