Skip to content
dhanu docs
Browse pages

API reference

Errors

Every Dhanu API error uses one envelope with a machine-readable code. Here is the full list and what to do about each.

Every failed request returns the same shape:

{
  "error": {
    "code": "invalid_api_key",
    "message": "Missing or unknown API key"
  }
}

Branch on code, not on message, messages are written for humans and may be reworded. The tables below are rendered from the same catalogue the server checks its responses against, so a code that can reach you is listed here.

Authentication and access

CodeStatusWhat happenedWhat to do
invalid_api_key401The bearer key is missing or unknown.Check the Authorization header.
api_key_revoked401The key was revoked.Create a new key.
api_key_expired401The key passed its expiry date.Create a new key.
api_key_ip_not_allowed403The caller's IP is outside the key's allowlist.Call from an allowed address, or widen the key's allowlist.
developer_access_revoked403The key's creator lost developer access in the workspace.Restore their access, or issue a new key.
api_key_project_scope403The key covers no active projects, or projectId is outside its scope.Fix the key's project scope.
api_key_operation_scope403The key's capability scope does not cover this operation.Widen the key's scope, or use a broader key.

Request problems

CodeStatusWhat happenedWhat to do
not_found404No such resource in the key's workspace.Check the id and that the key belongs to the same workspace.
channel_route_not_found404No staff member in the key's workspace has that trigger address.Copy the address from the staff member's Channels tab.
invalid_request_body422The body did not match the schema; error.issues names each field.Fix the listed fields.
invalid_cursor422The cursor was not one this endpoint issued.Pass nextCursor back verbatim.
invalid_idempotency_key400Idempotency-Key must be 1 to 255 characters.-
idempotency_key_reused409The same Idempotency-Key was sent with a different body.Use a new key for each distinct request.
idempotency_request_in_progress409The first request with this Idempotency-Key is still running.Retry shortly.
project_id_required422A multi-project key called without projectId.Pass projectId, or use a single-project key.
invalid_generation_prompt422The prompt was empty or longer than 2000 characters.-
invalid_image_aspect_ratio422The aspect ratio is outside the five supported values.-
invalid_workflow_values422The workflow values do not satisfy the workflow's fields; error.issues names each one.Fix the listed fields.
file_too_large413The file is larger than the direct-upload limit.Use the presigned multipart upload for large files.
unsupported_media_type415The file type is not accepted.-
unsupported_export_format422That file kind cannot be exported in the requested format.Pages export as html, sheets as csv or xlsx, decks as pdf or pptx.
export_not_rendered409The deck's PDF has not been rendered yet.POST /files/{fileId}/render, wait for the job, then export again.
video_not_ready409The video is still rendering, or failed.Poll the job or wait for the video.ready webhook.

Billing and limits

CodeStatusWhat happenedWhat to do
key_spend_limit_reached402The key reached its monthly spend cap.Raise the cap in Developers → API keys, or wait for next month.
storage_quota_exceeded507The workspace's storage quota is full.Free space or raise the quota in Settings → Storage.
insufficient_credits402The workspace credit balance is zero or below.Top up in Settings → Billing.
rate_limited429Too many requests for this workspace.Back off for Retry-After seconds.

Server

CodeStatusWhat happenedWhat to do
internal_error500Something failed on our side.Retry with backoff and quote the requestId to support.

Request IDs

Every response carries a request id, and it is included in the error envelope. You can supply your own with the x-request-id header, it must match [A-Za-z0-9._~-]{8,128}, otherwise Dhanu generates one, and it is echoed back on the response.

Include the request id when you contact support. It is the fastest way for us to find what happened. You can also look it up yourself: Developers → Requests in the console keeps every call made with your keys for 30 days, with its status, latency, cost and redacted request and response bodies.

Handling errors with the SDK

The SDK throws DhanuError, carrying the same code plus the request id:

import { DhanuError } from "dhanu";

try {
  await dhanu.images.generate({ prompt: "…" });
} catch (err) {
  if (err instanceof DhanuError) {
    console.error(err.code, err.status, err.message, err.requestId);
  }
}