Register a fulfillment service
POST /fulfillment_services
location_id. Manage with GET /fulfillment_services,
PUT /fulfillment_services/{id}, DELETE /fulfillment_services/{id}.
supplier_id is the routing key. Any paid order line whose product (or variant) is tagged
with this same supplier_id is automatically assigned to your service’s location and submitted to
you as a FulfillmentOrder. Set it at registration (or later via PUT); the merchant tags their
products with the matching value. Omit it and your service receives only lines a merchant manually
moves to your location.Pull assigned work
GET /assigned_fulfillment_orders?assignment_status=fulfillment_requested&limit=50&cursor=…
assignment_status ∈ fulfillment_requested · cancellation_requested · fulfillment_accepted ·
fulfillment_unsubmitted. Only FOs assigned to your own location are returned.
Per line item,
product_title, image_url, option1..3 and option_names are joined from
product.product + product.product_variant so a 3PL can source/purchase without a second
API call. option_names labels what option1..3 hold (e.g. ["Color","Size"], positionally
aligned — option_names[0] names option1) so you don’t have to guess which column is which.
title / sku remain the order-time snapshot (never mutated after the order was
placed); the enrichment fields reflect the CURRENT product state (rename-safe on your side).At the FO top level, merchant_id and store_id let a supplier receiving orders from more
than one merchant demux inbound FOs per tenant. Per-merchant integrations can ignore both — they
are additive to the previous shape.GET /fulfillment_orders/{id} returns a single FO. The supported_actions array tells you exactly
what’s allowed in the current state.
Sandbox: create a test order
POST /test_orders (no body)
Spins up a sandbox assigned FulfillmentOrder against your own location so you can exercise the
whole loop without a real order or payment — no merchant order is created.
TEST-SKU-001 line at request_status: submitted — pull it like any other
FO (above), then accept and ship it. Call again any time for a fresh test order.
Clean up when you’re done. DELETE /test_orders removes every sandbox order you created
(and their fulfillments) in one call. Real orders are never touched.
Accept
POST /fulfillment_orders/{id}/fulfillment_request/accept
request_status: accepted, status: in_progress. You can now create fulfillments.
Reject
POST /fulfillment_orders/{id}/fulfillment_request/reject
status: open). Valid reason values:
incorrect_address · incorrect_product_info · ineligible_product ·
international_shipping_unavailable · invalid_contact_information · invalid_sku ·
inventory_out_of_stock · merchant_blocked_or_suspended · missing_customs_info ·
order_too_large · package_preference_not_set · payment_declined ·
undeliverable_destination · other.
Cancellation handshake
If a merchant requests cancellation of an accepted FO, you receive a{"kind":"CANCELLATION_REQUEST"} callback and the FO appears under
assignment_status=cancellation_requested. Respond with:
POST /fulfillment_orders/{id}/cancellation_request/accept→ FOcancelled.POST /fulfillment_orders/{id}/cancellation_request/reject→ FO returns toin_progress.