Skip to main content

Webhook Payload Format

Complete reference for webhook payload structure.

Payload Structure

All webhook payloads follow this structure:

{
"id": "event-uuid",
"event": "order.delivered",
"payload": {
// Event-specific data
},
"at": "2026-08-19T10:30:00.000Z"
}

Top-Level Fields

FieldTypeDescription
idstringUnique event ID (use for idempotency)
eventstringEvent type (e.g., order.delivered)
payloadobjectEvent-specific data
atstringEvent timestamp (ISO 8601)

Common Payload Fields

Order Fields

Most order events include these fields:

{
"id": "order-uuid",
"status": "delivered",
"externalRef": "YANGO-ORDER-123",
"courimaxOrderId": "order-uuid",
"pickupAddress": "Rothschild Blvd 1, Tel Aviv",
"pickupLat": 32.0639,
"pickupLng": 34.7742,
"dropoffAddress": "Dizengoff Center, Tel Aviv",
"dropoffLat": 32.0753,
"dropoffLng": 34.7749,
"recipientName": "Jane Doe",
"recipientPhone": "+972501234567",
"packageSize": "small",
"trackingToken": "tracking-token-abc",
"createdAt": "2026-08-19T10:00:00.000Z",
"updatedAt": "2026-08-19T10:30:00.000Z"
}
FieldTypeDescription
idstringCourimax order ID
statusstringCurrent order status
externalRefstringYour order reference
courimaxOrderIdstringCourimax internal order ID
pickupAddressstringPickup address
pickupLatnumberPickup latitude
pickupLngnumberPickup longitude
dropoffAddressstringDropoff address
dropoffLatnumberDropoff latitude
dropoffLngnumberDropoff longitude
recipientNamestringRecipient name
recipientPhonestringRecipient phone
packageSizestringPackage size
trackingTokenstringPublic tracking token
createdAtstringOrder creation timestamp
updatedAtstringLast update timestamp

Driver Fields

Events involving driver assignment include:

{
"driver": {
"id": "driver-uuid",
"name": "David Cohen",
"phone": "+972501234567"
}
}
FieldTypeDescription
driver.idstringDriver ID
driver.namestringDriver name
driver.phonestringDriver phone

Location Fields

Events with driver location include:

{
"driverLocation": {
"latitude": 32.07,
"longitude": 34.78,
"accuracy": 10,
"timestamp": "2026-08-19T10:20:00.000Z"
}
}
FieldTypeDescription
latitudenumberGPS latitude
longitudenumberGPS longitude
accuracynumberGPS accuracy in meters
timestampstringLocation timestamp

Proof of Delivery

Delivered events include proof of delivery:

{
"proofOfDelivery": {
"recipientNameConfirmed": "Jane Doe",
"gpsLat": 32.0753,
"gpsLng": 34.7749,
"photoUrl": "https://storage.courimax.com/pod/photo.jpg",
"signatureUrl": "https://storage.courimax.com/pod/signature.jpg",
"deliveredAt": "2026-08-19T10:30:00.000Z"
}
}
FieldTypeDescription
recipientNameConfirmedstringConfirmed recipient name
gpsLatnumberDelivery GPS latitude
gpsLngnumberDelivery GPS longitude
photoUrlstringDelivery photo URL (optional)
signatureUrlstringSignature image URL (optional)
deliveredAtstringDelivery timestamp

Event-Specific Payloads

order.created

{
"id": "order-uuid",
"status": "pending",
"externalRef": "YANGO-ORDER-123",
"pickupAddress": "Rothschild Blvd 1, Tel Aviv",
"dropoffAddress": "Dizengoff Center, Tel Aviv",
"recipientName": "Jane Doe",
"recipientPhone": "+972501234567",
"packageSize": "small",
"createdAt": "2026-08-19T10:00:00.000Z"
}

order.assigned

{
"id": "order-uuid",
"status": "assigned",
"externalRef": "YANGO-ORDER-123",
"driver": {
"id": "driver-uuid",
"name": "David Cohen",
"phone": "+972501234567"
},
"assignedAt": "2026-08-19T10:05:00.000Z"
}

order.picked_up

