Create Order Export
POST {{BASE_HABITAT_URL}}/api/v3/orders/export
Required scope: reports:read
Start an asynchronous orders export using the same filters and search as Get Orders.
Use this flow for large exports instead of the legacy synchronous GET /v3/orders?format= request.
Recommended workflow
Section titled “Recommended workflow”-
POST
/v3/orders/export— enqueue the export job. -
GET
/v3/orders/export/:exportId— poll untilstatusisready(or listen for websocket eventorders-export:updateon roomorder-export:{exportId}). -
GET
/v3/orders/export/:exportId/download— download the file using thedownload_urlfrom step 2, or call this endpoint directly with your bearer token.
When the export completes, First also emails a download link to the requesting user’s account email (if available).
Authentication
Section titled “Authentication”Requires admin, partner, or vendor role.
Request body
Section titled “Request body”| Field | Required | Description |
|---|---|---|
format |
Yes | One of csv, json, or xlsx. |
filters |
No | Same shape as filters on Get Orders (territories, status, date range, provider, partner, order source, runner, merchant, etc.). |
search |
No | Free-text search across order fields. |
since |
No | ISO8601 date — only orders created after this time. |
active |
No | When true, limits to active orders. |
sorting |
No | { "id": "created_at", "desc": true } |
global |
No | When true, exports across all operators. Restricted to master root operator users. |
Response
Section titled “Response”{ "type": "success", "export_id": "93d85472-021c-4e77-aedf-ad0e1b06dd0a", "status": "queued"}Save export_id as {{ORDER_EXPORT_ID}} for the follow-up requests.
Export statuses
Section titled “Export statuses”| Status | Meaning |
|---|---|
queued |
Accepted and waiting to start. |
processing |
Rows are being fetched and written. Check progress_pct. |
ready |
File is available. Poll GET export for download_url. |
failed |
Export failed — see error. |
expired |
Export file TTL elapsed (24 hours). |
-
Download links include a short-lived
tokenquery param (15 minutes). -
Export files are retained for 24 hours after completion.
-
Only the user who created the export can poll its status.
Request body
Section titled “Request body”{ "search": "", "filters": { "territories": [], "status": ["completed"], "provider": [], "partner_name": [], "order_source": [] }, "format": "csv"}Examples
Section titled “Examples”curl --request POST '${BASE_HABITAT_URL}/api/v3/orders/export' \ --header 'Content-Type: application/json' \ --data '{ "search": "", "filters": { "territories": [], "status": ["completed"], "provider": [], "partner_name": [], "order_source": [] }, "format": "csv"}'const response = await fetch("${BASE_HABITAT_URL}/api/v3/orders/export", { "method": "POST", "headers": { "Content-Type": "application/json" }, "body": "{\n \"search\": \"\",\n \"filters\": {\n \"territories\": [],\n \"status\": [\"completed\"],\n \"provider\": [],\n \"partner_name\": [],\n \"order_source\": []\n },\n \"format\": \"csv\"\n}"})const data = await response.json()import requests
response = requests.request( "POST", "${BASE_HABITAT_URL}/api/v3/orders/export", headers={ 'Content-Type': 'application/json'}, data="{\n \"search\": \"\",\n \"filters\": {\n \"territories\": [],\n \"status\": [\"completed\"],\n \"provider\": [],\n \"partner_name\": [],\n \"order_source\": []\n },\n \"format\": \"csv\"\n}",)response.raise_for_status()
