Docs › Orders

Create an order

POST /v1/orders — single drops and multi-stop routes.

http
POST /v1/orders

Creates a delivery order in your Dragonfly account. Safe to retry: it is idempotent on externalId.

Request body

FieldTypeRequiredDescription
externalIdstring (≤200)yesYour own order id. Re-sending it returns the existing order instead of creating a duplicate.
pickupStopyesWhere the driver collects the order.
dropoffStopone ofA single delivery.
dropoffsStop[] (1–25)one ofA multi-stop route from the same pickup.
subMerchantIdstringnoThe pickup location, for merchants with several locations. It must belong to your account.
subtotalCentsintegerrecommendedOrder value in cents. Drives tiered pricing, and minimum gratuity where your contract has one.
tipCentsintegernoTip in cents. 100% goes to the driver.
taxCents, totalCentsintegernoFor your records and reporting.
metadataobjectnoFree-form; echoed back in webhooks.

Send either dropoff (one delivery) or dropoffs (a route).

Single drop (catering, on-demand)

bash
curl -s https://api.trydragonfly.com/v1/orders \
  -H "Authorization: Bearer $DRAGONFLY_API_KEY" -H 'content-type: application/json' -d '{
  "externalId": "cater-88412",
  "pickup":  { "address": "100 W Randolph St, Chicago, IL 60601", "contactName": "Kitchen", "contactPhone": "+13125550100",
               "windowStart": "2026-10-09T10:45:00-05:00", "notes": "Back door on Lake St" },
  "dropoff": { "address": "233 S Wacker Dr, Chicago, IL 60606", "contactName": "Front desk, 31st floor", "contactPhone": "+13125550111",
               "contactEmail": "[email protected]",
               "windowStart": "2026-10-09T11:30:00-05:00", "windowEnd": "2026-10-09T11:45:00-05:00",
               "notes": "Set up on the conference room credenza", "photoRequired": "REQUIRED" },
  "subtotalCents": 64000,
  "tipCents": 9000
}'

Multi-stop route

bash
curl -s https://api.trydragonfly.com/v1/orders \
  -H "Authorization: Bearer $DRAGONFLY_API_KEY" -H 'content-type: application/json' -d '{
  "externalId": "route-2026-10-09-am",
  "pickup": { "address": "870 Market St, San Francisco, CA 94102", "contactPhone": "+14155550100" },
  "dropoffs": [
    { "address": "1 Ferry Building, San Francisco, CA 94111", "contactName": "A. Patel", "contactPhone": "+14155550111" },
    { "address": "2173 Harbor Bay Pkwy, Alameda, CA 94502", "contactName": "J. Rivera", "contactPhone": "+14155550112", "requiresSignature": true }
  ]
}'
Note: If your account is on Dragonfly routing, send one order per recipient rather than building routes yourself. Dragonfly optimizes the day's routes across all of your orders.

Response

201 Created for a new order. 200 OK for an idempotent replay, which returns the existing order.

json
{
  "data": {
    "orderId": "cmuyh89rz000d01pc9uuokrld",
    "externalId": "cater-88412",
    "status": "PENDING",
    "dropoffs": 1,
    "dispatchedTo": "cartwheel",
    "trackingUrl": null,
    "idempotentReplay": false
  }
}

See The order object for every field and value.

Errors

HTTPcodeTypical cause
400VALIDATION_ERRORA missing contactPhone, a bad window format, or neither dropoff nor dropoffs. details[] names each field.
400INVALID_SUB_MERCHANTsubMerchantId isn't one of your locations.
401UNAUTHORIZEDMissing, wrong or revoked key.
403MERCHANT_INACTIVEThe account is deactivated.
429RATE_LIMITEDMore than 100 requests per minute on this key.

Full list: Errors.

Something unclear or missing? Tell us.