Skip navigation
Contents

API

Error codes

All errors use the OpenAI format. Branch on error.code (stable), not on message (may change).
Example: 402 insufficient_balance
{
  "error": {
    "message": "Insufficient balance: this request may cost up to $0.002014 (max_tokens=1000), available balance is $0.0005. Top up your wallet or lower max_tokens.",
    "type": "insufficient_quota",
    "code": "insufficient_balance"
  }
}

The OpenAI SDK maps statuses to exceptions: 400 → BadRequestError, 401 → AuthenticationError, 402 → APIStatusError (check e.status_code), 403 → PermissionDeniedError, 404 → NotFoundError, 422 → UnprocessableEntityError, 429 → RateLimitError, 5xx → InternalServerError. Every error response includes the X-Request-Id header.

API /v1#

  • 400invalid_request
    Meaning
    Invalid body: missing model, empty messages, max_tokens not a positive integer, stream not a boolean; embeddings: empty/wrong-type input, more than 2,048 items, invalid dimensions…
    What to do
    Fix the request as described in the returned message.
  • 400invalid_json
    Meaning
    The body is not valid JSON.
    What to do
    Check Content-Type: application/json and the JSON syntax.
  • 400model_type_mismatch
    Meaning
    Wrong model type for the endpoint: an embedding model on /v1/chat/completions or a chat model on /v1/embeddings.
    What to do
    Use the endpoint named in the message, or switch to a model of the right type (Type column in the pricing table).
  • 400unsupported_parameter
    Meaning
    Unsupported parameter (currently: n other than 1).
    What to do
    Remove the parameter or send several requests.
  • 400 / 413 / 422upstream_invalid_request
    Meaning
    The model/provider rejected the request (e.g. context window exceeded, a parameter the model doesn’t accept). If the provider returns a safe code such as context_length_exceeded, that code is passed through unchanged.
    What to do
    Shorten the prompt, lower max_tokens or remove parameters the model doesn’t support. Not billed.
  • 401missing_api_key
    Meaning
    No Authorization: Bearer header.
    What to do
    Add the header; see authentication.
  • 401invalid_api_key
    Meaning
    The key is wrong or has been revoked.
    What to do
    Check the key or create a new one.
  • 402insufficient_balance
    Meaning
    The available balance doesn’t cover the request’s maximum hold.
    What to do
    Top up or lower max_tokens. Don’t retry automatically. See holds.
  • 402key_spend_limit_exceeded
    Meaning
    The key has reached its spend limit (including in-flight requests).
    What to do
    Raise the key’s limit in the dashboard or use another key.
  • 403model_not_allowed
    Meaning
    This key is not allowed to use that model.
    What to do
    Add the model to the key’s allowed models.
  • 403account_suspended
    Meaning
    The account is suspended.
    What to do
    Contact support.
  • 404model_not_found
    Meaning
    The model doesn’t exist or is disabled.
    What to do
    Get the correct name from GET /v1/models.
  • 404null
    Meaning
    Wrong endpoint path (code is null).
    What to do
    Check that the base URL includes /v1.
  • 413request_too_large
    Meaning
    The body is larger than 10 MB.
    What to do
    Reduce the size (images, conversation history).
  • 429rate_limit_exceeded
    Meaning
    The key’s rpm, the account’s rpm or the concurrency limit was exceeded.
    What to do
    Wait as indicated by the Retry-After header, then retry. See Rate limits.
  • 429upstream_rate_limited
    Meaning
    The upstream provider is temporarily rate limiting.
    What to do
    Retry after a few seconds (backoff). Not billed.
  • 502upstream_error
    Meaning
    The provider failed, timed out, was unreachable or returned an invalid response.
    What to do
    Retry with backoff. The hold is released; not billed.
  • 503price_not_configured
    Meaning
    The model temporarily has no selling price.
    What to do
    Retry later or use another model; contact support if it persists.
  • 200 (SSE)upstream_error
    Meaning
    An error during a stream, after data was sent: a data: {"error": …} event, then the stream closes.
    What to do
    The generated part is billed; resend the request if you need the complete answer.

Which errors are billed?

Only successful requests (or streams that already produced content) are billed. Any error before the model responds — including provider errors — releases the hold.

