{
"object": "event",
"id": "msg_5f0c2a9e7b1d4c3a8e6f0b12",
"type": "order.filled",
"timestamp": "2026-09-25T06:13:02Z",
"version": 2,
"data": {
"object": "order",
"id": "ord_62jxryztxctob7uopekg",
"state": "filled",
"account": "1000000001",
"symbol": "DANGCEM",
"side": "buy",
"quantity": 10,
"type": "market",
"time_in_force": "day",
"price_kobo": null,
"filled_quantity": 10,
"exchange_order_id": "1790316754123",
"reason": null,
"reject_reason": null,
"created_at": "2026-09-25T06:12:34Z",
"updated_at": "2026-09-25T06:13:02Z",
"filled_at": "2026-09-25T06:13:02Z",
"average_fill_price_kobo_decimal": "47500",
"client_reference": null
}
}Receive an event
What we send to your webhook endpoint when one of your orders, applications or allocations changes: the event exactly as GET /v1/events lists it. Check webhook-signature before you trust it, and answer with any 2xx. See Webhooks for how to verify it and when we send it again. The example is the test vector on that page: it verifies with the secret shown there.
{
"object": "event",
"id": "msg_5f0c2a9e7b1d4c3a8e6f0b12",
"type": "order.filled",
"timestamp": "2026-09-25T06:13:02Z",
"version": 2,
"data": {
"object": "order",
"id": "ord_62jxryztxctob7uopekg",
"state": "filled",
"account": "1000000001",
"symbol": "DANGCEM",
"side": "buy",
"quantity": 10,
"type": "market",
"time_in_force": "day",
"price_kobo": null,
"filled_quantity": 10,
"exchange_order_id": "1790316754123",
"reason": null,
"reject_reason": null,
"created_at": "2026-09-25T06:12:34Z",
"updated_at": "2026-09-25T06:13:02Z",
"filled_at": "2026-09-25T06:13:02Z",
"average_fill_price_kobo_decimal": "47500",
"client_reference": null
}
}Authorizations
Authorization: Bearer <key>. Sandbox keys start with mgw_test_ and live keys start with mgw_live_. Each key works only in its own environment, and a live key works only from the IP addresses or ranges registered for it.
Headers
The event's id. It's the same on every attempt, so use it to drop repeats.
^msg_[0-9a-f]{24}$v1, and the base64 HMAC-SHA256 of webhook-id, webhook-timestamp and the body, joined by full stops, keyed with your signing secret. More than one, separated by spaces, while a secret is being rotated.
Body
"event"Unique identifier for the event. Starts with msg_. Matches the webhook-id header the event was sent with.
^msg_[0-9a-f]{24}$What changed, followed by the state the change moved it to. New types can appear: ignore any you don't handle.
allocation.booked, allocation.refused, allocation.rejected, allocation.uncertain, application.opened, application.refused, application.rejected, application.submitted, application.uncertain, application.unplaced, order.cancelled, order.expired, order.filled, order.partially_filled, order.pending, order.refused, order.rejected, order.uncertain The updated_at of the order, application or allocation.
Increases with each of your events and is never reused. Other partners' events never move it. Compare it per object: ignore an event whose version is lower than the last you applied to that object.
The order, application or allocation as the change left it, exactly as its GET returned it then. Its object field says which.
- Option 1
- Option 2
- Option 3
Show child attributes
Show child attributes
Response
Any 2xx tells us you have the event. Anything else, or no answer in time, and we send it again later.