Ngamia uses a small set of response formats. Most account, billing, activity, notification, and operational endpoints return the standard Ngamia envelope. OpenAI-compatible gateway routes return OpenAI-shaped JSON or raw audio on success so existing clients can be reused.
Standard success and error responses
Most non-gateway endpoints return:
{
"status": "success",
"code": 200,
"data": {},
"request_id": "req_..."
}On failure, the standard envelope includes a stable error_code:
{
"status": "error",
"code": 400,
"error_code": "validation_error",
"message": "the request is invalid",
"request_id": "req_..."
}Use error_code for program logic, show an appropriate message to the developer or user, and retain request_id for support. The same request id is returned in the X-Request-Id response header.
Route-specific response formats
| Endpoint or flow | Successful response | Failed response |
|---|---|---|
POST /v1/chat/completions | OpenAI-compatible chat JSON or Server-Sent Events when stream: true | OpenAI-compatible JSON error |
POST /v1/embeddings | OpenAI-compatible complete embeddings JSON | OpenAI-compatible JSON error |
POST /v1/audio/transcriptions | Transcription JSON, optionally verbose JSON | OpenAI-compatible JSON error |
POST /v1/audio/speech | Raw audio/mpeg or audio/pcm bytes | JSON error, never audio |
POST /v1/voice/responses | JSON transcript, text, and optional base64 audio | OpenAI-compatible JSON error |
| OAuth callbacks | Browser redirect | Browser or provider-specific redirect behavior |
| Other documented endpoints | Standard Ngamia envelope | Standard Ngamia envelope |
Always check the HTTP status before decoding or saving a response. In particular, do not save a non-2xx speech response as if it were an audio file.
Common errors and fixes
| Status | Code | Meaning | How to fix |
|---|---|---|---|
| 400 | validation_error | The body or query parameters failed validation. | Read `message`; it names the field or value that needs correction. |
| 400 | invalid_request_error | A gateway request, audio format, model capability, or parameter is invalid. | Validate the request against the endpoint guide and refresh `GET /v1/models`. |
| 400 | otp_invalid | The submitted verification code is incorrect. | Ask the user to re-enter the code or request a new one. |
| 400 | otp_expired | The verification code is no longer valid. | Request a fresh code with `POST /v1/auth/otp/resend`. |
| 401 | unauthorized | The bearer token is missing, invalid, or expired. | Check the `Authorization` header; refresh a JWT or use the correct API key. |
| 401 | invalid_credentials | The login identifier or password is incorrect. | Show a generic login failure and do not reveal which value was wrong. |
| 402 | insufficient_quota | Gateway routes only — the account balance is too low for the requested action. | Top up credits, then retry the request deliberately. |
| 402 | insufficient_credits | Envelope endpoints only — the account balance is too low for the requested action. | Top up credits, then retry the request deliberately. |
| 403 | forbidden | The credential is valid but lacks permission. | Use the credential type and account with the required access. |
| 404 | not_found | The resource or enabled model does not exist. | Check the resource or refresh the live model catalog. |
| 409 | conflict | The request conflicts with an existing resource or value. | Use a different resource value as indicated by `message`. |
| 409 | idempotency_conflict | The same idempotency key is still being processed or was reused for a different request. | Wait for the original request or generate a new key for a new request body. |
| 413 | invalid_request_error | Gateway audio/voice only — the request or generated audio exceeds the route size cap. | Compress or split the audio, or shorten the speech input. |
| 429 | rate_limited | The API key or IP has exceeded its request limit. | Retry with exponential backoff and jitter. See [Rate limits](/rate-limits). |
| 500 | internal_error | The service failed while processing the request. | Retry once with backoff, keep the `request_id`, and report persistent failures. |
| 502 | server_error | An upstream provider request failed or returned unusable data. | Retry only when safe and report the `request_id` if the issue persists. |
A simple client strategy
- Check the HTTP status before selecting a decoder.
- For JSON responses, parse the route’s documented shape and branch on
error_codeor the OpenAI error type. - Do not retry validation, authentication, permission, not-found, or insufficient-credit errors unchanged.
- Retry rate limits and temporary server failures with exponential backoff and jitter. Use an idempotency key only where the endpoint’s guide supports safe replay.
- Log the endpoint, status, bounded error code, and
request_id; never log API keys, JWTs, passwords, OTPs, refresh tokens, prompts, transcriptions, or raw audio.
See Security & data handling for the public integration trust boundary.