Skip to main content

Turning them on

Give your account manager an HTTPS URL during onboarding and we’ll push events to it. No URL on file means no webhooks. Poll GET /deliveries/{uid} instead for the same state. One URL per platform. Fan out to individual merchants on your side using uid or platform_payload. Both are on every event.

What we send

POST to your URL, Content-Type: application/json, with a JWT in the Authorization header. We expect a 2xx. Anything else, or a timeout, and we retry up to five times with a growing gap between attempts. Webhooks can arrive more than once, and status events can arrive out of order when a courier’s updates bunch up. Key on uid and treat handling as idempotent.

Event types

Delivery events cover the lifecycle of the delivery itself: Location events are the same milestones carrying fresh courier coordinates. Use these to move a pin on a map, and the delivery events to drive state. location.assigned_driver, location.pickup_enroute, location.pickup_arrived, location.pickup_complete, location.dropoff_enroute, location.dropoff_arrived, location.return_in_progress

Body

Notes on individual fields

Fields we have no value for are sent as null or omitted. Treat both the same way.

Verifying the request

Each webhook carries a JWT signed with our RSA private key. Verify it with our public key before you trust the body. Your account manager provides unihop_public_key.pem.
The token decodes to:
payload holds the body documented above. Check that iss is unihop, that the signature verifies under RS256, and that exp hasn’t passed.

Responding

Return a 2xx as soon as you’ve stored the event, then do the real work asynchronously. We treat a slow endpoint as a failed one.