Create Order
Creates an order on the Stream system from a quote estimate.
Endpoint
POST /orders
Description
Creates an order on the Stream system. To send documents (commercial invoice, packing list, materials safety data sheet) with the order, submit the request as multipart/form-data instead of JSON — see Uploading documents.
Request Body
Required Fields
| Field | Type | Description |
|---|---|---|
order.quote_estimate_id | integer | ID of the quote estimate to create the order from |
order.purpose_of_shipment_id | integer | Purpose of shipment ID |
order.origin_address | object | Origin address details, or order.origin_address_id for an address you have used before |
order.destination_address | object | Destination address details, or order.destination_address_id for an address you have used before |
order.description_of_contents | string | Description of package contents; the waybill cannot be generated without it |
Optional Fields
| Field | Type | Description |
|---|---|---|
order.customer_reference | string | Your own reference for the order |
order.send_consignee_tracking_details | boolean | Email tracking updates to the consignee |
order.hs_codes | array | Array of HS code objects for customs |
order.broker_address | object | Broker address details |
order.importer_of_record_address | object | Importer of record address |
order.clearance_detail | object | Clearance details including invoice number |
order.commercial_invoice | file | Your commercial invoice, multipart/form-data only. Replaces the invoice Stream would otherwise generate |
order.packaging_list | file | Packing list, multipart/form-data only |
order.materials_safety_data_sheet | file | Materials safety data sheet for dangerous goods, multipart/form-data only |
Address Object Structure
{
"name": "My House",
"company": "Company Name",
"address_1": "5 Open Street",
"address_2": "Melrose Arch",
"city": "Johannesburg",
"province": "Gauteng",
"postal_code": "1610",
"country_id": 226,
"email": "example@stream.com",
"phone": "+27825547358",
"import_code": "GB000000000000",
"export_code": "12345678"
}
Pickup instructions are not part of the order; set them when you schedule the pickup.
HS Code Object Structure
{
"code": "100322",
"cost": "100",
"description": "networking equipment",
"quantity": 5,
"weight": 1.1,
"eccn": "12345",
"country_id": 5
}
Request Example
curl -X POST \
https://stream-orders-api-sandbox.herokuapp.com/client_api/v2/orders \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{
"order": {
"origin_address": {
"name": "John",
"company": "Tech Corp",
"address_1": "123 Tech Street",
"city": "Johannesburg",
"province": "Gauteng",
"postal_code": "2196",
"country_id": 226,
"email": "john@example.com",
"phone": "+27123456789",
"export_code": "12345678"
},
"destination_address": {
"name": "Jane Smith",
"company": "UK Business",
"address_1": "456 London Road",
"city": "London",
"province": "London",
"postal_code": "SW1A 2AA",
"country_id": 70,
"email": "jane@ukbusiness.com",
"phone": "+442012345678",
"import_code": "GB000000000000"
},
"purpose_of_shipment_id": 8,
"quote_estimate_id": 5,
"customer_reference": "REF001",
"description_of_contents": "Networking Equipment",
"hs_codes": [
{
"code": "100322",
"cost": "100",
"description": "networking equipment",
"quantity": 5,
"weight": 1.1,
"eccn": "12345",
"country_id": 5
}
],
"clearance_detail": {
"reason_for_shipment_id": 1,
"invoice_number": "INV001",
"purchase_order_number": "PO001"
}
}
}'
Uploading documents
To attach files, send the same request as multipart/form-data. Every field keeps the nesting of the JSON body (order[origin_address][name], order[hs_codes][][code]), and the files go in these fields:
| Field | Purpose |
|---|---|
order[commercial_invoice] | Your commercial invoice. Keep it under 2 MB |
order[packaging_list] | Packing list |
order[materials_safety_data_sheet] | Materials safety data sheet, for dangerous goods |
curl -X POST \
https://stream-orders-api-sandbox.herokuapp.com/client_api/v2/orders \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-F "order[quote_estimate_id]=5" \
-F "order[purpose_of_shipment_id]=8" \
-F "order[customer_reference]=REF001" \
-F "order[description_of_contents]=Networking Equipment" \
-F "order[origin_address][name]=John" \
-F "order[origin_address][company]=Tech Corp" \
-F "order[origin_address][address_1]=123 Tech Street" \
-F "order[origin_address][city]=Johannesburg" \
-F "order[origin_address][province]=Gauteng" \
-F "order[origin_address][postal_code]=2196" \
-F "order[origin_address][country_id]=226" \
-F "order[origin_address][email]=john@example.com" \
-F "order[origin_address][phone]=+27123456789" \
-F "order[origin_address][export_code]=12345678" \
-F "order[destination_address][name]=Jane Smith" \
-F "order[destination_address][company]=UK Business" \
-F "order[destination_address][address_1]=456 London Road" \
-F "order[destination_address][city]=London" \
-F "order[destination_address][province]=London" \
-F "order[destination_address][postal_code]=SW1A 2AA" \
-F "order[destination_address][country_id]=70" \
-F "order[destination_address][email]=jane@ukbusiness.com" \
-F "order[destination_address][phone]=+442012345678" \
-F "order[destination_address][import_code]=GB000000000000" \
-F "order[hs_codes][][code]=100322" \
-F "order[hs_codes][][description]=networking equipment" \
-F "order[hs_codes][][quantity]=5" \
-F "order[hs_codes][][weight]=1.1" \
-F "order[hs_codes][][cost]=100" \
-F "order[hs_codes][][country_id]=5" \
-F "order[clearance_detail][invoice_number]=INV001" \
-F "order[commercial_invoice]=@invoice.pdf;type=application/pdf" \
-F "order[packaging_list]=@packing-list.pdf;type=application/pdf"
How uploads behave:
- Your invoice replaces ours. With
commercial_invoicepresent, Stream does not generate a commercial invoice; your file is what goes to the carrier and customs. Without it, Stream generates one fromhs_codes. - HS codes. With an uploaded invoice,
hs_codesare optional for waybill generation. Without one they are required on DDP shipments, because Stream builds the invoice from them. Send them for any shipment that clears customs. - Upload happens at creation only. There is no endpoint to add documents to an existing order. If a document is missing when you call Create Waybill, the response is
422naming the missing item and the order moves toawaiting_additional_documentation. Send the file to your account manager and call Create Waybill again, or cancel and re-create the order with the file attached. - Hub orders. Documents attach once, to the leg that clears customs. On EU hub lanes the local leg needs no commercial invoice, so one upload covers the order.
Taxes and Duties
Placing an order estimates import VAT and duties automatically. There is no field for it and nothing to opt into: if the shipment clears customs on a DDP / EXW / FOB / FCA incoterm and has HS codes, Import VAT and Import Duties are added to the order's charges.
This applies even when the quote behind the order was freight-only. A quote requested without estimate_taxes_and_duties does not mean the shipment carries no import charges — only that the quote did not show them. To show a customer the landed cost before they commit, quote with estimate_taxes_and_duties: true.
The charges appear on Get Orders under invoice_data.line_items. See the Taxes and Duties guide for the full conditions and the cases that return nothing.
Success Response (201 Created)
{
"order": {
"id": 12345,
"assigned_admin": "admin@example.com",
"battery_declaration_link": "",
"broker_address": null,
"ccd_status": "ccd_not_required",
"commercial_invoice_link": "",
"company_id": 789,
"created_at": "2025/08/04 11:48:40 UTC",
"customer_reference": "CUST-REF-001",
"customs_clearance_document_link": "",
"date_delivered": null,
"description_of_contents": "Electronic Components",
"destination_address": {
"id": 54321,
"address_1": "456 London Road",
"address_2": null,
"address_3": null,
"city": "London",
"classification": "business",
"company": "UK Business",
"country": {
"id": 70,
"default_postal_code": null,
"dhl_export_code": "GB",
"dhl_import_code": "GB",
"dhl_tax_code": "GB",
"export_code_label": "EORI Number",
"import_code_label": "Import Code",
"iso_code_2": "GB",
"iso_code_3": "GBR",
"name": "United Kingdom",
"postal_code_required": true,
"tax_number_label": "VAT Number",
"taxes_and_duties_config": {
"id": 101,
"minimum_value_of_goods": 800.0,
"minimum_value_of_goods_currency_id": "GBP"
},
"vat_rate": 0.20
},
"country_id": 70,
"email": "jane@ukbusiness.com",
"import_code": "GB000000000000",
"latitude": 51.5074,
"longitude": -0.1278,
"name": "Jane Smith",
"phone": "+442012345678",
"postal_code": "SW1A 2AA",
"province": "London",
"summary": "United Kingdom",
"tax_number": null,
"time_zone_id": "Europe/London"
},
"draft_bill_of_lading_link": "",
"eei_eligible": true,
"eei_request_document_link": "",
"export_permit_link": "",
"final_bill_of_lading_link": "",
"importer_of_record_address": null,
"internal_transaction_number": "TXN987654321",
"invoice_data": null,
"invoice_number": null,
"materials_safety_data_sheet_link": "",
"measured_weight": null,
"origin_address": {
"id": 22222,
"address_1": "123 Tech Street",
"address_2": null,
"address_3": null,
"city": "Johannesburg",
"classification": "business",
"company": "Tech Corp",
"country": {
"id": 226,
"default_postal_code": "0000",
"dhl_export_code": "ZA",
"dhl_import_code": "ZA",
"dhl_tax_code": "ZA",
"export_code_label": "Export Number",
"import_code_label": "Import Code",
"iso_code_2": "ZA",
"iso_code_3": "ZAF",
"name": "South Africa",
"postal_code_required": true,
"tax_number_label": "VAT Number",
"taxes_and_duties_config": {
"id": 150,
"minimum_value_of_goods": 500.0,
"minimum_value_of_goods_currency_id": "USD"
},
"vat_rate": 0.15
},
"country_id": 226,
"email": "john@example.com",
"import_code": null,
"latitude": -26.2041,
"longitude": 28.0473,
"name": "John Doe",
"phone": "+27123456789",
"postal_code": "2196",
"province": "Gauteng",
"summary": "South Africa",
"tax_number": null,
"time_zone_id": "Africa/Johannesburg"
},
"packaging_list_link": "",
"pickup_date": "2024-03-20",
"pickup_instructions": "Please call 30 minutes before arrival",
"proof_of_delivery_link": "",
"purpose_of_shipment_id": 8,
"quote_id": 999888,
"reference_number": "SHIP-2024-001",
"scheduled_pickup": "",
"send_consignee_tracking_details": true,
"shipments": [
{
"shipping_service": "Priority International",
"waybill": null,
"waybill_document_link": "",
"tracking_link": null,
"status": "order_received"
}
],
"shippers_letter_of_instruction_link": "",
"status": "order_received",
"stream_packing_list_link": "",
"tracking_link": null,
"value_of_goods": 600.0,
"value_of_goods_currency": "ZAR",
"waybill": null,
"waybill_document_link": ""
}
}
Hub Shipments
If your quote_estimate_id comes from a hub quote (hub_transit: true), creating the order is identical — just pass the hub estimate's id. The resulting order spans two shipment legs, and the response's shipments array has two entries in route order (origin → hub first).
Hub lane is fixed at quote time. The
origin_address/destination_addressyou send here do not re-route a hub order — they're ignored for routing (onlyorigin_address.export_codeis used). To ship a different lane, request a new hub quote. See the Hub Shipments guide.
Error Responses
400 Bad Request
{
"success": false,
"error": "Invalid input, object invalid"
}
429 Rate Limit Exceeded
{
"success": false,
"error": "Too many requests (20/20 in 60 seconds)"
}
Important Notes
- Orders are created from existing quote estimates
- You must have a valid
quote_estimate_idfrom a previously created quote - All required address fields must be provided
shipmentslists every leg of the order in route order; a direct order has one entry- HS codes are required for DDP shipments unless you upload a commercial invoice, and recommended for any shipment that clears customs
- The order will initially have status "order_received"
- A waybill must be generated separately using the waybill endpoint