Pushing Status Updates

The one call you make to YUMBI Gateway — reporting a delivery's progress, and the rules YUMBI Gateway applies to what you send.

Pushing Status Updates

Once a delivery is dispatched, you report its progress to YUMBI Gateway. This is the only endpoint you call; everything else in this section is us calling you.

POST https://gateway.yumbi.com/api/v1/deliveries/{order_guid}/status_update
Authorization: Bearer {access_token}
Content-Type: application/json

The host is gateway-za.yumbidemo.com on staging and gateway.yumbi.com in production — see Reference values. The path is the same on both.

{order_guid} is the order_guid we sent you on the dispatch webhook.

If your platform round-trips the numeric order_id instead of the guid, send it as an order_id field in the body. The path segment is only read as a guid, so a numeric id there resolves nothing on its own — the body field is what matches the order.

YUMBI Gateway applies the update to the delivery, records it, and forwards it to the ordering channel, which is what moves the customer's tracking screen.

Authentication

OAuth 2.0 bearer token — see Authentication. Cache the token and reuse it; a busy provider pushing location pings will otherwise mint thousands of tokens an hour.

🚧

HMAC is not accepted here

Inbound calls are OAuth only. A request signed with X-HMAC and X-Client-ID but no Authorization header is a 401.

Body

{
  "update_type": "status",
  "delivery_status": "on_route",
  "provider_delivery_id": "prv_dl_xyz789",
  "driver_full_name": "Sipho Ndlovu",
  "driver_registration": "CA 123-456",
  "vehicle_type": "motorcycle",
  "vehicle_color": "red",
  "driver_latitude": -29.7801,
  "driver_longitude": 30.7842,
  "estimated_time_of_arrival": "2026-08-07T14:41:00+02:00"
}
HTTP/1.1 200 OK

{ "ok": true }
FieldTypeNotes
update_type"status" | "location"Defaults to status. See Location pings.
delivery_statusstringA canonical status.
provider_delivery_idstringYour delivery reference. Send it on every update.
driver_full_namestringShown to the customer.
driver_registrationstringVehicle registration or licence plate.
vehicle_typestringFree text.
vehicle_colorstringFree text.
driver_latitudenumberDecimal degrees.
driver_longitudenumberDecimal degrees.
estimated_time_of_arrivalISO 8601
delivery_coords_overridestringCorrected dropoff coordinates, if you moved the pin.
pin_codestringHandover PIN, if it changes after dispatch.
signature_requiredbooleanIf it changes after dispatch.
order_idintegerThe numeric order reference, if your platform round-trips it instead of the guid.
brand_guidstringOnly where your signing secret is per brand — see below.

Every field is optional. Anything you omit keeps its stored value, so a driver's name reported once does not need repeating on every ping. Send what changed, plus provider_delivery_id.

Which delivery gets updated

Two references are tried, in order:

  1. provider_delivery_id in the body. Takes precedence, and targets a specific dispatch attempt.
  2. The order referenceorder_id from the body if present, otherwise the order_guid in the path.

A provider_delivery_id that matches nothing does not fail the request — it falls through to the order reference. That is deliberate: your very first update can arrive before YUMBI Gateway has finished recording your delivery id, and a strict lookup would drop it.

Location pings

If you can report driver position, send it as it moves:

{
  "update_type": "location",
  "provider_delivery_id": "prv_dl_xyz789",
  "driver_latitude": -29.7795,
  "driver_longitude": 30.7860
}

A location update moves the pin on the customer's map and is forwarded to the channel, but does not run the status state machine — so it cannot advance, or accidentally regress, the lifecycle.

Send them at whatever frequency you support, and send a status update whenever the status actually changes. The two are independent; a status update carrying coordinates updates both.

Location pings are forwarded but not written to YUMBI Gateway's delivery history by default — they are high volume and would swamp it. We can enable history per provider when a specific problem needs diagnosing.

Four rules YUMBI Gateway applies

