Errors

Every error says what to do next.

Every NIUA error is { "error": { "code", "message", "doc_url" } }. Match on code, never on the message. doc_url links to that code's section below.

What each NIUA error code means and the one thing to do next. For developers and agents whose call came back with an error.

  1. 01 See the error a call without a key gets

    curl -X POST https://api.ohao.tech/api/v1/check
  2. 02 Make a key in the console, then send it

    curl -H "Authorization: Bearer $NIUA_API_KEY" https://api.ohao.tech/api/v1/contracts
  3. 03 Read every code as JSON

    curl https://ohao.tech/errors.json
API key
a secret (niua_live_...) that tells NIUA who is calling. Make one in the console, send it as a Bearer header.
Gate
NIUA's checker. It runs a contract on your file and says pass or fail, with a fix for each fail.

For agents: errors.json · OpenAPI · llms.txt

invalid_api_keyHTTP 401

The call had no API key, a wrong one or a revoked one, so NIUA could not tell who is calling.

next
Sign in at https://ohao.tech/niua/login, create a key at https://ohao.tech/niua/console/keys and send it as Authorization: Bearer niua_live_...; checks are free.
export NIUA_API_KEY=niua_live_...   # from https://ohao.tech/niua/console/keys
curl -H "Authorization: Bearer $NIUA_API_KEY" https://api.ohao.tech/api/v1/contracts   # 200 means the key works
curl -X POST "https://api.ohao.tech/api/v1/playground/samples/prop-lamp/check?contract=glb.prop@1&variant=fixed"   # no key needed

permission_deniedHTTP 403

The key is valid but does not cover this call: a read-scope key on a write route, an API key trying to manage keys, someone other than the owner simulating a checked file, or publishing to the public showcase, which is staff only.

next
Use a full-scope key for writes, simulate only files you checked yourself, and manage keys and spend limits in the console in a browser.

spend_limit_exceededHTTP 402

The call would pass the spend limit on this API key; the body carries limit_cents, spent_cents, period and price_cents.

next
Do not retry; ask the key's owner to raise or clear the limit in the console.

quota_exceededHTTP 402 or 429

You hit a per-user limit: 429 when calls come too fast, 402 when your 5 GB of upload storage is full.

next
On 429 wait the seconds in the Retry-After header and retry; on 402 delete old uploads to free space.

idempotency_key_in_useHTTP 409

A project with that name, or a board session with that id, already exists.

next
Pick a different project name or session id and send the call again.

conflictHTTP 409

What you are creating already exists, for example a saved contract with the same id@version.

next
Bump version, or pick a new id, and save again.

not_foundHTTP 404

Nothing your account can see exists at that path or id; receipts from the no-account playground are never stored, so they are not found here either.

next
Check the id; to check a receipt you hold, POST it to https://api.ohao.tech/api/v1/receipts/verify as {"receipt": ...}.

region_restrictedHTTP 451

The model's license does not allow use from your region (mesh-decompose excludes the EU, UK and South Korea), and nothing was charged.

next
Use another model, or call from a region the license allows.

service_unavailableHTTP 503

A part NIUA needs for this call is down or switched off on this server, such as hosted generation.

next
Retry after a short wait; if it keeps failing, the feature is off on this server.

upstream_unavailableHTTP 503

Reserved and not currently returned: it is for a provider NIUA depends on that does not answer.

next
Retry after a short wait.

generation_failedHTTP 200

A paid generation ran and failed; it comes back as HTTP 200 with status failed, and the wallet is refunded.

next
Read the error field of GET /api/v1/jobs/{id}, adjust the input and try again.

internalHTTP 500

Something broke inside NIUA, not in your request.

next
Retry once; if it repeats, send the x-request-id response header to Ohao through https://ohao.tech/contact.