Dashboard (/api)#

Errors you may see when using the dashboard or calling the dashboard API directly.

  • 401unauthenticated
    Meaning
    The session has expired or the token is invalid.
    What to do
    Sign in again (the dashboard refreshes sessions automatically).
  • 401invalid_credentials
    Meaning
    Wrong email or password.
    What to do
    Try again.
  • 401invalid_refresh_token
    Meaning
    The refresh token has expired / been revoked.
    What to do
    Sign in again.
  • 403permission_denied
    Meaning
    Your role doesn’t have permission.
    What to do
    —
  • 403not_a_partnerpartner_disabled
    Meaning
    Partner pages: the account is not a partner, or the partner has been disabled.
    What to do
    Contact support.
  • 409email_taken
    Meaning
    The email is already registered.
    What to do
    Sign in or use a different email.
  • 409too_many_codes
    Meaning
    The partner already has the maximum number of active referral codes.
    What to do
    Deactivate some old codes.
  • 400amount_too_small
    Meaning
    The transfer amount is below the minimum (10,000 VND by default, after conversion if you enter USD).
    What to do
    Increase the amount.
  • 400amount_too_large
    Meaning
    The transfer amount exceeds the maximum for a single QR code (1,000,000,000 VND).
    What to do
    Split it into several top-ups.
  • 400too_many_keyskey_revoked
    Meaning
    You already have 50 active keys / you tried to edit a revoked key.
    What to do
    Revoke unused keys / create a new key.
  • 400invalid_cursor
    Meaning
    Invalid pagination cursor.
    What to do
    Start again from the first page.
  • 404 / 409not_foundconflict
    Meaning
    Not found / state conflict.
    What to do
    Reload the page.
  • 422invalid_request
    Meaning
    Invalid form data.
    What to do
    Fix it as described in the message.
  • 503deposits_not_configured
    Meaning
    The server has no receiving bank account configured.
    What to do
    Tell an administrator.
  • 503fx_rate_unavailable
    Meaning
    No USD/VND exchange rate is available yet, so a QR code can’t be created.
    What to do
    Retry later or tell an administrator.

Admin & webhooks#

Only seen in the admin console (admin/root) and the payment webhook.

  • 403root_only
    Meaning
    This action is reserved for root.
    What to do
    Sign in as root.
  • 409root_protected
    Meaning
    The root account can’t be changed via the API (it is managed in .env).
    What to do
    Edit ROOT_* in .env and restart.
  • 409loss_risk
    Meaning
    The new price / commission rate makes list × (1 − r) < cost. The body includes error.risks[].
    What to do
    Adjust it, or resend with ?confirm_loss=true.
  • 409model_not_ready
    Meaning
    Enabling a model that has no deployment with a passing test, or no price.
    What to do
    Add a deployment + price, then enable it again.
  • 409role_managed_by_partner
    Meaning
    Changing the role of a partner account.
    What to do
    Use the Partners page.
  • 409idempotency_key_reused
    Meaning
    A wallet adjustment reused an Idempotency-Key with a different body.
    What to do
    Use a new key.
  • 409use_assign
    Meaning
    Confirming a deposit with a transaction that already exists.
    What to do
    Assign the transaction on the Bank transactions page.
  • 409nothing_payabledeductions_exceed_payablepayout_would_be_negative
    Meaning
    Creating a payout when no commission is pending, or when clawbacks exceed it.
    What to do
    Pick another period / wait for more commission.
  • 422invalid_price_version
    Meaning
    The price version has an invalid effective_from.
    What to do
    Choose a different effective time.
  • 500credential_encryption_error
    Meaning
    The provider key can’t be decrypted (did SECRET_ENCRYPTION_KEY change?).
    What to do
    Restore the correct SECRET_ENCRYPTION_KEY or re-enter the provider key.
  • 501not_supported
    Meaning
    The provider doesn’t support listing remote models.
    What to do
    Enter the model name manually.
  • 401 / 400 / 503invalid_signatureinvalid_payloadwebhook_not_configured
    Meaning
    SePay webhook: bad HMAC signature, IP not in the allowlist, invalid body, or SEPAY_WEBHOOK_SECRET not set.
    What to do
    Check the SePay configuration (README).