Getting started
1. Create an API client
Section titled “1. Create an API client”In Dispatch, open Settings → Developers → API Access. Create a named client with:
quotes:createif you will show provider choices, prices, or estimates before checkoutorders:writeto create and update ordersorders:readto reconcile order statewebhooks:readandwebhooks:writeif the integration manages its own webhook destination
Create a key and copy the secret immediately. It is displayed once. Store it in a secret manager—never in browser code, screenshots, logs, or committed collection files.
2. Use sandbox first
Section titled “2. Use sandbox first”- Production:
https://api.firstdelivery.com/api - Sandbox:
https://sandbox.firstdelivery.com/api
Credentials are environment-specific. A production key does not work in sandbox, and a sandbox key does not work in production.
Send the key as a Bearer token:
curl 'https://sandbox.firstdelivery.com/api/v3/merchants' \ --header "Authorization: Bearer $FIRST_DELIVERY_API_KEY"New API-client keys begin with f1rst_k1_. Treat the full value as opaque.
3. Decide whether you need a quote
Section titled “3. Decide whether you need a quote”For basic integrations, quotes are optional. You can create an order directly and let the merchant’s Dispatch Strategy choose a provider.
Request quotes first when you need to:
- show the customer a provider choice;
- show delivery price or pickup/drop-off estimates before checkout; or
- preview what the configured strategy would choose right now.
The quote response is a point-in-time snapshot:
quotescontains successful providers after strategy bans and preference sorting;all_quotesalso includes successful providers that the strategy bans;strategyexplains the preference order and bans used for this request.
4. Get provider quotes (optional)
Section titled “4. Get provider quotes (optional)”Use the real merchant ID and a realistic, geocodable drop-off address near that merchant.
curl 'https://sandbox.firstdelivery.com/api/v3/quotes' \ --request POST \ --header "Authorization: Bearer $FIRST_DELIVERY_API_KEY" \ --header 'Content-Type: application/json' \ --data '{ "merchant_id": "YOUR_MERCHANT_ID", "dropoff": { "full_address": "2166 E Norris St, Philadelphia, PA 19125", "instructions": "Apartment 3B" } }'An empty quote list usually means the address is outside providers’ service areas, the phone/address data is invalid, or the strategy has filtered every available provider. Sandbox is especially sensitive to unrealistic locations—start with pickup and drop-off addresses in the same city.
See the complete Get Provider Quotes reference.
5. Create the order
Section titled “5. Create the order”curl 'https://sandbox.firstdelivery.com/api/v3/orders' \ --request POST \ --header "Authorization: Bearer $FIRST_DELIVERY_API_KEY" \ --header 'Content-Type: application/json' \ --data '{ "merchant_id": "YOUR_MERCHANT_ID", "external_id": "order-100042", "customer_name": "David Baldwin", "customer_phone": "+13179385775", "payment_type": "online", "subtotal": 9.99, "tax": 0.70, "tip": 3.00, "order_total": 13.69, "contents": [ { "name": "Jigowatt Nachos", "price": 9.99, "quantity": 1 } ], "pickup": { "instructions": "Pickup at the front counter" }, "dropoff": { "full_address": "2166 E Norris St, Philadelphia, PA 19125", "instructions": "Apartment 3B" } }'Save the returned First Delivery order.id; it is the canonical identifier for later API calls, webhooks, and support. Also retain _request_id when present.
See the complete Create Order reference.
6. Choose routing behavior
Section titled “6. Choose routing behavior”Order creation supports three routing modes:
- Merchant default: omit
quote_idandstrategy_id; the merchant’s active strategy decides. - Specific strategy: pass
strategy_idto use that strategy instead of the merchant default. Strategy hours still apply; outside active hours the order is created but not auto-dispatched. - Customer-selected provider: pass a quote
idasquote_id. First attempts that quote/provider first. If the quote/provider attempt fails, routing records the error and falls back to the strategy.
Provider prices and availability change. If the customer selected a quote, fetch quotes again immediately before creating the order so they can confirm any difference. Quote rejection becomes increasingly likely after roughly five minutes, although providers have different expiration rules.
Without an automated strategy, the order appears in its status column in Dispatch for manual assignment. With an automated strategy, it appears in the external-fleet flow and moves to the courier row after assignment. Inspect auto_route.success and auto_route.errors when routing does not succeed.
7. Avoid the common rejection causes
Section titled “7. Avoid the common rejection causes”- Addresses: Prefer a geocoder-normalized
dropoff.full_address. Put apartment numbers, building names, access details, and landmarks indropoff.instructions; mixing them into the address lowers provider acceptance. - Phones: Use real, country-valid merchant and customer phone numbers. Providers can reject obviously fake or wrong-country numbers.
- Scheduling: Omit both time fields for ASAP. For a scheduled order, send either
pickup_timeordropoff_time, not both, as an ISO 8601 UTC timestamp at least 20 minutes ahead. Individual fleets can apply longer scheduling thresholds. - Money:
order_total,tax, anddiner_delivery_feeare primarily reporting values.subtotalaffects refund eligibility andtipaffects courier acceptance. Monetary values in the order request are dollars/local currency, not cents. - Items: Include item
name, unitprice, andquantityfor refund eligibility. Dimensions are centimeters and weight is grams. - Provider options: PIN, signature, alcohol/ID checks, post-create edits, and undeliverable handling differ by fleet. Review Fleet behavior before exposing an option to customers.
8. Test the lifecycle
Section titled “8. Test the lifecycle”In sandbox, Uber is the only network provider that simulates the full assignment-to-delivery webhook lifecycle. To receive that sequence quickly:
- do not pass a non-Uber
quote_id; - make sure the active strategy can select Uber; and
- omit scheduled times.
Treat webhooks as signals that can be delayed, duplicated, or arrive out of order. Make the receiver idempotent and reconcile important state with GET /v3/orders/:id.

