KanalKanal API
Getting started

Errors

Error format, status codes, and how to handle them.

Errors are JSON with the relevant HTTP status code. There are two response shapes depending on where the error originates.

1. Auth, store & rate-limit errors

Problems detected before validation (missing/invalid key, store not authorized, store paused, rate limit) return a single error string:

401 / 403 / 404
{ "error": "API key does not authorize this store" }

These are not retryable (except 429) — fix the credentials, store_id or request, then resend.

2. Validation errors (422)

Invalid payloads return Laravel's validation shape: a summary message plus a per-field errors map (dot notation for nested fields):

422 Unprocessable Entity
{
  "message": "The customer.phone field is required.",
  "errors": {
    "customer.phone": ["The customer.phone field is required."]
  }
}

Not retryable — fix the payload before sending again.

3. Rate limit (429)

429 Too Many Requests
{ "message": "Too Many Attempts." }

Returned with a Retry-After header (seconds) and X-RateLimit-* headers. Retryable — wait for Retry-After, then resend. See Rate limits.

Status code reference

StatusMeaningShapeRetry?
200Updated an existing recordresource
201Created a new recordresource
204Deleted (no body)
400Missing store_id route parameter{ error }No
401Missing or invalid API key{ error }No
403Key not authorized for this store{ error }No
404Store unknown/paused, or record not found{ error }No
422Validation failed{ message, errors }No
429Rate limit exceeded{ message }Yes — honor Retry-After
5xxTransient server errorYes — exponential backoff
2xx        → success, done
422        → fix payload, do NOT retry (read `errors` for the failing fields)
401 / 403  → fix credentials / store_id, do NOT retry
404        → check store_id (or that the record exists for PATCH/DELETE)
429        → wait Retry-After, then retry
5xx / net  → exponential backoff + jitter, retry safely

Retries are always safe because writes are idempotent on (store_id, external_id) — see Idempotency.

On this page