Read these before you write your retry logic, because between them they mean you need very little.

1. Status never goes backwards

Statuses are ranked in lifecycle order. An update whose delivery_status ranks lower than the stored one is accepted with a 200 and discarded. An arrived webhook overtaking an on_route one on the network cannot rewind the customer's screen.

The exception is a re-dispatch: if provider_delivery_id differs from the stored one, YUMBI Gateway reads it as a new attempt and allows the status to reset. This is why you send provider_delivery_id on every update — without it, a genuine reset back to assigned is silently dropped.

The four terminal statuses share the top rank, so nothing moves a delivery once it is delivered, cancelled, failed or undeliverable. A regression from a terminal status on the same attempt is logged as an error on our side, because it should be impossible.

2. Duplicates are free

An update that changes nothing is dropped without re-notifying the channel. Retrying after a timeout, or sending the same status twice, produces no duplicate notifications downstream.

This is worth knowing if your platform models a delivery as multiple legs. Where a pickup leg and a dropoff leg have overlapping events — the pickup leg completing and the dropoff leg starting both meaning "the driver has the food" — the two map to the same left_store, and the second is simply dropped. You do not have to suppress it yourself.

3. A 404 is retryable, not fatal

A 404 means the delivery was not found for you. That covers three cases you cannot distinguish, deliberately:

  • The reference is genuinely unknown.
  • The delivery belongs to a different provider. (Reported as not-found rather than forbidden, so the response never confirms another provider's order exists.)
  • A race: your first update arrived before YUMBI Gateway finished recording the delivery.

Treat a 404 as retryable with backoff. It is only a real failure if it persists.

4. Terminal statuses stop everything

Pushing a terminal status also stops any polling workflow still tracking the delivery, and tells the channel the delivery is over. Always push the terminal status, even for outcomes you consider unremarkable — a cancelled you initiated yourself, a failed after a driver no-show. It is the only way YUMBI Gateway learns.

Responses

StatusMeaningWhat to do
200Received. Also returned when the update was discarded as a regression or a duplicate.Nothing
401Missing, expired or invalid token; or a token that is not a delivery provider'sRe-mint the token and retry once
404No delivery matching that reference belongs to youRetry with backoff
422The update itself was rejectedDo not retry; check the body
5xxOur problemRetry with backoff

Retry 5xx and 404 with exponential backoff. Do not retry 422.

If you do not re-send failed webhooks, say so during onboarding. We queue inbound updates with retries on our side for providers that push once and never again, so an unreachable Gateway does not lose an update permanently.

Per-brand scoping

If your signing secret is scoped per brand rather than per integration — one account per brand — include brand_guid naming the brand whose secret authenticated the call:

{
  "brand_guid": "0b0f6f0a-6a6f-4c9c-9f1a-4f1c1a2b3c4d",
  "provider_delivery_id": "prv_dl_xyz789",
  "delivery_status": "delivered"
}

YUMBI Gateway then checks the delivery belongs to that brand and rejects it with a 404 if not. Without this, every brand on your platform sits behind one provider identity, and one brand's account could move another brand's delivery.

Omit the field if your signing is per integration. The provider identity is then the whole check.

What the channel receives

Each accepted update is forwarded to the ordering channel. You do not need to do anything for this, but it is worth knowing what your data becomes:

{
  "update_type": "status",
  "order_guid": "chan-ord-7781",
  "provider_delivery_id": "prv_dl_xyz789",
  "delivery_status": "on_route",
  "driver": {
    "full_name": "Sipho Ndlovu",
    "registration": "CA 123-456",
    "vehicle_type": "motorcycle",
    "vehicle_color": "red",
    "latitude": "-29.780100",
    "longitude": "30.784200"
  },
  "estimated_time_of_arrival": "2026-08-07T14:41:00+02:00"
}

The order_guid there is the channel's order reference, not the one you were given — YUMBI Gateway translates between them, and neither side sees the other's identifiers.


Did this page help you?