Shipping & Fulfillment
Overview
The Cart API organizes items into shipments, with each shipment having a fulfillment type (how it’s delivered to the buyer). A single cart can have multiple shipments, each with a different fulfillment type — enabling complex checkout experiences across all merchant platforms with a consistent API.
What are Shipments?
Shipments represent groups of items that fulfill together. Common shipment scenarios:
- Items from different warehouse locations
- Products from multiple vendors
- Mixed fulfillment types (shipping, pickup, scheduled delivery)
- Items with different delivery requirements
Cart structure with shipments
{"cart_id": "1d6af01a-08ec-59f7-8dc6-abd6f6eeed25","line_items": [{"line_item_id": "0ef341c8-4a05-ce7c-4530-d100b60cbc2a","sku": "WIDGET-001","quantity": 1,"price": {"currency": "USD","value": 22.0,"number": 2200,"symbol": "$"},"line_price": {"currency": "USD","value": 22.0,"number": 2200,"symbol": "$"},"msrp": {"currency": "USD","value": 26.4,"number": 2640,"symbol": "$"},"image": {"url": "https://staging.luma.gift/widget-001.jpg","alt": "WIDGET-001","type": "default"}},{"line_item_id": "bb175284-a800-5a33-96ac-a642cd3952ce","sku": "GADGET-002","quantity": 2,"price": {"currency": "USD","value": 22.0,"number": 2200,"symbol": "$"},"line_price": {"currency": "USD","value": 44.0,"number": 4400,"symbol": "$"},"msrp": {"currency": "USD","value": 26.4,"number": 2640,"symbol": "$"},"image": {"url": "https://staging.luma.gift/gadget-002.jpg","alt": "GADGET-002","type": "default"}}],"shipments": [{"shipment_id": "f33fc75a-2694-230f-b615-d358eb4a6543","line_item_ids": ["0ef341c8-4a05-ce7c-4530-d100b60cbc2a","bb175284-a800-5a33-96ac-a642cd3952ce"],"fulfillment_type": {"id": "SHIP_TO_ADDRESS","name": "Ship to Address"},"fulfillment_type_options": [{"id": "SHIP_TO_ADDRESS","name": "Ship to Address"},{"id": "SCHEDULED_DELIVERY","name": "Scheduled Delivery"}],"shipping_method_options": [{"id": "standard","description": "Standard Ground (5-7 days)","price": {"currency": "USD","value": 9.99,"number": 999,"symbol": "$"}}],"shipping_method": {"id": "standard","description": "Standard Ground (5-7 days)","price": {"currency": "USD","value": 9.99,"number": 999,"symbol": "$"}}}]}
Line item assignment
The line_item_ids array maps items to their respective shipments:
Automatic Shipment Assignment
When items are added to the cart via Add Line Item, Firmly automatically organizes them into shipments — clients do not assign items to shipments manually:
- Groups compatible items — items with similar fulfillment requirements are placed in the same shipment.
- Creates new shipments — items with different fulfillment requirements get separate shipments.
- Inherits options — each new shipment is initialized with the fulfillment-type and shipping-method options available for its items.
Example: Mixed Cart
Adding a large sofa (requires scheduled delivery) to a cart that already contains small accessories (standard shipping) yields two shipments:
{"shipments": [{"shipment_id": "c48f90db-5f40-56e7-01fa-5d7e6bc142e0","line_item_ids": ["4ad19ada-4361-e123-c076-2312af81fd06"],"fulfillment_type": { "id": "SCHEDULED_DELIVERY" }},{"shipment_id": "3f1685b5-e89c-2801-4ddf-ec367b5f0951","line_item_ids": ["cf13aa70-f5d0-9302-6ab1-159b0f56a8dd", "b1de78d0-6be8-8214-a2d1-4188503a59c2"],"fulfillment_type": { "id": "SHIP_TO_ADDRESS" }}]}
Clients can then call Set Fulfillment Type or Set Shipping Method per shipment to refine the selection.
Fulfillment Types
Each shipment has a fulfillment type that determines how the items will be delivered. Available fulfillment types vary by merchant — always check the fulfillment_type_options array on the shipment to see what’s currently available.
SHIP_TO_ADDRESS
Standard shipping to a buyer-provided address. The most common fulfillment type.
| Aspect | Detail |
|---|---|
| Model | Traditional e-commerce shipping |
| Methods | Multiple shipping methods available (standard, express, overnight) |
| Cost | Calculated based on destination and method |
| Default | Yes — used if no other type is specified |
| Use cases | Most retail products, items not requiring special handling, residential or commercial addresses |
SCHEDULED_DELIVERY
Date- and time-specific delivery for items requiring coordination with the buyer.
| Aspect | Detail |
|---|---|
| Model | Buyer selects specific delivery date + optional time slot |
| Service level | Higher-touch — often includes white glove or installation |
| Use cases | Furniture, large appliances, items requiring installation, perishable goods |
PICKUP_IN_STORE
Buyer picks up items at a physical store location.
| Aspect | Detail |
|---|---|
| Model | Buyer selects pickup location and optional time slot |
| Cost | No shipping cost |
| Speed | Often same-day fulfillment |
| Use cases | Buy online, pick up in store (BOPIS); urgent orders; in-store inventory |
Setting the fulfillment type
curl -X POST 'https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/shipments/fulfillment-type' \-H 'x-firmly-authorization: YOUR_ACCESS_TOKEN' \-H 'Content-Type: application/json' \-d '{"shipment_id": "a2dfd593-7d99-e0ff-c7a4-1fe2f8cf208c","fulfillment_type": "SCHEDULED_DELIVERY"}'
Fields cleared on transition
When changing fulfillment types, related fields are automatically reset:
| From → To | Fields Cleared | New Requirements |
|---|---|---|
Any → SHIP_TO_ADDRESS |
selected_location, selected_date, selected_time_slot |
Shipping method selection |
Any → SCHEDULED_DELIVERY |
selected_location, selected_date, selected_time_slot |
Date/time selection |
Any → PICKUP_IN_STORE |
selected_date, selected_time_slot |
Store location selection |
Shipping methods (for SHIP_TO_ADDRESS)
Each shipment provides its own shipping options:
{"shipment_id": "a2dfd593-7d99-e0ff-c7a4-1fe2f8cf208c","shipping_method_options": [{"id": "standard","description": "Standard Ground (5-7 days)","price": { "value": 9.99, "currency": "USD", "number": 999, "symbol": "$" }},{"id": "express","description": "Express (2 days)","price": { "value": 29.99, "currency": "USD", "number": 2999, "symbol": "$" }}]}
Typical flow
Get the cart, inspect shipments[]
After adding items + setting a shipping address, cart.shipments[] is populated. Each shipment has its own shipment_id and fulfillment_type_options.
For each shipment, pick a fulfillment type
Check fulfillment_type_options. If you want a non-default type, call POST /cart/shipments/fulfillment-type per shipment.
Configure the chosen type
-
SHIP_TO_ADDRESS → set shipping method via
POST /cart/shipment/methods -
SCHEDULED_DELIVERY → pick a delivery date + time slot
-
PICKUP_IN_STORE → set pickup location (only when the merchant lists it in
fulfillment_type_options)
Place the order
With all shipments configured, call place-order. Firmly submits each shipment to the merchant per its fulfillment type.
Related
- Cart Lifecycle — cart states and what operations work in each
- Set Fulfillment Type — endpoint reference
- Set Shipping Method — endpoint reference
- Get Availability — endpoint reference (note: merchant-conditional)
- Shipment Configuration overview — all shipment endpoints