Multi-stop deliveries
Send one courier to several places in a fixed order: up to 10 stops between pickup and dropoff, each with its own contact and instructions.
A multi-stop delivery is one courier trip with intermediate stops between pickup and dropoff, for example a supplier on the way, or several recipients on one route.
Code examples use BASE_URL and headers from the Quickstart.
Rules#
- Send up to 10 entries in
stops, in the order the courier should drive them. - Do not repeat
pickupordropoffinsidestops. - Every stop has
address,latitude, andlongitude.contactandinstructionsare optional per stop. They are required at pickup (contact) and dropoff (contact). - The price covers the whole route, so quote with the same stops you book.
Quote and book a route with stops#
Quote the route
Send the stops to
POST /v1/quotes. Quotes take bare locations, without contacts or instructions.curl -X POST https://api.maxmove.com/v1/quotes \ -H "x-api-key: $MAXMOVE_KEY" -H "content-type: application/json" \ -d '{ "pickup": { "address": "Ehrenstraße 15, 50672 Köln", "latitude": 50.9385, "longitude": 6.9469 }, "stops": [ { "address": "Friedrich-Ebert-Platz 2, 51373 Leverkusen", "latitude": 51.0327, "longitude": 6.9877 } ], "dropoff": { "address": "Königsallee 27, 40212 Düsseldorf", "latitude": 51.2233, "longitude": 6.7768 }, "vehicle_type_id": "courier" }'const pickup = { address: 'Ehrenstraße 15, 50672 Köln', latitude: 50.9385, longitude: 6.9469 }; const stop = { address: 'Friedrich-Ebert-Platz 2, 51373 Leverkusen', latitude: 51.0327, longitude: 6.9877 }; const dropoff = { address: 'Königsallee 27, 40212 Düsseldorf', latitude: 51.2233, longitude: 6.7768 }; const quote = await fetch(`${BASE_URL}/quotes`, { method: 'POST', headers, body: JSON.stringify({ pickup, stops: [stop], dropoff, vehicle_type_id: 'courier' }), }).then((res) => res.json());pickup = {"address": "Ehrenstraße 15, 50672 Köln", "latitude": 50.9385, "longitude": 6.9469} stop = {"address": "Friedrich-Ebert-Platz 2, 51373 Leverkusen", "latitude": 51.0327, "longitude": 6.9877} dropoff = {"address": "Königsallee 27, 40212 Düsseldorf", "latitude": 51.2233, "longitude": 6.7768} quote = requests.post( f"{BASE_URL}/quotes", headers=headers, json={"pickup": pickup, "stops": [stop], "dropoff": dropoff, "vehicle_type_id": "courier"}, ).json()Book the same route with handoff details
Send the identical route to
POST /v1/deliveriesand add who the courier meets where. Withquote_id, any difference in addresses, coordinates, or stop order fails with400 quote_mismatch.const delivery = await fetch(`${BASE_URL}/deliveries`, { method: 'POST', headers: { ...headers, 'Idempotency-Key': 'order-4711' }, body: JSON.stringify({ quote_id: quote.id, pickup: { ...pickup, contact: { name: 'Feinkost Ehrenfeld', phone: '+49 221 1234567' } }, stops: [{ ...stop, instructions: 'Collect two crates at gate 3.' }], dropoff: { ...dropoff, contact: { name: 'Erika Muster', phone: '+49 170 1234567' }, instructions: 'Ring at reception, 2nd floor.', }, vehicle_type_id: 'courier', }), }).then((res) => res.json());delivery = requests.post( f"{BASE_URL}/deliveries", headers={**headers, "Idempotency-Key": "order-4711"}, json={ "quote_id": quote["id"], "pickup": {**pickup, "contact": {"name": "Feinkost Ehrenfeld", "phone": "+49 221 1234567"}}, "stops": [{**stop, "instructions": "Collect two crates at gate 3."}], "dropoff": { **dropoff, "contact": {"name": "Erika Muster", "phone": "+49 170 1234567"}, "instructions": "Ring at reception, 2nd floor.", }, "vehicle_type_id": "courier", }, ).json()
What changes while the courier drives#
- The delivery returns
stopsin the order you sent them, each with itscontactandinstructions(ornull). delivery.courier_arrivedfires at every waypoint. At pickup and dropoff the status becomesat_pickuporat_dropoff; at an intermediate stop the status does not change.- Tracking reports
eta_secondsanddistance_metersto the next waypoint, not to the final dropoff.
Several independent recipients with different time windows are usually better served by separate deliveries: each one then has its own status, tracking link, and proof of delivery.
Did this answer your question?