API

Overview

Order Supliful products from your own systems.

The Supliful public API lets a partner list the products a connection exposes and place orders against them, authenticated with an API key issued from the store list in the Supliful app.

Supliful fulfills every order you place: we pack it, ship it to your customer, and report each step back to you through webhooks.

Start here

  • API Reference — every endpoint, with request and response schemas.
  • Errors — every problem type the API returns, and what to do about each one.
  • Webhooks — the events Supliful sends you, how to verify them, and a page that fires a real one at your endpoint.
  • Order lifecycle — drive a test order from created to completed, and watch the webhooks follow it.

If you use a coding agent for your integration, install the agent skill. It provides the endpoint reference, webhook verification, error types and OpenAPI spec, so the agent works from the documented contract.

Authentication

Send your key as Authorization: Bearer <key>; x-api-key: <key> is accepted too. GET /v1/me has no side effects and returns the connection a key acts as, which makes it the quickest way to check a credential.

Products

GET /v1/products lists what a merchant has exposed to your connection, oldest first. Page with limit (50 by default, 100 at most) and the opaque nextCursor from the previous page — do not parse a cursor, and do not page by offset: the merchant may publish while you sync, and the cursor is what keeps a new product from displacing rows you have not read yet.

A product the merchant exposes while you are paging may land on a later page, or not until your next pass. product.published tells you about it straight away.

sku is a filter, not a lookup. Nothing stops a merchant giving two products the same SKU, so ?sku= returns a list that may legitimately hold more than one product — do not assume data[0]. To fetch exactly one product, use GET /v1/products/{id} with the UUID.

A product whose status is discontinued still resolves, so orders already placed against it stay readable, but a new order naming it is refused with 422 validation-failed. Stop offering it.

Ordering

POST /v1/orders takes a shipping address and a list of { productId, quantity } lines, where each productId comes from GET /v1/products. A product the merchant has not exposed to your connection is refused exactly like one that does not exist.

Send an Idempotency-Key header, or an externalOrderId — your own identifier for the order, which is used as the key when the header is absent. Retrying a request that already succeeded returns that order, as it stands now, with 200 rather than creating a second one. A request carrying neither is refused with 400, because there would be no safe way to retry it.

A key belongs to the request it was first sent with. Reusing it for a different request is refused with idempotency-key-reused rather than answered with the first order. An externalOrderId is unique per connection, so a second order claiming one is refused with order-already-exists, even under a new key.

Prices are the merchant's, not yours: an order records what Supliful charges the merchant, and your own retail pricing never reaches us. Shipping is priced when the order is routed, so the order you get back carries no shipping cost. Carrier tracking mail goes to the merchant's account email. To keep your buyer informed, use the trackingUrl on each shipment, returned by GET /v1/orders/{orderId} and the order.shipmentCreated webhook. It is null until the carrier has issued tracking.

On this page