Skip to main content
An Order represents the physical fulfillment event - the point at which a gift becomes a shipment. The Order is the primary integration object for Direct Fulfillment: you create it via a single call to POST /v3/orders with the recipient and variant details, then track its progress through the lifecycle. Orders are also generated automatically by Snappy when a recipient claims their gift in the Triggered Gifting model - those orders are retrievable, listable, and cancellable through the same V3 Orders API.
Want to understand how Orders fit into the bigger picture? Check out the Core Concepts & Data Models page.
The V3 Orders API exposes Orders as first-class resources with their own lifecycle, line items, fulfillments, and tracking - independent of the Gift entity. You no longer need to retrieve orders through their parent Gift.

The Order Object


Order status

Fulfillment status

Aggregated across all line items.

Line items

Fulfillments

A Fulfillment represents a shipment containing one or more line items. An Order can have multiple Fulfillments (e.g. split shipments), and a Fulfillment can cover multiple line items (e.g. consolidated shipping). This is a many-to-many relationship between line items and fulfillments.

Delivery statuses

Use Webhooks to track delivery status changes in real time rather than polling. See Webhook Event Types.

Recipient

Shipping address

Cancellation details


Key Concepts & Business Rules

Idempotency on order placement

Every POST /v3/orders request must include an idempotencyKey (1-120 characters). If a request with the same key has already succeeded for this Company, the original order is returned - no duplicate is created. Use stable, caller-generated keys (e.g. your internal order ID). See Duplicate Detection for the full idempotency reference.

Variants are required - not Products

When placing an order, you must always specify the variantId, not the productId. Every Product has at least one Variant, even if it has no variations. See Products & Variants Overview.

Tags vs metadata

Two separate fields with different purposes:
  • tags - array of strings for grouping and filtering orders in reports (e.g. ["q4-campaign", "vip"]).
  • metadata - key-value object for arbitrary passthrough data (e.g. {"externalRecipientId": "crm-user-987"}). Up to 50 pairs, keys up to 40 chars, values up to 500 chars.
Use tags for categorization; use metadata for data you want to round-trip.

Status vs fulfillment status

The Order has two distinct status fields that capture different concerns:
  • status tracks the commercial lifecycle: activecompleted, or activecancelled / refunded
  • fulfillmentStatus tracks the physical lifecycle aggregated across line items: unfulfilledfulfilled (or cancelled)
Per-shipment carrier progress lives inside fulfillments[].status.

Cancellation rules

Orders can only be cancelled before they are picked up by the fulfillment partner. Once an Order is in transit, cancellation returns 422. The cancellationReason enum currently only supports customer_requested; additional reasons may be added in future releases.

Address validation reduces fulfillment failures

Invalid or incomplete shipping addresses are a common cause of fulfillment failures. We recommend validating the recipient’s address via POST /orders/addresses/validate before calling POST /v3/orders, especially when addresses are entered by end users in your platform UI.

Billing is triggered at order creation

The Billing Method (referenced via billingMethodId) is debited when an Order is successfully placed. If the Billing Method has insufficient funds at the time of the request, the order will not be processed. See Billing Methods Overview to check remaining balance before placing high-value orders.

Pagination

The V3 list endpoint uses page-number pagination (page[number] and page[size], max 300, default 100). Responses include a top-level links object with first, next, and prev URLs. See Request & Response Standards for the full V3 pagination contract.

Account scoping

Pass the optional Snappy-Account-Id header to scope queries to a specific Account. For POST /v3/orders, accountId may alternatively be supplied in the request body - the header takes precedence when both are provided.

Permissions

The V3 Orders endpoints require different scopes depending on the operation: PII fields (recipient name, tracking info) are masked under orders:read:masked and returned in full under orders:read:unmasked.

How to Work with Orders

Place an order (Direct Fulfillment)
Creates a new Order for a single variant on behalf of a recipient. Returns a minimal create result with the Order ID, initial status (active), and a tracking link. Required: billingMethodId, variantId, recipient, shippingAddress, idempotencyKey. Optional: accountId, tags, metadata. List orders
Returns a paginated list of Orders matching the supplied filters. Filter by status (active, cancelled), idempotencyKey (comma-separated array), or createdAt range. Sort by createdAt (newest first by default). Get an order by ID
Retrieves a single Order with full detail - line items, recipient, shipping address, fulfillments, and tracking info. Cancel an order
Cancels an Order that has not yet been fulfilled. Returns the Order in its post-cancellation state with status: "cancelled" and a populated cancellationDetails object. Returns 422 if the Order has already been picked up by the fulfillment partner.
Last modified on June 30, 2026