Order Drafts API
v1List, read, complete, and delete order drafts — incomplete imported orders waiting for the data they're missing.
An order draft is an order that arrived incomplete. When an import can’t be turned into a real order — missing customer, order type, vehicle type, or valid stops — Zendera stores it as a draft instead of rejecting it outright. Drafts sit in a worklist until someone (or something) completes them.
There is no POST. Drafts are created as a side effect of order import; this API manages the queue they land in.
Where this fits in your operation
- Work the exception queue programmatically: your integration polls the draft list, enriches drafts with the data your ERP has (customer ID, order type), and
PUTs them back — completed drafts turn into real orders automatically. - Clean up dead drafts: imports that will never complete (cancelled in your system) get
DELETEd instead of lingering. - Pre-book before finalising: drafts can be booked on schedule intervals while still incomplete.
Interactive API Explorer
Loading API Documentation...
Authentication
Authorization: apikey YOUR_API_KEY_HEREBase URLs
- Production:
https://app.zenderatms.com/api/ - Staging:
https://staging.zenderatms.com/api/
Endpoints
List drafts
GET /v1/draft/orders
Returns all drafts in your organization — there is no pagination or filtering. 204 No Content when there are none. Each draft carries the order fields it has so far (internal_order_number, customer_id/customer_name, order_type_id/order_type_name, vehicle_type_id/vehicle_type_name, …), its order_location_drafts and order_product_drafts, an optional route_schedule_booking, and a checksum.
draft_reasons lists why the order import created a draft instead of an order — use it to route each draft to whoever can fix it. The values are lowercase reason strings, not the import response’s reasons[].code enum names:
draft_reasons value | Missing or invalid |
|---|---|
customer_not_found_invalid_reason | Customer |
vehicle_type_not_found_invalid_reason | Vehicle type |
order_type_not_found_invalid_reason | Order type |
invalid_product_invalid_reason, invalid_product_skill_invalid_reason, invalid_custom_unit_invalid_reason | Products, product skills, custom units |
missing_pickup_invalid_reason, missing_pickup_location_name, invalid_pickup_address_invalid_reason, invalid_pickup_timewindow_invalid_reason, invalid_pickup_skill_invalid_reason | Pickup stop |
missing_delivery_invalid_reason, missing_delivery_location_name, invalid_delivery_address_invalid_reason, invalid_delivery_timewindow_invalid_reason, missing_delivery_skill_invalid_reason | Delivery stop |
conflicting_pickup_external_number_invalid_reason, conflicting_delivery_external_number_invalid_reason | External location number already used by another location |
invalid_group_invalid_reason | Groups |
invalid_custom_field_invalid_reason | Custom fields |
The field is omitted when there are no reasons — for example on drafts that weren’t created by the v3 import.
Get one draft
GET /v1/draft/orders/{orderDraftID} — 204 when not found.
Update a draft — and promote it
PUT /v1/draft/orders/{orderDraftID}
Send the draft back with the missing pieces filled in. When the draft becomes complete, it is automatically promoted to a real order: the order is created and priced, attached documents move over, and the draft is deleted. Complete means: customer, order type, and vehicle type resolvable (by ID or name), and a valid pickup + delivery pair with time windows.
If it’s still incomplete after your update, it stays a draft with the new data — nothing is lost.
Concurrent-edit protection via checksum. Echo back the checksum you read; if someone changed the draft in the meantime you get 409 Conflict. Set "checksum_override": true to overwrite regardless.
Delete a draft
DELETE /v1/draft/orders/{orderDraftID} — hard delete; 204 when not found.
Common gotchas
- Promotion is implicit. There is no separate “finalize” call — a successful
PUTof a complete draft is the promotion, and the draft ID stops existing afterwards. - The list is unpaginated. If your organization accumulates many drafts, work the queue down rather than letting it grow.
- snake_case JSON (v1 endpoint).
- Names can stand in for IDs. A draft resolves customer/order type/vehicle type by ID or by exact name match at promotion time.
Related documentation
- Orders Import — where drafts come from
- Orders API — draft booking — book a draft on a schedule interval
- Documents — attachments follow the draft into the promoted order