Auto-routing strategies
Auto-routing creates the order first, then tries to place its delivery with an eligible external fleet. A routing failure does not mean the order was never created. Always retain the returned order.id and inspect the auto_route result.
The configuration mental model
Section titled “The configuration mental model”A strategy answers four separate questions:
-
Should this order route automatically?
Territory/merchant settings, strategy hours, request flags, and manual-dispatch tripwires decide.
-
When should routing start?
Immediately, or after
auto_assign_delay. -
Which provider should be tried first?
Bans, preferred ordering, the tie breaker, and an optional faster-provider threshold rank successful quotes.
-
What happens if assignment stalls?
Optional auto-reassign settings can start another provider attempt.
Strategy resolution
Section titled “Strategy resolution”The strategy is resolved in this order: request strategy_id, merchant strategy, territory strategy, then operator default.
An explicit strategy_id overrides the merchant, territory, and default selection, but it does not bypass the strategy’s inactive hours or manual-dispatch controls.
A quote_id is different: it asks First to try that quote’s provider before running the resolved strategy. It does not replace strategy resolution.
Auto-routing eligibility
Section titled “Auto-routing eligibility”Auto-routing is skipped when any configured manual-dispatch tripwire matches:
- scheduled orders when Hold scheduled orders is enabled;
- catering orders when Hold catering orders is enabled;
- merchant-app orders when Hold manually entered orders is enabled; or
- orders over the strategy’s maximum order value.
The routing trail records the exact skip reason. The order remains available for manual dispatch.
Supplying strategy_id is an explicit request to route with that strategy, even when the territory would not otherwise route at creation. The API does not let skip_routing_strategy block an explicit strategy_id; treat those fields as conflicting intents and send only one.
A quote_id is attempted only after the order enters routing. In production, quote_id by itself does not enable routing when strategy routing is off—enable strategy routing for the territory or send an explicit strategy_id.
Immediate routing versus delayed routing
Section titled “Immediate routing versus delayed routing”auto_assign_delay lets an internal fleet receive the order first before external fleets are attempted. When the delay expires, the order must still be pending and eligible.
Hybrid strategy settings can bypass the delay and route immediately when:
- the order is flagged out-of-zone and Route out-of-zone orders externally is enabled;
- crow-flies distance exceeds the configured threshold;
- the tip is below the configured threshold;
- no driver shifts/blocks exist; or
- blocks exist but no drivers are checked in, when that additional condition is enabled.
Quote filtering and provider ranking
Section titled “Quote filtering and provider ranking”First requests quotes from eligible fleets, then applies the strategy:
Provider settings
Section titled “Provider settings”| Setting | Behavior |
|---|---|
| Preferred providers | Tried first in configured order. |
| Banned providers | Removed before delivery attempts. |
| Tie breaker: cheapest | Ranks non-preferred providers by quoted price. |
| Tie breaker: fastest | Ranks non-preferred providers by estimated delivery time. |
| Faster-provider threshold | Allows an alternative to move ahead of the top preferred provider only when it is faster by more than the configured minutes. An exact tie stays with the preferred provider. |
| Skip matching source provider | Avoids sending an order back to the same provider that originated it when configured. |
| Catering preferences | For catering orders, catering-preferred providers are ranked before standard preferences when configured. |
If the top preferred provider does not return a comparable quote, routing falls back to the remaining strategy order.
quote_id override behavior
Section titled “quote_id override behavior”When POST /v3/orders includes quote_id:
- Before inserting the order, First validates that the quote exists. An unknown quote ID fails order creation with
Quote not found. - First attempts that quote’s provider after the order enters routing.
- If Skip matching source provider is enabled and the quote provider matches the order source—for example, Uber Eats → Uber—the override is skipped.
- If the provider accepts, routing stops successfully.
- If the quote/provider attempt fails, First records the error and continues through the strategy-ranked providers.
- If a previously validated quote disappears before the routing step, First records the lookup failure and falls through to strategy routing.
Quotes are snapshots. Re-fetch immediately before checkout confirmation so the customer can accept price or timing changes.
Reading the create-order response
Section titled “Reading the create-order response”The create response separates the committed order from routing metadata:
{ "type": "success", "order": { "id": "FIRST_ORDER_ID", "status": "pending_assign" }, "auto_route": { "enabled": true, "success": true, "errors": [], "strategy": {} }}enabled: falsemeans immediate create-time routing was not active. Common causes are strategy routing being off,skip_routing_strategy, inactive strategy hours, or a manual-dispatch tripwire.enabled: true, success: truemeans routing ran successfully. A configured delay can mean the provider attempt is intentionally queued.enabled: true, success: falsemeans the order exists but no delivery was placed. Inspecterrorsand the routing trail, then resolve manually or retry deliberately.
Do not retry POST /v3/orders blindly after a routing failure—the order may already exist.
An authorized dispatcher can deliberately retry a still-unassigned order through POST /v3/orders/:orderId/autoroute. The endpoint refuses an order that already has an external assignment.
Auto-reassign after initial routing
Section titled “Auto-reassign after initial routing”Auto-reassign is an advanced safety net for an accepted delivery that does not obtain a courier by the configured threshold.
Relevant settings include:
- whether auto-reassign is enabled;
- the threshold and timestamp anchor;
- whether the initial provider can be retried; and
- whether the original pending delivery remains active while the replacement is attempted.
During a race, multiple delivery attempts can temporarily exist for one order. Integrations must continue correlating by First Delivery orderId, not by provider delivery ID.
Operational recipe
Section titled “Operational recipe”For a reliable automated integration:
- Configure a default or merchant strategy with explicit preferences and bans.
- Enable strategy routing for the territory/merchant.
- Start with no assignment delay unless you intentionally operate a hybrid internal/external fleet.
- Configure manual tripwires for orders that truly require human review.
- Create a named API client with
orders:write,orders:read, andquotes:createif quoting first. - Persist
order.id,_request_id, selected strategy, and provider delivery ID. - Consume webhooks idempotently and reconcile via
GET /v3/orders/:id. - Monitor orders where
auto_route.successis false or assignment remains pending beyond your expected window.

