Creating Orders

Creating Orders Guide

This guide walks you through creating outbound orders using the Spreetail Channel Integration API.

Overview

Outbound orders represent customer orders that need to be fulfilled and shipped. When you create an order, it is validated, stored, and queued for processing by our fulfillment system.

Endpoint

POST /outbound

Full URL: https://api.spreetaileu.com/api/api/v1/outbound

Authentication

Requires Bearer token authentication. See the Authentication Guide for details.

Order Structure

A complete order includes:

  • Order Information: Reference number, dates, status, currency
  • Order Items: Products/SKUs with quantities and prices
  • Delivery Address: Shipping destination
  • Billing Address: Billing information

Required Fields

FieldTypeDescription
ReferenceNumberstringUnique order reference (per client)
ReceivedDatestring (ISO 8601)When the order was received
DispatchBystring (ISO 8601)Latest dispatch date/time
CurrencystringISO 4217 currency code (EUR, GBP, USD)
PaymentStatusstringPayment status (e.g., "PAID")
ChannelBuyerNamestringCustomer name
OrderItemsarrayAt least one item required
DeliveryAddressobjectComplete delivery address
BillingAddressobjectComplete billing address
ℹ️

Note: The Status field is automatically set to "Pending" when creating an order. You do not need to include it in your request, and any value you provide will be ignored.

Example: Complete Order

{
  "ReferenceNumber": "ORD-2025-001",
  "ReceivedDate": "2025-01-15T10:00:00Z",
  "DispatchBy": "2025-01-16T17:00:00Z",
  "Currency": "EUR",
  // Note: Status is automatically set to "Pending" - do not include
  "PaymentStatus": "PAID",
  "ChannelBuyerName": "John Doe",
  "PostalServiceCost": 5.99,
  "PostalServiceTaxRate": 19,
  "OrderItems": [
    {
      "SKU": "PROD-12345",
      "ItemTitle": "Premium Wireless Headphones",
      "Qty": 2,
      "PricePerUnit": 29.99,
      "TaxRate": 19
    },
    {
      "SKU": "PROD-67890",
      "ItemTitle": "USB-C Cable",
      "Qty": 1,
      "PricePerUnit": 9.99,
      "TaxRate": 19
    }
  ],
  "DeliveryAddress": {
    "FullName": "John Doe",
    "Company": "Acme Corp",
    "Address1": "123 Main Street",
    "Address2": "Suite 100",
    "Town": "Berlin",
    "Region": "Berlin",
    "PostCode": "10115",
    "Country": "Germany",
    "CountryCode": "DE",
    "PhoneNumber": "+49 30 12345678",
    "Email": "[email protected]"
  },
  "BillingAddress": {
    "FullName": "John Doe",
    "Company": "Acme Corp",
    "Address1": "123 Main Street",
    "Address2": "Suite 100",
    "Town": "Berlin",
    "Region": "Berlin",
    "PostCode": "10115",
    "Country": "Germany",
    "CountryCode": "DE",
    "PhoneNumber": "+49 30 12345678",
    "Email": "[email protected]"
  }
}

Code Examples

Python

import requests
from datetime import datetime, timedelta

def create_order(access_token, order_data):
    """Create an outbound order"""
    url = "https://api.spreetaileu.com/api/api/v1/outbound"
    headers = {
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "application/json"
    }
    
    response = requests.post(url, headers=headers, json=order_data)
    response.raise_for_status()
    return response.json()

# Example usage
order = {
    "ReferenceNumber": f"ORD-{datetime.now().strftime('%Y%m%d-%H%M%S')}",
    "ReceivedDate": datetime.utcnow().isoformat() + "Z",
    "DispatchBy": (datetime.utcnow() + timedelta(days=1)).isoformat() + "Z",
    "Currency": "EUR",
    # Note: Status is automatically set to "Pending" - do not include
    "PaymentStatus": "PAID",
    "ChannelBuyerName": "John Doe",
    "OrderItems": [{
        "SKU": "PROD-12345",
        "ItemTitle": "Premium Headphones",
        "Qty": 2,
        "PricePerUnit": 29.99
    }],
    "DeliveryAddress": {
        "FullName": "John Doe",
        "Address1": "123 Main Street",
        "Town": "Berlin",
        "PostCode": "10115",
        "Country": "Germany",
        "CountryCode": "DE"
    },
    "BillingAddress": {
        "FullName": "John Doe",
        "Address1": "123 Main Street",
        "Town": "Berlin",
        "PostCode": "10115",
        "Country": "Germany",
        "CountryCode": "DE"
    }
}

