Skip to main content

Orders

This guide covers the complete order lifecycle: creating orders with buyer and item references, updating order state and properties, and querying with rich filters including JSONB property searches.
All endpoints require header-based auth: X-Business-ID and X-API-Key.

Authentication

Include these headers in every request:
  • X-Business-ID: Your business identifier
  • X-API-Key: Your API key

Overview: Orders, Buyers, and Items

Orders in Polinate connect buyers with items:
  1. Create Items with variants (SKU, price, dimensions, etc.)
  2. Create Buyers representing your customers/partners
  3. Create Orders that reference the buyer and specific item variants
Each order contains:
  • A reference to the buyer (partnershipId, membershipId)
  • Order-level metadata (delivery address, dates, totals, custom properties)
  • Order items that reference specific item variants with quantity and pricing
The API returns full context so you always know which buyer and which items/variants are in each order.

List Orders

Endpoint: GET /api/v1/orders Supports pagination, time-window filters, state filters, and property-based queries: Pagination:
  • page (number, default 1)
  • limit (number, max 100, default 20)
Time-window filters:
  • createdSince (ISO datetime): orders with createdAt > createdSince
  • updatedSince (ISO datetime): orders with updatedAt > updatedSince
  • modifiedSince (ISO datetime): orders where (createdAt > ts OR updatedAt > ts)
    • Mutual exclusivity: modifiedSince cannot be combined with createdSince or updatedSince. You may combine createdSince and updatedSince together.
State filters:
  • phase (enum): High-level order state
  • status (enum): Physical fulfillment/movement state
Property-based queries:
  • propertyPath (string): Dot-notation path to a property (e.g., sage200Evo.salesOrderNo)
  • propertyValue (string): Filter orders where the property equals this value
  • propertyExists (boolean): Filter by property existence (true) or absence (false)
    • Mutual exclusivity: propertyValue and propertyExists cannot be used together
    • Both require propertyPath to be specified
Results are scoped to your business and exclude soft-deleted orders.

Understanding Phase vs Status

Orders have two complementary state dimensions: Phase represents the high-level lifecycle of an order:
  • DRAFT: Order is being prepared
  • PENDING: Order is awaiting acceptance/confirmation
  • ACTIVE: Order is confirmed and in progress
  • ARCHIVED: Order is complete and archived
  • REJECTED: Order was declined
  • CANCELLED: Order was cancelled
  • DELETED: Order was soft-deleted
Status represents the physical movement/fulfillment state:
  • UNASSIGNED: Not yet assigned for processing
  • ACCEPTED: Accepted and ready for fulfillment
  • PREPARING: Being prepared for shipment
  • SHIPPED: In transit to destination
  • DELIVERED: Successfully delivered
  • CANCELLED: Fulfillment cancelled
  • RETURNED: Returned by recipient
Phase and status work together. For example, an order can have phase: CANCELLED but status: SHIPPED if it was cancelled after already being dispatched.

Example Queries

Best practices:
  • Use modifiedSince for catch-up syncs: it returns all orders created or updated after the given timestamp
  • Use propertyExists=false to find orders that need processing (e.g., not yet synced to your ERP)
  • Combine state filters with property filters for powerful queries

Response Structure

Each order includes buyer context and full item details:
Key fields explained:
  • partnershipId: Links to the buyer (see Buyers API)
  • orderItems[].itemListEntry.itemVariantId: The specific variant ordered
  • orderItems[].itemListEntry.itemVariant.itemId: The parent item
  • properties: Flexible JSONB field for custom data (see Properties section below)

Get Individual Order

Endpoint: GET /api/v1/orders/{id} Fetch a single order by ID with all buyer and item context:
Returns the same structure as the list endpoint, but for a single order.

Update an Order

Endpoint: PATCH /api/v1/orders/{id} Update order state, metadata, and properties. The API supports partial updates with automatic property merging.
Returns: Full updated order with all items (same structure as GET)

Ingest an Order (Idempotent)

Endpoint: POST /api/v1/orders Use an Idempotency-Key header so retries don’t create duplicates. The expected key is:

Working with Properties

The properties field is a flexible JSONB column that lets you store custom data with orders. This is perfect for:
  • External system references (ERP order numbers, tracking IDs)
  • Integration metadata (sync status, timestamps)
  • Custom business logic data

Deep Merge Behavior

When you update properties via PATCH, the API performs a deep merge (upsert behavior):
  • Top-level keys are merged independently
  • Nested objects within the same key are merged
  • New keys are added without affecting existing keys
  • Null values are stored as-is (use null to explicitly set a property to null)

Property Merge Examples

Initial order properties:
PATCH request:
Resulting properties (merged):
Nested merge example: If you then PATCH:
The sage200Evo object is merged (not replaced):

Querying by Properties

Use property filters to find orders based on custom data: Find orders synced to Sage 200:
Find orders NOT yet synced to Sage 200:
Find order with specific external ID:
Property filter limitations:
  • propertyValue and propertyExists are mutually exclusive
  • Both require propertyPath to be specified
  • Property paths use dot notation (e.g., system.subfield.value)

Common Integration Pattern

A typical ERP/external system integration workflow:
  1. Fetch unsynced orders:
  2. Process in your system (create sales order, get order number)
  3. Update order with external reference:
  4. Later, add more external data (merges automatically):

Pagination & Rate Limits

  • Pagination is standard page + limit (max 100). Default: page 1, limit 20.
  • Rate limits return HTTP 429 with a Retry-After header (seconds). Back off and retry after that interval.

Errors

  • 400: Validation errors (e.g., invalid timestamps, mutually-exclusive filters, missing propertyPath)
  • 401: Missing or invalid authentication headers
  • 404: Order not found or doesn’t belong to your business
  • 429: Too many requests — honor Retry-After
  • 500: Unexpected server error

Best Practices

  • Incremental syncs: Use modifiedSince to fetch only changed orders
  • Property filters: Use propertyExists=false to find orders needing processing
  • Idempotency: Always use idempotency keys for POST operations
  • Property structure: Namespace your properties by system (e.g., sage200Evo, unleashed, myErp)
  • Timestamps: Store sync timestamps in properties for debugging and monitoring
  • Error handling: Orders you don’t own return 404 (not 403) to prevent information leakage