Webhooks
Receive real-time notifications when events happen in your Atoship account. Webhooks allow you to build integrations that react to shipping events automatically.
Webhooks are HTTP callbacks that notify your application when events occur in your Atoship account. Instead of polling our API for updates, webhooks push data to your server in real-time.
Real-Time Updates
Get notified instantly when events happen
Reduced API Calls
No need to poll for updates
Automated Workflows
Trigger actions based on shipping events
1. Create a Webhook Endpoint
curl -X POST https://atoship.com/api/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Order Notifications",
"url": "https://example.com/webhooks/atoship",
"event_types": ["label.purchased", "tracking.delivered"],
"retry_attempts": 3,
"timeout": 30
}'2. Response
You'll receive a webhook secret in the response. Save this securely - you'll need it to verify webhook signatures.
{
"id": "whk_abc123def456",
"name": "Order Notifications",
"url": "https://example.com/webhooks/atoship",
"secret": "whsec_a1b2c3d4e5f6...",
"_warning": "Save this secret securely!"
}Subscribe to specific events or use all to receive all events.View detailed event payloads →
Label Events
label.createdA new shipping label has been createdlabel.purchasedA shipping label has been purchased and is ready for uselabel.voidedA shipping label has been voided/cancelledlabel.refundedA shipping label refund has been processedTracking Events
tracking.createdTracking has been initiated for a shipmenttracking.updatedTracking status has been updatedtracking.deliveredPackage has been deliveredtracking.exceptionA tracking exception has occurred (delay, return, etc.)Batch Events
batch.createdA new batch operation has been createdbatch.completedA batch operation has completed successfullybatch.failedA batch operation has failedScan Form Events
scan_form.createdA new SCAN form has been createdscan_form.updatedA SCAN form status has been updatedPayment Events
payment.createdA payment/charge has been initiatedpayment.completedA payment has been successfully completedpayment.failedA payment has failedReturn Events
return.createdA return label/RMA has been createdreturn.receivedA return has been received at the warehousereturn.completedA return has been fully processedInsurance Events
insurance.purchasedInsurance has been purchased for a shipmentinsurance.cancelledInsurance has been cancelledClaim Events
claim.createdAn insurance claim has been filedclaim.approvedAn insurance claim has been approvedclaim.rejectedAn insurance claim has been rejectedAll webhook payloads follow a consistent format with the event type, timestamp, and relevant data.
{
"id": "evt_abc123def456",
"object": "Event",
"type": "tracking.delivered",
"created_at": "2025-01-12T14:30:00.000Z",
"data": {
"object": {
"id": "lbl_xyz789",
"tracking_number": "9400111899223033005436",
"carrier": "USPS",
"status": "delivered",
"status_detail": "Package delivered to recipient",
"delivered_at": "2025-01-12T14:28:00.000Z",
"location": {
"city": "Los Angeles",
"state": "CA",
"zip": "90001"
}
},
"previous_attributes": {
"status": "out_for_delivery"
}
}
}Payload Fields
id- Unique event identifiertype- Event type (e.g., tracking.delivered)created_at- When the event occurreddata.object- The affected resourcedata.previous_attributes- Changed fields (if applicable)
HTTP Headers
X-Atoship-Signature- HMAC signatureX-Atoship-Event- Event typeX-Atoship-Delivery- Delivery attempt IDContent-Type- application/json
Security Best Practice
Always verify webhook signatures to ensure requests are from Atoship and haven't been tampered with. Never process webhooks without signature verification in production.
Each webhook includes an X-Atoship-Signature header containing an HMAC-SHA256 signature of the payload using your webhook secret.
import crypto from 'crypto';
function verifyWebhookSignature(
payload: string,
signature: string,
secret: string
): boolean {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// Usage in your webhook handler
app.post('/webhooks/atoship', (req, res) => {
const signature = req.headers['x-atoship-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhookSignature(payload, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process the webhook...
const event = req.body;
console.log('Received event:', event.type);
res.status(200).send('OK');
});If your endpoint returns a non-2xx status code or times out, we'll retry the webhook delivery.
Retry Schedule
- • Attempt 1: Immediate
- • Attempt 2: After 1 minute
- • Attempt 3: After 5 minutes
- • Attempt 4: After 30 minutes
- • Attempt 5: After 2 hours
Success Criteria
- • HTTP status 200-299
- • Response within timeout (default 30s)
- • Connection established
Configurable Options
retry_attempts- Number of retries (0-10, default 3)timeout- Request timeout in seconds (5-60, default 30)
Do
- Return 200 immediately, process asynchronously
- Always verify webhook signatures
- Handle duplicate events idempotently
- Use HTTPS endpoints only
- Log webhook payloads for debugging
Don't
- Don't do heavy processing before responding
- Don't ignore signature verification
- Don't assume events arrive in order
- Don't use HTTP (non-secure) endpoints
- Don't expose your webhook secret
/v1/webhooksList all webhook endpoints
/v1/webhooksCreate a new webhook endpoint
/v1/webhooks/:idRetrieve a webhook endpoint
/v1/webhooks/:idUpdate a webhook endpoint
/v1/webhooks/:idDelete a webhook endpoint
/v1/webhooks/:id/testSend a test webhook to verify your endpoint