Error shape
json
{
"error": "Invalid request",
"details": { /* validation issues, when applicable */ }
}Status codes
| Status | Meaning | Retry? |
|---|---|---|
| 400 | Validation failed — the details field lists the offending inputs | no — fix the request |
| 401 | Missing, malformed, or revoked API key | no |
| 404 | Resource not found in this workspace (template version, contact) | no |
| 422 | Recipient suppressed, or workspace quota exhausted | no |
| 429 | Rate limited | yes — after backoff |
| 5xx | Transient server error | yes — with backoff |
Rate limits
- 100 requests / minute per API key
- 1,000 requests / hour per IP address
Exceeding either returns 429 with standard draft-6 rate limit headers (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset) so clients can back off precisely.
The SDK backs off for you.
@ewyn/client retries 429 and 5xx automatically with exponential backoff, and idempotencyKey guarantees retries never double-send.
Timeouts
The SDK aborts requests after 30 seconds by default and surfaces them as an EwynApiError with status 408 and code TIMEOUT. Timeouts are not retried automatically — pair sends with an idempotency key and retry on your side if delivery is critical.