Skip to content

Error taxonomy

All API errors use a consistent JSON envelope. Clients should localize user-facing text from error.code, not from error.message (English, intended for logs).

Error envelope

{
  "success": false,
  "error": {
    "code": "JOB_NOT_FOUND",
    "message": "Job not found",
    "details": []
  }
}
Field Description
success Always false on errors
error.code Stable machine-readable code — use as your i18n key
error.message English diagnostic string — do not show directly to end users
error.details Optional array of extra validation messages (often empty)
error.correlationId Present on unhandled 500 errors for support correlation

HTTP status mapping

HTTP Typical error.code When it happens
400 VALIDATION_ERROR, INVALID_ASIN, CHECKOUT_INCOMPLETE, INVALID_CHECKOUT_METADATA Invalid body, query, or business rule
401 UNAUTHORIZED, INVALID_CREDENTIALS, WRONG_CURRENT_PASSWORD, CHECKOUT_SIGNATURE_INVALID Missing/invalid JWT, bad login, bad checkout signature
402 PAYMENT_REQUIRED, INSUFFICIENT_CREDITS Billing gate or not enough credits to start a job
403 FORBIDDEN Authenticated but not allowed
404 NOT_FOUND, JOB_NOT_FOUND, PROJECT_NOT_FOUND, SCHEDULE_NOT_FOUND, API_KEY_NOT_FOUND Resource missing for this organization
409 CONFLICT, EMAIL_ALREADY_EXISTS Duplicate or conflicting state
429 RATE_LIMIT_EXCEEDED Throttled endpoint (e.g. referral click recording)
500 INTERNAL_ERROR Unexpected server failure

When no domain-specific code is supplied, the API falls back to generic codes derived from HTTP status (VALIDATION_ERROR, NOT_FOUND, etc.).

Domain error codes (reference)

Canonical list lives in the API source: backends/apps/api/src/common/errors/error-codes.ts.

Generic

  • VALIDATION_ERROR — request failed validation
  • UNAUTHORIZED — auth required or token invalid
  • PAYMENT_REQUIRED — generic billing gate
  • FORBIDDEN — permission denied
  • NOT_FOUND — generic missing resource
  • CONFLICT — generic conflict
  • INTERNAL_ERROR — server error

Identity

  • INVALID_CREDENTIALS — wrong email/password
  • EMAIL_ALREADY_EXISTS — registration duplicate
  • WRONG_CURRENT_PASSWORD — password change rejected

Billing

  • INSUFFICIENT_CREDITS — cannot enqueue job
  • CHECKOUT_SIGNATURE_INVALID — Creem redirect verification failed
  • CHECKOUT_INCOMPLETE — payment not completed
  • INVALID_CHECKOUT_METADATA — checkout payload invalid

Crawl jobs

  • JOB_NOT_FOUND
  • INVALID_ASIN

Projects, schedules, API keys

  • PROJECT_NOT_FOUND
  • SCHEDULE_NOT_FOUND
  • API_KEY_NOT_FOUND

Rate limiting

  • RATE_LIMIT_EXCEEDED — returned with HTTP 429 on throttled routes (not all routes are rate-limited today)

Client handling pattern

  1. Parse JSON; if success === false, read error.code.
  2. Map error.code to a localized string in your app.
  3. For 500, log error.correlationId when present and show a generic retry message.
  4. For 402 / INSUFFICIENT_CREDITS, prompt top-up or reduce job size.

See Sample responses for concrete examples.

Tiếng Việt: Phân loại lỗi (VI)