Skip to main content

Schemas

The Customer API exposes machine-readable schemas for its two primary endpoints, so clients can adapt automatically to new fields without code changes. Use the schema endpoints to:

  • Validate the shape of the data before processing it.
  • Generate column headers for CSV exports dynamically.
  • Detect new fields in your monitoring tools and alert when the surface changes.

:::caution Casing mismatch with data endpoints The schema endpoints report field names in camelCase (sKU, mOQ, hSCode, etc.), while the data endpoints themselves — /products, /stock, /prices — return JSON property keys in PascalCase (SKU, MOQ, HSCode, etc.). This is a known mismatch in the current API profile. If you generate column headers from the schema and then read values by those header names, you will need to translate the schema names back to PascalCase to look them up in the response. :::

GET /products/schema

GET /products/schema

Returns a description of the /products response.

Authentication

Required. Bearer token from /auth/token.

Example response

{
"endpoint": "/products",
"apiVersion": "2026-04",
"fields": [
{ "name": "sKU", "type": "string", "required": true },
{ "name": "name", "type": "string", "required": false },
{ "name": "description", "type": "string", "required": false },
{ "name": "productCategoryCode", "type": "string", "required": false },
{ "name": "status", "type": "string", "required": false },
...
],
"arrays": {
"productImages": {
"fields": [
{ "name": "imageID", "type": "string", "required": false },
{ "name": "fileName", "type": "string", "required": false },
{ "name": "isPrimaryImage", "type": "boolean", "required": false }
]
},
"productAccessories": { "fields": [ { "name": "accessorySKU", "type": "string" } ] },
"productSubstitutions": { "fields": [ { "name": "substituteSKU", "type": "string" } ] },
"productComposition": {
"fields": [
{ "name": "materialCode", "type": "string" },
{ "name": "materialDescription", "type": "string" },
{ "name": "compositionPercentage", "type": "decimal" }
]
},
"productPrices": {
"fields": [
{ "name": "priceListCode", "type": "string" },
{ "name": "priceListName", "type": "string" },
{ "name": "currencyCode", "type": "string" },
{ "name": "sKU", "type": "string" },
{ "name": "priceExclVAT", "type": "decimal" },
{ "name": "mOQ", "type": "decimal" },
{ "name": "orderMultiple", "type": "decimal" }
]
}
}
}

What's in it

FieldMeaning
endpointThe path of the endpoint this schema describes.
apiVersionThe API profile this schema belongs to. Matches /api/version.
fields[]The scalar fields of each item, in source declaration order.
arrays{}Each nested-array field, with its own list of inner fields.

Each field carries:

  • name — the field name in camelCase.
  • type — one of string, integer, decimal, boolean, date, datetime. Unknown types fall back to a lowercase form of the underlying type name.
  • requiredtrue only for fields explicitly required by the underlying model (currently only sKU). All other fields are required: false regardless of whether they are typically present.

GET /stock/schema

GET /stock/schema

Returns a description of the /stock response. The shape is the same as /products/schema but without an arrays block (stock entries have no nested arrays).

Example response

{
"endpoint": "/stock",
"apiVersion": "2026-04",
"fields": [
{ "name": "sKU", "type": "string", "required": true },
{ "name": "stockLocation", "type": "string", "required": false },
{ "name": "availableQTY", "type": "decimal", "required": false },
{ "name": "nextAvailableETA", "type": "date", "required": false }
]
}

When to call the schema endpoints

In most integrations, you'll call the schema endpoint once on startup and cache the result in memory. You don't need to fetch it on every request — it changes only when Kiss releases a new API profile.

A common pattern:

on startup:
schema = GET /products/schema
cached_field_names = [f.name for f in schema.fields]

on each sync:
data = GET /products
write_csv(headers=cached_field_names, rows=data)

When mapping schema names back to fields in the data response, remember to translate the casing — for example, the schema's sKU corresponds to the response's SKU. See the casing-mismatch note above.

If you want to be defensive against profile changes mid-run, compare the response's apiVersion to a cached copy on every call and refresh the schema when it changes.

Status codes

StatusCause
200Success.
401Missing, malformed, or expired bearer token.
429Rate limited — see Rate limits.