What an error looks like
SendLib returns JSON errors. Depending on the deployment/version, you may see either:
- A simple error object
- A standard envelope that includes
data,meta, anderror
Be liberal in what you accept
When writing SDKs/integrations, handle both shapes so you don't break when the platform upgrades.
Simple error body
json
{
"error": {
"type": "invalid_request",
"message": "Human-readable message",
"code": "OPTIONAL_MACHINE_CODE",
"details": {"any": "shape"}
}
}Standard envelope (recommended)
json
{
"data": null,
"meta": {
"request_id": "abc123/xyz789-000001",
"timestamp": "2026-02-05T12:00:00.000Z"
},
"error": {
"type": "unauthorized",
"message": "Invalid credentials",
"code": "",
"details": null
}
}Request IDs
When present, meta.request_id is also returned as X-Request-ID.
Include request IDs in bug reports
If you're contacting support or debugging with logs, include X-Request-ID and the approximate timestamp.
Common status codes
| Status | Meaning | What to do |
|---|---|---|
400 | Invalid request (malformed JSON, validation) | Fix the payload; log the error details. |
401 | Missing/invalid credentials | Check Authorization: Bearer ... and key validity. |
403 | Authenticated but not allowed | Add the missing scope or use a different key. |
404 | Not found | Double-check the resource id and base path. |
409 | Conflict | Usually "already exists" or state conflict; read message. |
415 | Unsupported media type | Set Content-Type: application/json. |
422 | Unprocessable entity | Treat as semantic validation (often per-recipient rejects). |
429 | Rate limited | Backoff + retry later; see rate limits. |
500 | Internal server error | Retry with backoff; include request id if persistent. |
502 | Upstream failure | Retry with idempotency if the request creates something. |
Handling errors in code
- Treat
4xxas "fix the request or permissions". - Treat
5xx/502as transient unless proven otherwise. - For create-style endpoints, combine retries with Idempotency.
ts
const res = await fetch("https://api.sendlib.com/v1/transmissions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SENDLIB_API_KEY}`,
"Idempotency-Key": "0d6c2a6f-3f3c-4d4a-9c1a-2f7f9c1a1f0b",
"Content-Type": "application/json",
},
body: JSON.stringify({ /* ... */ }),
});
if (!res.ok) {
const text = await res.text();
throw new Error(`SendLib error ${res.status}: ${text}`);
}Next
- Rate limiting: Rate Limits
- Retry safety: Idempotency