Burq → Getcho, endpoint by endpoint.
Moving a Burq delivery integration onto Getcho's Business Orders API is a base-URL swap, a header swap, and a thin body/status rename layer. This page maps every Burq call you make today to its Getcho counterpart and calls out what's new and what isn't there yet.
- In one paragraph
- Base URL & auth
- Endpoint map
- A · Quote
- B · Book
- C · Track & status mapping
- D · Cancel & reschedule
- Webhooks
- Sandbox
- Not on Getcho yet
- Discovery questions
In one paragraph
Burq and Getcho are the same shape: quote → book → poll → cancel/reschedule, one API key per business, prices returned per carrier. Getcho adds a real sandbox (simulated couriers, no charges), a stable tracking URL from the first response, and a first-class reschedule call. Getcho does not yet expose Burq's multi-stop routes, stores, or a list endpoint. Budget roughly a day of integration work against the sandbox.
Base URL & auth
| Burq | Getcho | |
|---|---|---|
| Production | https://api.burqup.com/v1 | https://api.getcho.app/api/v1/business-orders |
| Sandbox | same URL, Sandbox Key (dashboard "Test Environment" toggle) | https://staging.getcho.app/api/v1/business-orders, gcho_test_… key |
| Auth header | x-api-key: <key> | Authorization: Bearer <key> |
| Env mix-up | silently hits the other environment | 401 with an explicit reason (Test api key used on production …) |
The business is inferred from the key — there is no business id in any body. You receive a gcho_test_ key first; the live key is minted at go-live and the only change on your side is the base URL and token.
Endpoint map
| You call on Burq today | Call on Getcho | Notes |
|---|---|---|
POST /quote · POST /delivery_information (initiate:false) | POST /quotes | Multi-carrier, cheapest first, prices final & all-in |
POST /initiate_delivery · POST /delivery_information (initiate:true, quote_id) | POST /orders — or POST /orders/dispatch for ASAP | Booking runs async; poll |
GET /delivery/{id} | GET /orders/{orderId} | Status, courier, ETAs, tracking URL, proof of delivery |
POST /delivery/{id}/cancel | POST /orders/{orderId}/cancel | Idempotent; warning if the carrier cancel failed |
PUT /orders/{id} (time only) | POST /orders/{orderId}/reschedule | Getcho-only as a first-class call |
GET /deliveries (list) | — | Burq-only keep your own order → orderId map |
/stores CRUD | — | Burq-only send the pickup address on every quote |
| Routes / multi-stop, Incidents, Connect | — | Burq-only see Not on Getcho yet |
| Webhooks | delivery.* events | see Webhooks |
A · Quote
POST /quotes
Burq's quote is one price for the provider Burq picked. Getcho returns every bookable carrier as its own quote, cheapest first, each with a single-use quoteId that expires in ~15 minutes.
Request — Burq's flat fields become nested objects. Items need weight and dimensions (Burq only asked for name / quantity / size).
{
"pickup_address": "8340 W 3rd St, Los Angeles, CA 90048",
"pickup_name": "French Florist",
"pickup_phone_number": "+13235550100",
"dropoff_address": "1043 S Point View St, Los Angeles, CA 90035",
"dropoff_name": "Gilit R.",
"dropoff_phone_number": "+13105550123",
"dropoff_notes": "Leave with doorman",
"items": [{ "name": "Arrangement", "quantity": 1, "size": "medium" }],
"external_order_ref": "FF-221927",
"initiate": false
}{
"pickup": { "address": "8340 W 3rd St, Los Angeles, CA 90048",
"name": "French Florist", "phone": "+13235550100" },
"dropoff": { "address": "1043 S Point View St, Los Angeles, CA 90035",
"name": "Gilit R.", "phone": "+13105550123",
"instructions": "Leave with doorman" },
"items": [{ "description": "Arrangement", "quantity": 1,
"weight": 5, "length": 12, "width": 12, "height": 18 }],
"overallSize": "medium", // optional, default medium
"pickupWindow": { "start": 1756660800000, "end": 1756668000000 },
// optional; omit for ASAP
"requestProof": true, // photo proof of delivery
"externalRef": "FF-221927" // echoed on every Order
}Response
{
"quotes": [
{ "quoteId": "q_3b1c", "carrier": "uber", "displayName": "Uber",
"priceCents": 930, "etaMinutes": 41, "currency": "USD" },
{ "quoteId": "q_8f2a", "carrier": "doordash", "displayName": "DoorDash",
"priceCents": 975, "etaMinutes": 34, "currency": "USD" },
{ "quoteId": "q_c41d", "carrier": "grubhub", "displayName": "Grubhub",
"priceCents": 999, "etaMinutes": 47, "currency": "USD" }
],
"expiresAt": "2026-08-31T18:15:00Z"
}
priceCents is the carrier's price — no percentage markup is added. An empty quotes: [] means no carrier serves the lane (typically distance); treat it as Burq's "no provider available".
B · Book
POST /orders (scheduled) · POST /orders/dispatch (ASAP)
Burq books by re-sending the manifest with quote_id (or via /initiate_delivery). Getcho books the quoteId alone — addresses and items from the quote are reused. POST /orders anchors dispatch to the quote's pickupWindow; POST /orders/dispatch sends a courier now.
{
"quoteId": "q_3b1c",
"dropoff": { "notes": "Call on arrival" }, // optional overrides
"isSignatureRequired": false,
"minAgeRequirement": 21 // ID check at handoff (alcohol)
}{
"orderId": 68901,
"status": "PENDING", // carrier booking in flight
"carrier": "uber",
"priceCents": 930, "currency": "USD",
"trackingUrl": "https://withgetcho.com/t/68901",
// stable from the first response
"pickup": { "address": "…", "name": "…", "phone": "…" },
"dropoff": { "address": "…", "name": "…", "phone": "…",
"instructions": "…" },
"externalRef": "FF-221927",
"createdAt": "2026-08-31T17:02:11Z"
}The response is immediate; the carrier accepts in the background. Poll GET /orders/{orderId} until status is DISPATCHED (or FAILED — then book another quote). 409 = quote already booked, 410 = quote expired.
C · Track
GET /orders/{orderId}
Same call as Burq's GET /delivery/{id}; the object is flatter.
| Burq field | Getcho field |
|---|---|
id | orderId |
status (see mapping below) | status |
provider.name | carrier |
payment_amount + fee | priceCents (one number, all-in) |
tracking_url | trackingUrl |
courier_name · courier_phone_number | courierName · courierPhoneNumber |
pickup_eta · dropoff_eta | pickupEta · dropoffEta |
dropoffs[0].* + flat dropoff_* | dropoff.{address,name,phone,instructions,lat,lng} |
proof_of_delivery | proofOfDelivery[] ({type:"photo_proof_of_delivery", url}) |
external_order_ref | externalRef |
| — | providerDeliveryId Getcho-only |
test_mode · reroute · status_history · courier_location_* · signature | Burq-only — courier location is available via the delivery.location_updated webhook |
Status mapping
Getcho collapses Burq's 19 statuses into 6. Map on your side:
| Burq | Getcho |
|---|---|
request, scheduled, delivery_created, driver_not_assigned | PENDING |
driver_assigned, enroute_pickup, arrived_at_pickup | DISPATCHED |
pickup_complete, enroute_dropoff, arrived_at_dropoff | PICKED_UP |
dropoff_complete, delivered | DELIVERED |
provider_canceled, customer_canceled, burq_canceled | CANCELED |
failed | FAILED (+ failureReason) |
enroute_to_return, returned, disputed | not a status on Getcho — returns arrive as the delivery.returned webhook; disputes go through support |
D · Cancel & reschedule
POST /orders/{orderId}/cancel
One route for Burq's cancel/delete variants. Body { "reason": "…" } is optional. The order is canceled on our side regardless; if the carrier cancel fails you get 200 with a warning and our ops team steps in. 409 once delivered. Idempotent.
POST /orders/{orderId}/reschedule
Burq: PUT the order with a new time. Getcho: { "pickupWindow": { "start", "end" } } in epoch milliseconds. Rejected (409) once the courier is at or past pickup; 501 on a carrier that can't reschedule (Grubhub). Address, item or contact changes are cancel + rebook — same as Burq.
Webhooks
Burq: dashboard-registered per environment, delivery.updated and friends, signed with Burq-Signature. Getcho: delivery.* events to an HTTPS endpoint, HMAC-signed —
delivery.created · delivery.driver_assigned · delivery.pickup_complete · delivery.delivered · delivery.canceled · delivery.failed · delivery.returned · delivery.location_updated (opt-in heartbeat, ~10 min)
GET /orders/{orderId} is always sufficient.Sandbox
https://staging.getcho.app runs production code and database with Uber's test-mode account behind it. Every booking gets a simulated Robo Courier: DISPATCHED immediately, PICKED_UP at about 1:30, DELIVERED at about 2:30 — real tracking URL, real webhooks, no charge. Staging quotes are Uber-only. A gcho_test_ key works only there, a gcho_live_ key only on production, and each environment can only see its own orders.
Not on Getcho yet
- Multi-stop routes (Burq
/v2/routes, route quotes, batch orders) — one pickup → one dropoff per order today. Consolidated runs are arranged with Getcho ops, not through the API. GET /deliverieslist, Stores, Incidents, Connect.test_modeon the order — the environment is implied by the key.- Carriers: Uber, DoorDash and Grubhub are bookable through the API; other Getcho fleets are internal-only until exposed. Grubhub can't take age-restricted orders or reschedules.
Discovery questions
Each lists Getcho's default assumption — if it holds, there's nothing extra to do.
- One-shot or two-step?
POST /delivery_informationwithinitiate:true, or quote theninitiate_delivery. (Default: two-step.) - Burq v1 or v2?
/delivery_information(v1) or/v2/orders→ routes → quotes → dispatch (v2). The map above is v1; v2 flattens to the same three Getcho calls. - Webhooks or polling? (Default: polling.)
- Scheduled windows or ASAP? A window's start maps to
pickupWindow.start. (Default: ASAP.) - Any Routes / multi-stop use? (Default: none.)