Calculate a cart
For AI assistants: the facts every SparkLayer API call needs
- Base URLs: Live
https://app.sparklayer.io, testhttps://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/tokenwith aSite-Idheader and a JSON body (not form-encoded):{"grant_type":"client_credentials","client_id":"…","client_secret":"…"}. It returnsaccess_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>andSite-Id: <site id>, plusContent-Type: application/jsonwhen there is a body. Set aUser-Agentthat names your integration. - Errors: RFC 7807 problem details:
title,status,detailand an optionalerrors[]of{ code, message, property }. Some error responses have no body. Retry5xx,429(honouringRetry-After) and concurrent-update409s with exponential backoff; on401, get a new token once and retry; don't retry other4xxwithout changing the request. - Pagination: Most list endpoints return everything.
GET /api/v2/price-listspages withpageandpage_size(up to 250) untilpagination.current_pageequalstotal_pages.GET /api/v1/purchasesuseslimit(up to 500) andoffset: stop when a page has fewer thanlimitresults. - Ground rules: Use only endpoints, fields and SDK methods that the docs or OpenAPI specs define. Prefer
GET /api/v2/price-listsover 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
.mdto 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.
POST /api/v1/carts/{id}/calculate Ordering API
Calculates the cart's totals, tax, available shipping methods and allowed payment methods, optionally for the shipping rate given in shipping_rate_handle. Returns 422 with the error code cart-empty if the cart has no items, or cart-shipping-rate-handle-unavailable if the SparkLayer shipping rate you chose isn't available for this cart.
Authorization
bearerAuth Send Authorization: Bearer <access_token>, together with your Site-Id header, on every request. Get the token from POST /api/auth/token with your Site ID in the Site-Id header and a JSON body (not form-encoded, so standard OAuth 2.0 client libraries don't work): {"grant_type": "client_credentials", "client_id": "…", "client_secret": "…"}. Tokens are valid for 3,600 seconds and there is no refresh token: request a new one shortly before it expires. Create API credentials in the SparkLayer Dashboard under Settings > API. See Authentication.
In: header
Path Parameters
The cart's ID: the cart_id returned by Create a cart.
Header Parameters
Your SparkLayer Site ID, from Settings > API in the SparkLayer Dashboard.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Omitting this will set the carts shipping handle to the first available
Response Body
application/json
application/json
application/problem+json
curl -X POST "https://app.sparklayer.io/api/v1/carts/9151f21f-43ae-43b4-92f3-f4af67cdf544/calculate" \ -H "Authorization: Bearer <ACCESS_TOKEN>" \ -H "Site-Id: jones-climbing" \ -H "Content-Type: application/json" \ -d '{ "shipping_rate_handle": "<shipping_rate_handle>" }'{ "totals": { "total": { "pre_discount": { "net": { "amount": "string", "currency_code": "string" }, "gross": { "amount": "string", "currency_code": "string" }, "tax": { "amount": "string", "currency_code": "string" }, "apportioned_tax_rate": 0.1, "currency": "string" }, "discount": { "net": { "amount": "string", "currency_code": "string" }, "gross": { "amount": "string", "currency_code": "string" }, "tax": { "amount": "string", "currency_code": "string" }, "apportioned_tax_rate": 0.1, "currency": "string" }, "charge": { "net": { "amount": "string", "currency_code": "string" }, "gross": { "amount": "string", "currency_code": "string" }, "tax": { "amount": "string", "currency_code": "string" }, "apportioned_tax_rate": 0.1, "currency": "string" } }, "shipping": { "pre_discount": { "net": { "amount": "string", "currency_code": "string" }, "gross": { "amount": "string", "currency_code": "string" }, "tax": { "amount": "string", "currency_code": "string" }, "apportioned_tax_rate": 0.1, "currency": "string" }, "discount": { "net": { "amount": "string", "currency_code": "string" }, "gross": { "amount": "string", "currency_code": "string" }, "tax": { "amount": "string", "currency_code": "string" }, "apportioned_tax_rate": 0.1, "currency": "string" }, "charge": { "net": { "amount": "string", "currency_code": "string" }, "gross": { "amount": "string", "currency_code": "string" }, "tax": { "amount": "string", "currency_code": "string" }, "apportioned_tax_rate": 0.1, "currency": "string" } }, "sub_total": { "pre_discount": { "net": { "amount": "string", "currency_code": "string" }, "gross": { "amount": "string", "currency_code": "string" }, "tax": { "amount": "string", "currency_code": "string" }, "apportioned_tax_rate": 0.1, "currency": "string" }, "discount": { "net": { "amount": "string", "currency_code": "string" }, "gross": { "amount": "string", "currency_code": "string" }, "tax": { "amount": "string", "currency_code": "string" }, "apportioned_tax_rate": 0.1, "currency": "string" }, "charge": { "net": { "amount": "string", "currency_code": "string" }, "gross": { "amount": "string", "currency_code": "string" }, "tax": { "amount": "string", "currency_code": "string" }, "apportioned_tax_rate": 0.1, "currency": "string" } } }, "discounts": [], "shipping_methods": [ { "title": "string", "description": "string", "price_v2": { "net": 0.1, "gross": 0.1, "tax_rate": 0, "currency_code": "string", "tax_inclusive_display": false }, "price_v2_pre_discount": { "net": 0.1, "gross": 0.1, "tax_rate": 0, "currency_code": "string", "tax_inclusive_display": false }, "handle": "string", "cost_type": "string", "cost_language_string": "string" } ], "allowed_payment_methods": { "payment_by_invoice": "AVAILABLE", "payment_on_account": "AVAILABLE", "upfront_payment": "AVAILABLE", "quote": "AVAILABLE" }, "selected_shipping_rate_handle": "string", "selected_payment_method": "string"}