# Ordering API

URL: https://docs.sparklayer.io/developers/api/ordering

Create, update, calculate and complete carts with the Ordering API to place orders for customers, check their pricing first and handle validation errors.

> **For AI assistants:** these facts apply to every SparkLayer API call.
>
> - **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 `409`s 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: https://docs.sparklayer.io/llms.txt. Every API operation, compactly: https://docs.sparklayer.io/llms-api.txt. The developer guides in full: https://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 Ordering API lets you create SparkLayer carts on behalf of your customers and complete them as orders on your connected eCommerce platform — for example to place orders from an external system or for drop shipping. Carts use the same pricing, validation, ordering rules and checkout logic as the SparkLayer cart your customers use, except that upfront payment methods aren't available for carts created through the API.

> **Beta**
>
> The Ordering API is in beta. If you'd like to use it, email [support@sparklayer.io](mailto:support@sparklayer.io) and our team will help you get started.

The API reference below gives full endpoint and schema details. This guide covers checking customer-specific pricing, the cart and order lifecycle, and how validation works.

## Customer-specific pricing lookup

The [Get customer-specific pricing](https://docs.sparklayer.io/developers/api/core/get-customer-specific-pricing.md) endpoint is part of the Core API. Use it before creating a cart to check pricing and price breaks for validation or user feedback.

It calculates real-time pricing for one or more SKUs in the context of a specific customer. It returns per-line-item unit prices, line totals, and quantity price breaks, accounting for the customer's assigned price lists and any customer-level discount percentage.

### Price calculation

SparkLayer looks up the customer's assigned price lists and uses those to calculate accurate pricing for each requested product. This includes:

- **Quantity price breaks** — the price adjusts based on how many units are being ordered
- **Variant aggregation** — if your store is configured to apply price breaks across variants, quantities across sizes or colours of the same product are combined when determining the price tier. For example, ordering 5× size M and 5× size L could unlock the 10-unit price break for both.
- **Customer discounts** — any discount assigned to the customer is applied on top of the list price

Each product in the response includes the unit price, line total, and a full breakdown of available quantity price breaks. All prices are returned as net values.

### Potential issues

- **Partial pricing failure** — if any product can't be priced, the response status is `207`: affected line items include an error with null pricing data, and successfully priced items are returned alongside them.
- **Invalid request** — a `400` is returned if the request is malformed, the customer doesn't exist, or the customer has no price lists configured.

## Order lifecycle

Every order starts as a cart for a customer, and goes through four steps:

1. [Create a cart](#1-create-an-empty-cart) for the customer.
2. [Update the cart](#2-update-the-cart) with line items and order details, and review any validation errors.
3. [Calculate the cart](#3-calculate-the-cart) to get totals and the available shipping and payment methods. Calculate again with your chosen shipping rate to confirm the totals.
4. [Complete the cart](#4-complete-the-cart) with the shipping rate and payment method to place the order.

## 1. Create an empty cart

[Create a cart](https://docs.sparklayer.io/developers/api/ordering/create-cart.md) for the customer you're placing the order for. Identify the customer with `customer_id` and `customer_lookup_by`: `sparklayer` (the customer's SparkLayer ID), `platform` (the ID from your eCommerce platform) or `email`.

A new cart is empty. It holds all the order information, including line items, quantities and the shipping address. The response includes a `cart_id`: use it for every later request about the cart.

## 2. Update the cart

[Update the cart](https://docs.sparklayer.io/developers/api/ordering/update-cart.md) with the information the order needs:

- Line items and their quantities
- The shipping address (`shipping_address_id`), or a `temporary_shipping_address`
- The customer reference, PO number, requested shipping date and custom fields

Each update replaces the cart's line items, so always send the full list with the final quantity of each item. Omitting `line_items`, or sending an empty array, empties the cart.

For drop shipping, use a temporary shipping address when the delivery address shouldn't be stored against the customer's account.

### Validation

Each cart update returns the latest cart state, including any validation errors generated by your business rules in SparkLayer, such as:

- Minimum or maximum order quantity restrictions
- Product availability constraints
- Customer-specific purchasing restrictions

The response also has a result for each line item, so you can see how each requested item was processed and whether it was adjusted or has a validation error.

The [Update a cart](https://docs.sparklayer.io/developers/api/ordering/update-cart.md) and [Calculate a cart](https://docs.sparklayer.io/developers/api/ordering/calculate-cart.md) operations don't fail because of validation errors: the errors are included in the response for your application to handle. Calculating does return a `422` if the cart is empty or the shipping rate you chose isn't available — see [Cart errors](https://docs.sparklayer.io/developers/errors.md#cart-errors).

The [Complete a cart](https://docs.sparklayer.io/developers/api/ordering/complete-cart.md) operation behaves differently. If validation errors exist, it returns a `422` and the cart isn't completed. To allow specific validation errors, list them in the `ignore_validation_errors` property.

## 3. Calculate the cart

[Calculate the cart](https://docs.sparklayer.io/developers/api/ordering/calculate-cart.md) before completing it. SparkLayer:

- Calculates the order totals and tax with the connected platform
- Applies pricing
- Returns the available shipping methods and their costs
- Returns the allowed payment methods
- Validates the current cart state

To choose a shipping method, pass its `shipping_rate_handle`. If you leave it out, SparkLayer uses the first available shipping rate. Calculate again after changing the shipping rate or the cart, so the totals you show are up to date. 

## 4. Complete the cart

[Complete the cart](https://docs.sparklayer.io/developers/api/ordering/complete-cart.md) once it's valid and you've chosen how to ship and pay. Send:

- `shipping_rate_handle`: a shipping rate returned when you calculated the cart
- `payment_method`: `paymentByInvoice` or `paymentOnAccount`
- `ignore_validation_errors`: the validation errors to allow (an empty list allows none, `"*"` allows all)

Completing a cart turns it into a SparkLayer order and submits it to the connected eCommerce platform.

The response includes the new `purchase_id`. The cart is deleted once it's completed, so later requests with its ID return `404`.

## Endpoints

- [POST Create a cart](https://docs.sparklayer.io/developers/api/ordering/create-cart.md)
- [GET Get a cart](https://docs.sparklayer.io/developers/api/ordering/get-cart.md)
- [PATCH Update a cart](https://docs.sparklayer.io/developers/api/ordering/update-cart.md)
- [DELETE Delete a cart](https://docs.sparklayer.io/developers/api/ordering/delete-cart.md)
- [POST Complete a cart](https://docs.sparklayer.io/developers/api/ordering/complete-cart.md)
- [POST Calculate a cart](https://docs.sparklayer.io/developers/api/ordering/calculate-cart.md)

## Next steps

- [Authentication](https://docs.sparklayer.io/developers/authentication.md): get an access token for your requests.
- [Errors](https://docs.sparklayer.io/developers/errors.md#cart-errors): the cart error codes and what they mean.
- [Purchasing API](https://docs.sparklayer.io/developers/api/purchasing.md): the orders and quotes customers see in My Account.
