For AI agents: a documentation index is available at /llms.txt. A markdown version of this page is available at /guide/api/errors.md.

APIIntroduction

Errors

Status codes the Developer API returns, what causes each one, and which are worth retrying.

Errors use standard HTTP status codes and the same envelope as successful responses, so you can parse both with one code path.

json
{
  "success": false,
  "message": "Invalid signature"
}

#Status codes

200Success. Check the success field for soft failures.
201Created. Returned by the create endpoints, with the new record's UUID in data.
401Authentication failed — key, timestamp, nonce or signature.
403Authenticated, but the key's scopes do not cover this endpoint.
422Validation error — the decrypted payload is missing a field or has a bad value.
429Rate limit exceeded.
500Server error.

#401 Unauthorized

By far the most common error while building an integration, and it covers five distinct causes. The message field tells you which:

MessageCauseFix
Missing required headerOne of the four auth headers is absentSend X-API-KEY, X-TIMESTAMP, X-NONCE, X-SIGNATURE
Invalid API keyKey unknown, inactive, expired or revokedCheck the key in the admin portal
Timestamp outside windowClock drift beyond ±5 minutesSync the machine clock with NTP
Nonce already usedNonce replayed within 10 minutesGenerate fresh randomness per request
Invalid signatureCanonical string or body hash mismatchSee below

#Debugging an invalid signature

Nine times out of ten the body hash is the culprit. Work through these in order:

  1. Hash the bytes you send

    Serialise the JSON body once into a string, hash that string, and send that same string. Re-serialising between hashing and sending changes key order or whitespace and invalidates the signature.

  2. Check the separator

    The canonical string is joined with \n (LF). A \r\n from a Windows here-doc or a template literal will not match.

  3. Check the path

    Use the path only — /api/v1/partner/tasks/list — with a leading slash and no host, no query string, no trailing slash.

  4. Check the field order

    METHOD, PATH, TIMESTAMP, NONCE, SHA256(BODY). Method uppercase.

  5. Check the encoding

    The signature is hex, lowercase. Base64 will be rejected.

Tip

Call /api/v1/partner/validate while debugging. It exercises the full signing path with an empty payload, which removes the body hash from the equation — if validate succeeds but a real call fails, the problem is in your body serialisation.

#403 Forbidden

The key authenticated but its scopes do not cover the endpoint. Scopes are set when the key is issued; a key with * reaches everything. Ask your account manager to widen the scope, or use a key that already has it.

#422 Validation error

The signature was fine and the payload decrypted, but its contents failed validation — a missing required field, an unknown status value, or a UUID where an integer id was expected.

json
{
  "success": false,
  "message": "The project_id field is required."
}

Common causes:

  • Passing a user UUID to assigned_to, which expects a numeric id
  • A priority outside low, medium, high, urgent
  • A date that is not YYYY-MM-DD
  • Referencing a record in a project the key's workspace cannot see

#429 Too Many Requests

You have exceeded 120 requests in a minute or 5,000 in a day. The response carries headers telling you how long to wait:

less
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0
Retry-After: 60

See Rate limits for how to stay under them.

#500 Server error

Something failed on our side. These are logged with a correlation id.

#What to retry

Retry rules

Retry 429 after Retry-After, and 500 with exponential backoff and jitter — but generate a fresh timestamp, nonce and signature for every attempt. Replaying the original headers will be rejected as a reused nonce.

Never retry 401, 403 or 422 — they are deterministic and will fail identically until you change the request.

Retries are not idempotent

The create endpoints have no idempotency key. A retried tasks/create that actually succeeded the first time will create a second task. Confirm with a search before retrying a write that timed out.

#Audit trail

Every request, successful or not, is recorded with its status code, response time, calling IP and endpoint — the same trail the MCP server writes to. If a call behaves unexpectedly in production, that log is the place to start.