Errors
HTTP status codes, error codes and response shapes returned by the Kustomer API, what causes each, and which to retry.
The Kustomer API uses standard HTTP status codes. 2xx means success, 4xx means something about the request needs to change, and 5xx means something went wrong on Kustomer's side.
Error shape
Most errors return an errors array. Each entry has a machine-readable code, a human-readable message, and optional meta:
{
"errors": [
{
"code": "bad_request",
"message": "Invalid request body or parameters.",
"meta": {}
}
]
}Some endpoints return the JSON:API error object instead, with status, code, title, detail, source (pointing at the bad field) and meta. Write your error handling to accept both:
interface KustomerError {
code?: string
message?: string
title?: string
detail?: string
status?: string
source?: { pointer?: string; parameter?: string }
}
async function errorMessage(res: Response): Promise<string> {
const body = await res.json().catch(() => null)
const err: KustomerError | undefined = body?.errors?.[0]
if (!err) return `HTTP ${res.status}`
const where = err.source?.pointer ?? err.source?.parameter
return [err.code, err.message ?? err.detail ?? err.title, where && `at ${where}`].filter(Boolean).join(': ')
}Status codes
Retry policy
Diagram source
flowchart TD
R[Response] --> S{Status}
S -- "2xx" --> OK[Done]
S -- "429" --> W["Wait until x-ratelimit-reset<br/>+ jitter, then retry"]
S -- "5xx or network error" --> B["Exponential backoff<br/>0.5s, 1s, 2s, 4s… (max 5 tries)"]
S -- "409 'in progress'" --> B
S -- "other 4xx" --> F[Fail: log code and message, fix the request]Retrying a POST that timed out can create duplicates. Make creates safe to repeat by setting externalId and looking it up before you retry. See Making requests.
Bulk job errors
Bulk jobs report errors per item instead of failing the whole request. When you send _clientRef, each result has a status of created, updated or error, and failed items include an error reason. See Bulk operations.
Debugging checklist
- Log the status, the
errorsarray, the method and path. Never log theAuthorizationheader. - Reproduce the request with the Try it panel on the operation's reference page, or with
kusty api ... --dry-runto see exactly what would be sent. - Check the roles on the reference page against your key's roles from
GET /v1/auth/tokens/current. - For
400errors, compare your body with the request schema on the reference page. Custom attribute names must end in a valid suffix.