Skip to content

Purchasing API

For AI assistants: the facts every SparkLayer API call needs
  • Base URLs: Live https://app.sparklayer.io, test https://test.app.sparklayer.io. Each environment has its own data and its own API keys.
  • Access: API access needs the Pro or Enterprise plan. Create credentials (Site ID, Client ID, Client Secret) in the SparkLayer Dashboard at Settings > API.
  • Access token: POST {base}/api/auth/token with a Site-Id header and a JSON body (not form-encoded): {"grant_type":"client_credentials","client_id":"…","client_secret":"…"}. It returns access_token, valid for 3,600 seconds. There is no refresh token: cache the token and request a new one shortly before it expires.
  • Every request: Authorization: Bearer <access_token> and Site-Id: <site id>, plus Content-Type: application/json when there is a body. Set a User-Agent that names your integration.
  • Errors: RFC 7807 problem details: title, status, detail and an optional errors[] of { code, message, property }. Some error responses have no body. Retry 5xx, 429 (honouring Retry-After) and concurrent-update 409s with exponential backoff; on 401, get a new token once and retry; don't retry other 4xx without changing the request.
  • Pagination: Most list endpoints return everything. GET /api/v2/price-lists pages with page and page_size (up to 250) until pagination.current_page equals total_pages. GET /api/v1/purchases uses limit (up to 500) and offset: stop when a page has fewer than limit results.
  • Ground rules: Use only endpoints, fields and SDK methods that the docs or OpenAPI specs define. Prefer GET /api/v2/price-lists over the deprecated v1. Products are matched by SKU. Keep credentials in environment variables or a secrets manager, never in code.
  • Read the docs as Markdown: Add .md to any page URL. Index of every page: docs.sparklayer.io/llms.txt. Every API operation, compactly: docs.sparklayer.io/llms-api.txt. The developer guides in full: docs.sparklayer.io/developers/llms.txt.
  • OpenAPI specs: core, ordering, pricing, purchasing, stock, files, sync-log: https://docs.sparklayer.io/openapi/<api>.yaml (also .json). Ignite: https://docs.sparklayer.io/openapi/ignite.yaml.
  • MCP: Search and read these docs from your assistant with the docs MCP server at https://docs.sparklayer.io/mcp.

The Purchasing API stores your customers' purchases: carts, quotes, purchases awaiting approval or confirmation, and placed orders. Use it to keep the orders shown in My Account up to date.

Purchases aren't sent to your eCommerce platform

Purchases you create with this API show in the My Account area for your B2B customers, but SparkLayer doesn't push them to your eCommerce platform (such as Shopify). To have an order on your platform too, create it with the platform's own API, such as the Shopify order API (opens in a new tab).

For orders created on your platform to sync to SparkLayer, they need a few properties, which depend on your platform. On Shopify, each order needs:

  • The b2b tag
  • The sparklayer.order_import metafield, set to true

See Import order history into SparkLayer for the Shopify steps.

Creating and updating purchases

Create and update purchases with Create or update a purchase (PUT /api/v1/purchases/{lookupBy}/{identifier}). If no purchase matches lookupBy and identifier, a new one is created.

  • Send the full purchase every time. The request replaces the purchase's previous data, so include every field, not just the ones that changed. This prevents stale data and keeps order integrations simple.
  • Leave out calculated fields. The API calculates them, so don't set them in the request body.
  • Expect a 400 for missing or invalid values. The error identifies the value to fix.

Purchase identifiers

The purchase_identifiers object holds the purchase's IDs in each system. Use one of them as lookupBy:

IdentifierDescription
sparklayerSparkLayer's ID for the purchase (a UUID). For an order placed through SparkLayer, this is the ID of the SparkLayer cart, which SparkLayer passes to your eCommerce platform when the customer completes checkout. Send it so the order moves from awaiting_merchant to order and replaces the cart. For other orders, leave it blank.
platformThe purchase's ID on your eCommerce platform.
internalYour ID for the purchase, such as the order number in your ERP or order management system (OMS).
visibleThe ID shown to the customer in their recent orders.

Purchase types

Most integrations send purchases of type order.

Purchase typeDescription
quoteA quote, with a quote status.
awaiting_approvalA purchase waiting for another person at the customer's company to approve it, typically with company users.
awaiting_merchantAn order completed in SparkLayer but not yet confirmed, because it's pending on the eCommerce platform or the sync hasn't finished.
orderA finalised order, saved on the eCommerce platform or in your order source of truth, such as an ERP or OMS.

Packages

A purchase is mostly made up of packages, which hold the line items, shipping methods, addresses and IDs.

  1. When you first create an order, put its line items in a processing package.
  2. As the order progresses, move items to the relevant packages, such as shipment, return or cancelled. You can have more than one of each, for example for partial shipments.

The order status customers see is calculated from the package dates, such as when each package was created and shipped.

Purchase transactions

Record payments, refunds and other transactions against a purchase with Create or update a purchase transaction. SparkLayer uses the transactions to calculate the purchase's payment status.

If you record transactions with this API, don't also send them to your eCommerce platform: the same transaction could be recorded twice.

  • Identify the purchase in the request URL, with lookupBy and identifier. A purchase can have many transactions, but each needs a unique platform_id: the ID the third-party system (such as your payment provider) uses for the transaction. purchase_spark_id in the response is read-only, so don't send it.
  • Set the amount in total: positive for a payment, negative for a refund. A currency_code is also required.
  • Choose whether it counts with apply_to_balance.
apply_to_balanceWhat happens
falseThe transaction is stored for information only, and isn't used to calculate the payment status. The list endpoint returns it, but nothing else happens. Use this for pending or failed transactions, which can help with debugging.
trueThe transaction counts towards the purchase's payment status. SparkLayer also adds an entry to the purchase history, which the customer sees, and adjusts the outstanding balance of the purchase's customer by the total.

Changing a transaction from true to false deletes the history entry it created, and reverses the change to the customer's balance and payment status.

Use full_transaction to store the full transaction, as a JSON string, as the third-party system holds it. SparkLayer stores it as given, without redacting anything, so remove or obscure sensitive data, such as full card numbers, before you send it.

Endpoints

Next steps

Was this page helpful?

Last updated