Skip to content

Create or update a customer

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.
  • Ignite: With Ignite, SparkLayer calls endpoints that your service implements (the Ignite spec), and your service calls the SparkLayer APIs above for everything else.
  • 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.

Implemented by your integration

This is an Ignite endpoint: your integration service implements it and SparkLayer calls it. Use this reference to build and test your implementation.
PUT/v1/{siteEnv}/{siteId}/customers

Create or update a "customer" on the eCommerce platform. The email address of the customer should be used as the unique identifier for finding the customer on the target platform.

Path Parameters

siteEnv*string

The SparkLayer environment the request is for, such as live. Store it, with the site ID, when SparkLayer connects your platform.

siteId*string

The SparkLayer site ID the request is for, such as bobs-store. Store it, with the environment, when SparkLayer connects your platform.

Length1 <= length

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

email*string
Formatemail
first_name*string
Length1 <= length <= 128
last_name*string
Length1 <= length <= 128
company_name?|
Lengthlength <= 128
accounting_id?|

The identifier for the customer in the merchant's accountancy or ERP

Length1 <= length <= 124
sales_agent_groups?array<string>|null
price_lists?array<string>|null
customer_discount_percentage?|
Formatfloat
group?|
Lengthlength <= 128
role?string|null
addresses?array<>|

List of customer addresses

send_invite?boolean|null
tax_exempt?boolean

Whether the customer is tax exempt or not. This is only relevant to platforms that support tax exemption.

parent_customer_external_id?|

Parent Customer ID of the Customer

additional_tags?array<>|

Additional tags to appear on the customer in Shopify. Automatically prefixed with spark-

payment_on_account?|null

Response Body

application/json

curl -X PUT "https://ignite.example.com/v1/live/bobs-store/customers" \  -H "Content-Type: application/json" \  -d '{    "email": "bob@sparklayer.io",    "first_name": "Bob",    "last_name": "Jones",    "company_name": "Tom Jones Climbing Ltd",    "accounting_id": "<accounting_id>",    "sales_agent_groups": [      "group-1"    ],    "price_lists": [      "25-off"    ],    "customer_discount_percentage": 25,    "group": "50-off",    "role": "limited-customer",    "addresses": [      {        "title": "Mr",        "first_name": "Bob",        "last_name": "Jones",        "company": "Tom Jones Climbing Ltd",        "address_line1": "Example Industrial Estate",        "address_line2": "North Country",        "city": "Cityland",        "region_name": "California",        "region_code": "CA",        "postal_code": "12345",        "country_code": "US",        "phone": "+44 (0) 123456789",        "is_default_shipping": true,        "is_default_billing": true,        "is_temporary": true      }    ],    "send_invite": true,    "tax_exempt": true,    "parent_customer_external_id": "CU1234",    "additional_tags": [      "high-priority"    ],    "payment_on_account": {      "credit_limit": 0,      "balance": 0,      "currency_code": "<currency_code>",      "net_terms": "7_days"    }  }'
{  "customer_external_id": "CU1234"}