Error codes
HTTP status codes
| Code | Meaning | Recommended action |
|---|---|---|
200 | Request accepted (write processing is asynchronous) | Continue |
400 | Invalid request (malformed JSON, wrong parameter) | Fix the request |
401 | Missing or invalid API key (spm-api-key) | Check the key |
403 | Access denied for this resource | Check the key's permissions |
404 | Resource not found | Check the identifier |
409 | Conflict (e.g. uniqueness constraint) | Adjust the data |
422 | Payload validation failed | Fix the reported fields |
429 | Too many requests (rate limit) | Retry after backoff |
500 502 503 504 | Server error or unavailability | Retry with backoff |
Idempotent deletes
The delete* and bulkDelete* operations are idempotent: deleting an unknown identifier succeeds silently (no 404).
Bulk writes: partial rejections
A bulk write (POST / PUT / bulk-delete) returns 200 even if some items are rejected. Invalid items don't interrupt the batch:
{
"statusCode": 200,
"sent_count": 18,
"rejected_count": 2,
"rejected_items": [
{ "index": 4, "errors": ["email must be a valid email"] }
]
}Always check rejected_count / rejected_items — a 200 confirms acceptance, not that all items were accepted.
Error handling with the SDK
The JavaScript SDK never throws on an HTTP error: it returns a uniform envelope whose error field carries a normalized code.
const res = await SpmOrders.bulkSave(client, orders);
if (!res.ok) {
console.log(res.error.code); // 'HTTP_429', 'HTTP_503', 'ETIMEDOUT', …
console.log(res.error.retryable); // true if the error is transient
console.log(res.error.attempts); // number of attempts made
}| Type | error.code | retryable |
|---|---|---|
| HTTP 4xx (except 408/429) | HTTP_4xx | false |
| HTTP 408 / 429 | HTTP_408 / HTTP_429 | true |
| HTTP 5xx | HTTP_5xx | true |
| Network | ETIMEDOUT, ECONNRESET, ECONNREFUSED, ENOTFOUND, … | true |
The SDK automatically retries retryable errors (408 / 429 / 5xx / network) with an exponential backoff — see Resilience. SpmHelpers.formatError(res) produces an object that's safe to log.
Without the SDK
For direct calls (fetch / cURL / PHP), test the HTTP status code and the presence of rejected_items in the body. Implement your own backoff on 429 and 5xx.