Webhooks

Instead of asking about each booking, you can have EazyGo post an event to your server whenever one of your agency's bookings changes. That includes bookings made on the agent panel.

Setting up

  1. On the agent panel, open API Access and enter your webhook URL. It must be a public https:// address.
  2. Copy the signing secret shown after saving. It is shown only once; New secret replaces it.
  3. Click Send test event to receive a ping. Recent deliveries and their results are listed on the same page.

Events

event When
booking.confirmed The booking is confirmed (for API bookings, right after you book)
trip.driver_assigned A driver is assigned, or replaced by another driver
trip.started The driver starts the trip at the pickup
trip.completed The trip has ended
booking.cancelled The booking is cancelled, by you or by EazyGo
ping Test event from the API Access page

The request

POST to your URL with a JSON body:

{
  "id": "6f1c3a6e-2b1d-4f7e-9a51-3c1f0e2b7d40",
  "event": "trip.driver_assigned",
  "created_at": "2026-11-19T21:04:10+05:30",
  "data": {
    "reference": "EZ7Q2K9P4XMA",
    "status": "confirmed",
    "trip_status": "assigned_driver",
    "driver": { "name": "Ramesh Patil", "mobile": "9800000002" },
    "vehicle": { "model": "Maruti Dzire", "registration_number": "MH12AB1234", "color": "White" },
    "...": "the rest of the booking, as GET /bookings/{reference} returns it"
  }
}

Headers:

Header Value
X-EazyGo-Event The event name
X-EazyGo-Delivery The event's unique id. The same id on a retry
X-EazyGo-Signature t=<unix time>,v1=<signature>
User-Agent EazyGo-Webhooks/1.0

Checking the signature

The signature is the hex HMAC-SHA256 of <t>.<raw request body>, keyed with your signing secret. Check it before trusting the event, and ignore events whose t is more than 5 minutes old.

PHP:

$payload = file_get_contents('php://input');
parse_str(str_replace(',', '&', $_SERVER['HTTP_X_EAZYGO_SIGNATURE'] ?? ''), $sig);

$expected = hash_hmac('sha256', ($sig['t'] ?? '').'.'.$payload, getenv('EAZYGO_WEBHOOK_SECRET'));

if (! hash_equals($expected, $sig['v1'] ?? '') || abs(time() - (int) ($sig['t'] ?? 0)) > 300) {
    http_response_code(400);
    exit;
}

$event = json_decode($payload, true);

Node.js:

const crypto = require('crypto');

function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
  const expected = crypto.createHmac('sha256', secret).update(`${parts.t}.${rawBody}`).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) <= 300;
  return fresh && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1 || ''));
}

Use the raw body exactly as received. Re-encoding the JSON changes it.

Answering and retries

  • Answer with any 2xx status within 10 seconds. Do the slow work after answering.
  • Any other answer, a timeout or a redirect counts as a failure. EazyGo retries after 1 minute, 5 minutes, 15 minutes, 1 hour and 3 hours, and then marks the delivery failed.
  • Events can arrive more than once or out of order. Use X-EazyGo-Delivery to skip duplicates, and when order matters, read the booking's current state with GET /bookings/{reference}.
Sign in with Mobile
Enter your mobile number to receive OTP