Webhooks
Use webhooks to receive real-time updates about delivery status and platform events.
Webhooks
Webhooks allow you to build reactive applications that respond to events on the Safaribid platform. Instead of polling our API for status changes, we push data to your server as soon as an event occurs.
How it Works
- Configure Endpoint: Provide a URL in your Dashboard where you want to receive events.
- Event Occurs: A delivery status changes or an order is paid.
- POST Request: Safaribid sends a
POSTrequest to your URL with a JSON payload. - Acknowledgment: Your server should return a
2xxstatus code to acknowledge receipt.
Event Types
| Event | Description |
|---|---|
delivery.created | A new delivery request has been initiated. |
delivery.rider_assigned | A rider has accepted the delivery request. |
delivery.rider_arriving | The rider is within 500m of the pickup location. |
delivery.picked_up | The rider has successfully picked up the package. |
delivery.in_transit | The rider is moving towards the destination. |
delivery.completed | The delivery has been successfully fulfilled. |
delivery.cancelled | The delivery has been cancelled by the merchant, rider, or system. |
Payload Example
{
"id": "evt_912837",
"type": "delivery.rider_assigned",
"created_at": "2026-05-14T11:20:00Z",
"data": {
"delivery_id": "del_8x2j9k1",
"status": "rider_assigned",
"rider": {
"name": "Sam K.",
"phone": "+254700999999",
"vehicle_plate": "KAB 123X"
}
}
}Security & Verification
To ensure that a webhook request actually came from Safaribid, we include a X-Safaribid-Signature header in every request.
Verifying Signatures
The signature is an HMAC-SHA256 hash of the request body, using your Webhook Secret as the key.
import crypto from 'crypto';
const signature = req.headers['x-safaribid-signature'];
const payload = JSON.stringify(req.body);
const secret = process.env.SAFARIBID_WEBHOOK_SECRET;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
if (signature === expectedSignature) {
// Request is authentic
}Retry Policy
If your server returns anything other than a 2xx status code, Safaribid will attempt to redeliver the webhook using exponential backoff:
- 1st Retry: 5 minutes
- 2nd Retry: 30 minutes
- 3rd Retry: 2 hours
- Final Retry: 24 hours
After the final retry, the event is marked as failed and can be replayed manually from the dashboard.
Best Practices
- Idempotency: Always check the
idof the event to ensure you don't process the same event twice. - Async Processing: Return a
200 OKimmediately and process the logic in a background worker to avoid timeouts. - Secure Endpoints: Use HTTPS for all your webhook URLs.