Projekt Developers
Status codes · envelope

Errors.

Errors are always JSON. The HTTP status is the source of truth — handle it first, parse the body for human-readable detail second.

Envelope#

Every non-2xx response has at least this shape:

{
  "error": "Human-readable description of what went wrong."
}

Validation errors add a structured errors map keyed by field name:

{
  "error": "Validation failed",
  "errors": {
    "title":       ["The title field is required"],
    "priority":    ["The priority must be one of: low, medium, high, urgent"]
  }
}

Status codes you should handle#

StatusMeaningWhat to do
200 Success. Body is the resource (or { data, meta } for paginated lists). Carry on.
201 Resource created. Returned for POST on collections (issues, projects, comments, …). Body has the new resource, including its id.
204 Success, no body. Common on DELETE. Treat as OK.
304 Not Modified. The resource hasn't changed since the If-None-Match ETag you sent. Use your cached copy.
400 Bad request. Malformed JSON, missing required header, unparseable parameter. Fix the request. Do not retry the same payload.
401 Unauthorized. Missing, expired, or revoked token. Re-authenticate. Don't retry blindly — repeated 401s look like brute-force.
403 Forbidden. You're authenticated but not allowed: wrong role, PAT used on a cross-org endpoint, X-Org-Id doesn't match the key's bound org. Check role and org binding. Read the message — it's specific.
404 Not found. Either the resource doesn't exist or your org can't see it. Verify the ID and the X-Org-Id header.
405 Method not allowed. The path exists but not for that verb. Check the OpenAPI spec for the allowed methods.
409 Conflict. Duplicate slug/key, concurrent edit, optimistic-lock failure. Re-read the resource and reconcile.
422 Validation failed. Body shape passed the schema but values are wrong. Inspect errors, fix the offending fields.
429 Too Many Requests. You blew the rate limit. Honor X-RateLimit-Reset / Retry-After. See Rate limits.
500 Internal server error. Something blew up on our side. Retry with backoff. If it persists, report it.
502 / 503 Upstream or gateway error. Transient. Retry with exponential backoff (cap at ~30s).

Retry policy#

!
Honor X-RateLimit-Reset

When the server returns 429, the X-RateLimit-Reset header tells you how many seconds until your window refills. Sleeping that long beats hammering the endpoint with linear retries.

Common errors and what they mean#

401 Unauthorized · "Authentication required"

You sent no token, or the token is invalid. Confirm the Authorization header is present and starts with Bearer pjk_live_.

403 Forbidden · "API key bound to a different organization"

You sent X-Org-Id pointing at an org the key is not bound to. Either drop the header (the key already knows its org) or send the right UUID.

403 Forbidden · "Not available for API key auth — use a user session"

The endpoint is intentionally off-limits to PATs (creating orgs, joining via invite code, cross-org search). Sign in to the web app for those operations.

422 Validation failed

Look at errors. Each key is the field name that broke; the value is an array of human-readable messages. Fix them, retry.

429 Too Many Requests · "Rate limit exceeded. Try again later."

You're over your per-token budget. See Rate limits for the exact numbers and headers.