Headers Sent by Carrier
All custom headers sent by Carrier use theX-Carrier- prefix.
X-Carrier-Receive-Count
The number of times this message has been received from SQS.This corresponds to the SQS
ApproximateReceiveCount attribute and indicates how many times the particular message has been delivered.Use cases:- Implement exponential backoff strategies
- Track retry attempts
- Trigger alerts for problematic messages
- Apply different processing logic based on retry count
1, 3, 5X-Carrier-First-Receive-Time
The timestamp (in seconds since Unix epoch) when this message was first received from SQS.This corresponds to the SQS
ApproximateFirstReceiveTimestamp attribute.Use cases:- Calculate message age
- Implement time-based backoff strategies
- Track message latency
- Expire stale messages
1710004800, 1710091200Content-Type
The MIME type of the message body.This header is always sent with webhook requests. The value can be:
- Dynamic: Set per-message using the
Body.ContentTypeSQS message attribute - Configured: Set globally via
CARRIER_WEBHOOK_DEFAULT_CONTENT_TYPEenvironment variable - Default:
application/jsonif neither is specified
application/json, application/xml, text/plainHeaders Received by Carrier
Carrier processes specific headers from webhook responses to implement dynamic behavior.Retry-After
Used with HTTP 429 (Too Many Requests) responses to specify when to retry the message.Format: Number of seconds to wait before retryWhen your webhook returns a 429 status with this header, Carrier will:
- Parse the
Retry-Aftervalue (in seconds) - Calculate a new SQS visibility timeout
- Update the message visibility to prevent redelivery until after the specified time
30, 60, 300Example Webhook Requests
First Delivery
When a message is delivered for the first time:Retry with Custom Content Type
A message with a custom content type on its third attempt:Implementing Dynamic Backoff
Here’s how to implement a distributed exponential backoff strategy in your webhook handler:Tracking Message Age
Calculate how long a message has been in the system:Setting Dynamic Content Types
To send messages with custom content types, use SQS message attributes:The SQS message attribute name must be exactly
Body.ContentType for Carrier to recognize it and set the Content-Type header dynamically.Response Status Codes
Carrier expects specific HTTP status codes from webhook endpoints:| Status Code | Behavior | Description |
|---|---|---|
200 OK | Message deleted from SQS | Successful processing |
429 Too Many Requests | Visibility timeout updated | Retry with backoff (requires Retry-After header) |
| Other (4xx, 5xx) | Message returns to queue | Failed processing, message will retry based on SQS configuration |
Best Practices
- Always handle X-Carrier-Receive-Count: Use this to implement intelligent retry strategies and prevent infinite loops
- Return 429 with Retry-After for rate limiting: This ensures proper backoff without losing messages
-
Monitor message age: Use
X-Carrier-First-Receive-Timeto detect and handle stale messages - Set appropriate Content-Type: Use SQS message attributes to specify content types for non-JSON payloads
- Implement exponential backoff: Use receive count to calculate increasing delays for retry attempts
- Return 200 only on success: Only return HTTP 200 when the message has been successfully processed and can be safely deleted
