Fulfill orders

Pull orders with the full ship-to address, mark them shipped, attach tracking and notify the marketplace.

The order loop for a WMS/ERP integration (requires orders:read + orders:write):

Each order carries number, the number the merchant sees on the channel (Shopify "#1011" → "1011"): search and show orders by it. When the channel provides it, the order also has its money breakdown: subtotal, shipping, discount, tax, tax_remitted_by (marketplace when the channel collects and pays the tax) and the channel's total, the same numbers as the orders export. Book shipping, discounts and tax from these; when they're null the channel gave no breakdown and total is the sum of the lines.

1. Get orders as they arrive

Subscribe to order.created, or poll:

curl "https://api.nembol.com/rest/v1/orders?limit=50" \
  -H "Authorization: Bearer $NEMBOL_API_KEY"

Every order is normalized to one shape regardless of channel: status, fulfillment_status, lines[], tracking, and buyer including the ship-to address (buyer.address).

2. Ship it

curl -X POST https://api.nembol.com/rest/v1/orders/{id}/fulfillment \
  -H "Authorization: Bearer $NEMBOL_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: ship-EBAY-12345" \
  -d '{
    "mark_shipped": true,
    "tracking": {"number": "1Z999...", "carrier": "UPS", "url": "https://..."}
  }'

With tracking present, Nembol also notifies the source marketplace by default (eBay, Etsy, Shopify, WooCommerce, Amazon, TikTok Shop, OnBuy, Square, Squarespace), and the buyer gets the channel's own shipping notification. Disable with "notify_channel": false.

Stock and cancellations

When an order is canceled on its channel before shipping and its sale had taken the units out of Nembol's stock, Nembol puts them back, once per order line, and sends the new quantity to every channel the product is on (the same way a sale does). You get inventory.updated with data.source: "order", data.reason: "order_canceled", data.channel, data.order_id_on_channel, data.variant_id, data.sku and a positive data.quantity_change.

No restock happens when:

  • the sale didn't change Nembol's stock: "quantity from orders" (sync.quantity_from_orders) was off for that account, the order came from the first import of past orders, or it was fulfilled by Amazon (FBA);
  • the order had already shipped or been delivered;
  • the channel's own quantity changes sync into Nembol (sync.quantity_from_channel_edits on: Shopify, WooCommerce, Amazon): the channel's restock arrives through that sync, and adding it again would count the units twice;
  • the order is only refunded: a refund doesn't say the goods came back. Adjust stock yourself (POST /inventory/batch) when a return arrives.

Orders received before 2026-10-17 aren't restocked automatically.

Gotchas

  • One order per channel order. An order with several lines is one order (all its lines, the full total); the fulfillment ships all its lines.
  • No tracking, no notification. mark_shipped alone updates Nembol only. Send the tracking (now or later) to notify the marketplace.
  • A tracking can't be corrected through Nembol once the marketplace has one: the new number is saved in Nembol and the answer says channel_already_notified. Fix it on the marketplace.
  • Resending is safe. The same tracking again sends nothing (one email to the buyer, ever): the answer says attempted: false, already_notified_same_tracking. Fields you leave out keep their value.
  • url must be an http(s) URL, or the call answers 422.
  • Tracking fields over their limit are refused (number and carrier 64, url 512 characters), never shortened.
  • Cancellations made on the channel arrive within 10 minutes (status canceled, order.status_changed).
  • Marketplace notification is once-per-order, hard-idempotent. Retrying the call never notifies (or emails) the buyer twice.
  • Terminal orders refuse fulfillment: canceled/refunded orders return 422 order_not_fulfillable.
  • Buyer data is PII. It sits behind orders:read; process it lawfully and don't store more than you need.
  • channel_notification in the response tells you exactly what happened: {attempted, delivered, error}.

Last updated on October 17, 2026

Need help?

Email us and a human replies, usually within one business day.

On this page