Errors and Retries
Errors and Retries
Error handling, retry policy, and idempotency guidance for stable integrations.
Audience: Engineers implementing robust clients for Selwise private and public APIs.
Critical: Treat 4xx vs 5xx responses differently: most 4xx are client-actionable, while 5xx and some 429 are retry candidates.
Who This Page Is For
Use this page when implementing retry/backoff behavior, duplicate protection, and error observability for Selwise API calls.
Quick Start (2-5 Minutes)
Classify response code
Separate non-retryable client errors from retryable infrastructure errors.
401/403/404/422 usually fix request or permissions; 429/5xx may retry.Honor rate-limit headers
Use Retry-After and X-RateLimit headers for throttled endpoints.
Backoff with jitter; avoid immediate replay loops.Implement idempotency for orders/events
Prevent duplicate purchase/order submissions in retries.
Deduplicate by orderId and client request IDs where possible.Log structured error context
Capture endpoint, payload hash, status, and correlation metadata.
Support fast incident triage and replay decisions.Use bounded retry policy
Set max attempts and escalation threshold.
Example: 3 attempts with exponential backoff and jitter.Handle email webhook idempotency
Provider events may be delivered more than once.
Use providerEventId semantics and treat duplicates as non-fatal.Required Fields / Minimum Payload
| Field | Required | Type | Used by events | Description |
|---|---|---|---|---|
statusCode | Required | HTTP code | All API responses | Primary signal for retry/abort decision. |
error/message | Conditional | response body fields | Error responses | Human-readable failure reason. |
Retry-After | Conditional | header | 429 responses | Backoff hint in seconds. |
orderId | Conditional | string | Order ingestion | Key dedup field for idempotent order submissions. |
providerEventId | Conditional | string | Email provider webhook events | Used for deduplication in connector-based event ingestion. |
Common status handling
200/201 Success
400 Bad request (payload or query issue)
401 Unauthorized (token missing/invalid)
403 Forbidden (permission/site/origin/subscription policy)
404 Not found
409 Conflict (for example duplicate order)
422 Validation error
429 Too many requests (retry with backoff)
500 Internal server error (retry with bounded policy)
# Email delivery specifics
SMTP auth/TLS failure Mark sender unhealthy and escalate operator action
Permanent recipient reject Suppress recipient and stop replay
Provider duplicate event Treat as idempotent duplicate, do not retry as errorEvent or Endpoint Decision Matrix
| Scenario | Use This | Why |
|---|---|---|
| Receive 400/422 | Fix payload and do not blind retry | Client-side validation issue likely. |
| Receive 401/403 | Refresh auth or permissions/origin setup | Security boundary failure, not transient transport issue. |
| Receive 409 duplicate order | Stop replay and enforce idempotent order flow | Conflict indicates duplicate submission. |
| Receive SMTP permanent error (for example 550/5.1.1) | Mark as permanent fail + suppress recipient | Retrying can damage sender reputation and wastes capacity. |
| Receive 429 | Retry with Retry-After + exponential backoff | Server explicitly requests paced retry. |
| Receive 5xx | Retry with bounded attempts and alert on persistent failure | Potential transient server-side issue. |
Common Errors and Fixes
Repeated 429 loops
Cause: Client retries immediately without respecting Retry-After.
Fix: Apply server-provided wait and exponential backoff with jitter.
Duplicate orders in downstream systems
Cause: Retry logic resubmits same order without idempotency keying.
Fix: Deduplicate by orderId and prevent uncontrolled replay.
Persistent 403 on public endpoints
Cause: Origin or subscription validation failure.
Fix: Verify domain/origin and subscription conditions before retrying.
Silent data loss after errors
Cause: No structured error logging and no dead-letter/retry queue.
Fix: Capture structured logs and route failed payloads to retry workflow.
Provider webhook appears to double count events
Cause: Provider retries callback and integration treats duplicate as new.
Fix: Respect providerEventId idempotency and monitor duplicate counters separately from rejected events.
Production Checklist
- Retry policy differentiates 4xx from 429/5xx responses.Required
- Retry-After and rate-limit headers are honored.Required
- SMTP permanent failures trigger suppression and no blind replay.Required
- Order/event submissions include idempotency safeguards.Required
- Error telemetry includes endpoint, status, and request context.Required
- Persistent retry failures trigger operational alerts.Required