Error Handling
Understand error responses and HTTP status codes from the Salesly API.
The Salesly API uses standard HTTP status codes and returns errors in a consistent JSON envelope.
Error Envelope
All errors follow the same structure:
{
"error": {
"type": "error_type",
"message": "Human-readable description of what went wrong.",
"details": {}
}
}| Field | Type | Description |
|---|---|---|
type | string | Machine-readable error code (use this for programmatic handling) |
message | string | Human-readable description |
details | object | Additional context (present on validation errors) |
HTTP Status Codes
| Code | Meaning | When |
|---|---|---|
200 | OK | Request succeeded |
201 | Created | Resource successfully created |
401 | Unauthorized | Missing or invalid API key |
404 | Not Found | Resource or endpoint doesn't exist |
409 | Conflict | Action conflicts with current state |
422 | Unprocessable Entity | Validation failed |
429 | Too Many Requests | Rate limit exceeded |
500 | Server Error | Something went wrong on our end |
Error Types
unauthorized
Missing or invalid x-api-key header.
{
"error": {
"type": "unauthorized",
"message": "Invalid API key."
}
}not_found
The requested resource does not exist.
{
"error": {
"type": "not_found",
"message": "Contact not found."
}
}validation_error
Request body failed validation. The details field contains per-field error messages.
{
"error": {
"type": "validation_error",
"message": "The given data was invalid.",
"details": {
"name": ["The name field is required."],
"type": ["The type field is required."]
}
}
}idempotency_conflict
The Idempotency-Key was already used with a different request.
{
"error": {
"type": "idempotency_conflict",
"message": "This Idempotency-Key has already been used with a different request."
}
}rate_limit_exceeded
Too many requests. Check the Retry-After response header.
{
"error": {
"type": "rate_limit_exceeded",
"message": "Too many requests. Please retry after the period indicated in the Retry-After header."
}
}conflict
The action conflicts with the current state of the resource.
{
"error": {
"type": "conflict",
"message": "Cannot delete category: it still has associated products."
}
}server_error
An unexpected error on our side. If this persists, contact support.
{
"error": {
"type": "server_error",
"message": "An unexpected error occurred. Please try again later."
}
}Handling Errors in Code
const response = await fetch(url, { headers });
if (!response.ok) {
const { error } = await response.json();
switch (error.type) {
case "validation_error":
console.error("Validation failed:", error.details);
break;
case "rate_limit_exceeded":
const retryAfter = response.headers.get("Retry-After");
console.log(`Rate limited. Retry in ${retryAfter}s`);
break;
case "not_found":
console.error("Resource not found:", error.message);
break;
default:
console.error("API error:", error.message);
}
}