result = create_order(access_token, order)
print(f"Order created: {result}")

JavaScript/Node.js

async function createOrder(accessToken, orderData) {
  const url = 'https://api.spreetaileu.com/api/api/v1/outbound';
  
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(orderData)
  });
  
  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Order creation failed: ${error.error || response.statusText}`);
  }
  
  return await response.json();
}

// Example usage
const order = {
  ReferenceNumber: `ORD-${Date.now()}`,
  ReceivedDate: new Date().toISOString(),
  DispatchBy: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
  Currency: 'EUR',
  // Note: Status is automatically set to "Pending" - do not include
  PaymentStatus: 'PAID',
  ChannelBuyerName: 'John Doe',
  OrderItems: [{
    SKU: 'PROD-12345',
    ItemTitle: 'Premium Headphones',
    Qty: 2,
    PricePerUnit: 29.99
  }],
  DeliveryAddress: {
    FullName: 'John Doe',
    Address1: '123 Main Street',
    Town: 'Berlin',
    PostCode: '10115',
    Country: 'Germany',
    CountryCode: 'DE'
  },
  BillingAddress: {
    FullName: 'John Doe',
    Address1: '123 Main Street',
    Town: 'Berlin',
    PostCode: '10115',
    Country: 'Germany',
    CountryCode: 'DE'
  }
};

createOrder(accessToken, order)
  .then(result => console.log('Order created:', result))
  .catch(error => console.error('Error:', error));

Response

Success Response (200)

{
  "success": true,
  "data": {
    "message": "Order created successfully",
    "order_id": "order-abc-123",
    "reference_number": "ORD-2025-001"
  }
}

Error Responses

400 Bad Request - Validation error:

{
  "success": false,
  "error": "ReferenceNumber is required"
}

401 Unauthorized - Invalid or expired token:

{
  "success": false,
  "error": "Unauthorized"
}

409 Conflict - Duplicate reference number:

{
  "success": false,
  "error": "Order with ReferenceNumber 'ORD-2025-001' already exists"
}

Important Notes

Reference Number Uniqueness

  • Reference numbers must be unique per client
  • If you submit the same reference number twice, you'll receive a 409 Conflict error
  • Use a consistent format (e.g., ORD-YYYYMMDD-####)

Currency Codes

Supported ISO 4217 currency codes:

  • EUR - Euro
  • GBP - British Pound
  • USD - US Dollar

Date Formats

All dates must be in ISO 8601 format with UTC timezone:

  • Format: YYYY-MM-DDTHH:mm:ssZ
  • Example: 2025-01-15T10:00:00Z

Address Requirements

Both DeliveryAddress and BillingAddress require:

  • FullName
  • Address1
  • Town
  • PostCode
  • Country or CountryCode

Order Items

  • At least one item is required
  • Each item must have: SKU, ItemTitle, Qty, PricePerUnit
  • Quantities must be positive integers

Best Practices

  1. Generate Unique Reference Numbers: Use timestamps or UUIDs to ensure uniqueness
  2. Validate Before Sending: Validate all required fields and formats before API calls
  3. Handle Errors Gracefully: Implement retry logic for transient errors
  4. Store Order IDs: Save the returned order_id for future reference
  5. Monitor Order Status: Use /order/{order_id} to check order status after creation

Next Steps

After creating an order:

  1. Check Order Status: Use GET /order/{order_id} to verify the order was processed
  2. Handle Errors: Implement error handling for validation failures
  3. Track Shipments: Monitor order status for dispatch and tracking updates

Related Endpoints

  • GET /order/{order_id} - Retrieve order details
  • POST /order/{order_id}/cancel - Cancel an order
  • GET /inventory - Check inventory before creating orders