MuviaDevelopers
Guides: Errors

Errors

Every non-2xx response of the public API has the same envelope:

{
  "error": {
    "code": "not_found",
    "message": "Project not found",
    "status": 404
  }
}
  • code — a stable, machine-readable identifier. Branch on it, never on the message text.
  • message — a human-readable English description. It may change.
  • status — the HTTP status, repeated for convenience.
  • details — optional structured context, such as the fields that failed validation.

Error codes

Status Code When Retry?
400 bad_request The request cannot be served as sent. No — fix the request.
401 unauthorized Missing, malformed, unknown, revoked or expired API key. Always the same response. No — see Authentication.
403 forbidden The key is valid but does not hold the endpoint's scope. No — see Scopes.
404 not_found No such resource in your company, including one that belongs to another company. No.
409 conflict The project has no database, so its datasets have no rows to read. No — until the project gets one.
422 validation_error A parameter failed validation; details names each one. No — fix the request.
422 query_failed A dataset's query could not run in ClickHouse. The query is never echoed back. No — the dataset needs fixing in Muvia.
429 rate_limit_exceeded A rate-limit window is exhausted. After Retry-After — see Rate limits.
500 internal_error An unexpected server error. Yes, with backoff.
503 service_unavailable The data store behind dataset rows did not answer, or refused the platform. Yes, with backoff.

New codes may appear within v1 (see Versioning). Handle a code you do not know by its HTTP status.

Validation errors

A 422 validation_error carries one entry per offending parameter, named by field:

{
  "error": {
    "code": "validation_error",
    "message": "The request is not valid",
    "status": 422,
    "details": [
      { "field": "size", "message": "Input should be less than or equal to 100" }
    ]
  }
}

404, not 403, for another company's data

Asking for a project, dataset or node that belongs to another company answers 404, the same as asking for one that does not exist. The API never confirms that data outside your company exists.

Backing off

For 500 and 503, retry with exponential backoff and jitter — for example 1, 2, 4, 8 seconds, then give up and alert. For 429, wait exactly as long as Retry-After says. Never retry a 400, 401, 403, 404 or 422 unchanged: the answer will be the same.