{
"id": "order-uuid",
"status": "picked_up",
"externalRef": "YANGO-ORDER-123",
"driver": {
"id": "driver-uuid",
"name": "David Cohen"
},
"pickedUpAt": "2026-08-19T10:15:00.000Z"
}

order.in_transit

{
"id": "order-uuid",
"status": "in_transit",
"externalRef": "YANGO-ORDER-123",
"driver": {
"id": "driver-uuid",
"name": "David Cohen"
},
"driverLocation": {
"latitude": 32.07,
"longitude": 34.78
},
"inTransitAt": "2026-08-19T10:20:00.000Z"
}

order.delivered

{
"id": "order-uuid",
"status": "delivered",
"externalRef": "YANGO-ORDER-123",
"driver": {
"id": "driver-uuid",
"name": "David Cohen"
},
"deliveredAt": "2026-08-19T10:30:00.000Z",
"proofOfDelivery": {
"recipientNameConfirmed": "Jane Doe",
"gpsLat": 32.0753,
"gpsLng": 34.7749,
"photoUrl": "https://storage.courimax.com/pod/photo.jpg",
"signatureUrl": "https://storage.courimax.com/pod/signature.jpg"
}
}

order.failed

{
"id": "order-uuid",
"status": "failed",
"externalRef": "YANGO-ORDER-123",
"driver": {
"id": "driver-uuid",
"name": "David Cohen"
},
"failedAt": "2026-08-19T10:30:00.000Z",
"failureReason": "Customer not available",
"notes": "Attempted delivery 3 times"
}

order.cancelled

{
"id": "order-uuid",
"status": "cancelled",
"externalRef": "YANGO-ORDER-123",
"cancelledAt": "2026-08-19T10:10:00.000Z",
"reason": "Customer requested cancellation"
}

TypeScript Types

interface WebhookEvent {
id: string;
event: WebhookEventType;
payload: OrderPayload;
at: string;
}

type WebhookEventType =
| 'order.created'
| 'order.assigned'
| 'order.picked_up'
| 'order.in_transit'
| 'order.delivered'
| 'order.failed'
| 'order.cancelled';

interface OrderPayload {
id: string;
status: OrderStatus;
externalRef: string;
courimaxOrderId?: string;
pickupAddress?: string;
pickupLat?: number;
pickupLng?: number;
dropoffAddress?: string;
dropoffLat?: number;
dropoffLng?: number;
recipientName?: string;
recipientPhone?: string;
packageSize?: string;
trackingToken?: string;
driver?: Driver;
driverLocation?: Location;
proofOfDelivery?: ProofOfDelivery;
createdAt?: string;
updatedAt?: string;
assignedAt?: string;
pickedUpAt?: string;
inTransitAt?: string;
deliveredAt?: string;
failedAt?: string;
cancelledAt?: string;
failureReason?: string;
reason?: string;
notes?: string;
}

interface Driver {
id: string;
name: string;
phone: string;
}

interface Location {
latitude: number;
longitude: number;
accuracy?: number;
timestamp?: string;
}

interface ProofOfDelivery {
recipientNameConfirmed: string;
gpsLat: number;
gpsLng: number;
photoUrl?: string;
signatureUrl?: string;
deliveredAt: string;
}

type OrderStatus =
| 'pending'
| 'dispatching'
| 'assigned'
| 'picked_up'
| 'in_transit'
| 'delivered'
| 'failed'
| 'cancelled';

Validation

Validate webhook payloads using TypeScript or a validation library:

const Joi = require('joi');

const webhookSchema = Joi.object({
id: Joi.string().uuid().required(),
event: Joi.string().valid(
'order.created',
'order.assigned',
'order.picked_up',
'order.in_transit',
'order.delivered',
'order.failed',
'order.cancelled'
).required(),
payload: Joi.object().required(),
at: Joi.date().iso().required()
});

app.post('/webhooks/courimax', (req, res) => {
const { error } = webhookSchema.validate(req.body);

if (error) {
logger.error('Invalid webhook payload', error);
return res.status(400).send('Invalid payload');
}

handleWebhook(req.body);
res.status(200).send('OK');
});

Next Steps