Skip to content

API conventions ​

Rules shared by all endpoints of the Adore JSON API. The endpoints themselves are in the API reference.

Base URLs ​

PrefixWhatExample
/api/v0Core (simploSHOP) API: products, variations, carts, orders, …GET /api/v0/products/71
/api/themeAdore theme API: Adore-only resources (restocks, companies, offers, …)GET /api/theme/product-variation-expected-restocks

The shop is resolved from the hostname of the request (e.g. adore.localhost, sk.adore.localhost). The hostname also sets the default language and currency (from the hostname's country). Behind a proxy send the shopfront host in X-SES-Referer-Host. An unknown hostname returns 404 with type ShopNotRecognized.

Headers ​

HeaderPurpose
Language-PreferenceLocale(s) of multilingual props in the response: cs-CZ, sk-SK, en-US (comma-separated for several). One locale → plain strings; no header → objects keyed by language ID ({"ces": "…", "slk": "…"}). Unknown locale → 400.
Currency-PreferenceCurrency of money props, e.g. CZK. One currency → {value, formatted}; no header → object keyed by currency.
Accept-Preferred-LanguageLanguage the shop runs in for this request (translations of messages, slugs). Enabled in Adore.
Authorization: Bearer <jwt>Signed-in customer (shopfront) or admin user. Customers can also use the customer_access_token cookie.

The shopfront always sends Language-Preference and Currency-Preference.

Authentication and permissions ​

  • Product and variation reads are public: guests and customers see active products accessible to their customer group (hidden products are left out of lists). Admin users with products:read see everything, including inactive variations.
  • Writes need an admin user with the matching permission (create, update, delete).
  • Without a session a protected action returns 401 Unauthenticated, with an insufficient one 403 Unauthorized.

Response shape ​

Detail — the object itself:

json
{ "id": 71, "code": "1101310", "stock_state": 50, "_links": [...], "_embedded": { ... } }

List — items plus pagination metadata (only when paginated):

json
{
  "items": [ { "id": 71, ... }, { "id": 72, ... } ],
  "_meta": { "page": 1, "total_pages": 57, "records": 113, "per_page": 2 }
}
  • _links – HATEOAS links (href is relative, type is the HTTP method).
  • _embedded – present only when embeds were requested.
  • Dates use the format Y-m-d\TH:i:sO, e.g. 2026-11-20T06:00:00+0100.
  • An empty response (e.g. after DELETE) is 204 without a body.

embed – related data in one request ​

Embeds add related or computed data under _embedded. They are loaded in batches, so embedding into a list does not cost one request per item. Always prefer an embed to a follow-up request.

http
GET /api/v0/products/71?embed=expected_restocks,additional_data

Grammar:

SyntaxMeaning
embed=a,bembeds a and b
embed=a{x,y}embed a, only its props x and y
embed=a{x,_embed{b,c}}embed a and inside each a item embed b and c

Example – product with its variations and each variation's restocks:

http
GET /api/v0/products/71?embed=product_variations{id,code,stock_state,_embed{expected_restocks}}
  • Unknown embed → 400 InvalidResourceParameters listing the names.
  • Nesting works only for embeds that return resources (e.g. product_variations, default_category, brand).
  • additional_data{key} does not narrow the keys – the whole object is always returned.
  • Embed parameters (embed=a:param) are not supported.

Product embeds ​

EmbedReturns
expected_restocksRestocks of the active variations summed per date {items: [{datetime, count}], total_count} (Adore)
additional_data{product_variation_type, available_lead_time_days} (Adore)
stock_states[{stock_id, state}] per warehouse
product_variationsall variations (including inactive), supports nested _embed
active_product_variations_countnumber of active variations
product_availabilityavailability label
product_variation_propertiesvariation properties of the product
default_product_variation_id, default_product_variation_ids_by_attributedefault variation
computed_prices, computed_taxed_prices, discounted_price, discounted_taxed_price, discount_percents, discount_taxed_percents, discounted_fixed_amount, customer_price, customer_taxed_price, quantity_prices, pricesprices for the current customer (prices only with price lists)
default_image_id, default_image_url, default_image, default_image_size, secondary_image_id, secondary_image_url, secondary_image_size, og_image_urlimages
urls, default_category, brand, root_brand, brand_image_url, manufacturernavigation and brand
category_ids, tag_ids, tags, propertiesclassification
attachments, product_attachmentsdocuments
rating, product_review_parameters, product_review_parameter_ratingsreviews (*detail only)
customer_product_wish_list_item_id, customer_product_variations_wish_list_items, customer_account_products, customer_account_products_all, active_customer_groupscustomer-specific data
related_product_gifts, product_related_products_grouped_by_propertiesrelated products
reservation_expiration_at, amount_unit_translations, export_product_ids, product_pairings, product_fields, product_package_product_ids, product_package_variation_idsother

Product variation embeds ​

EmbedReturns
expected_restocksthe variation's restocks {items: [{datetime, count}], total_count} (Adore)
additional_data{is_included_in_feed, product_variation_type, available_lead_time_days} (Adore)
stock_states[{stock_id, state}] per warehouse
product_availabilityavailability label
properties[{product_property_id, product_property_attribute_id, attribute_name, property_name}]
image_url, image, default_image_id, default_image_url, default_imageimages (image_url falls back to the product image)
computed_prices, computed_taxed_prices, discounted_price, discounted_taxed_price, discount_percents, discounted_fixed_amount, customer_price, customer_taxed_price, quantity_prices, pricesprices
tag_ids, tags, customer_account_productsother

only / except – choose props ​

http
GET /api/v0/products?only=id,code,stock_state&embed=expected_restocks
  • Comma list, a.b for nested props, a[b,c] for a group.
  • only and except cannot be combined.
  • Fewer props mean less computation – use only in lists.
  • only does not remove _embedded.

filters – list filtering ​

filters is a base64-encoded JSON array of conditions:

json
[
  { "f": "product_id", "o": "eq", "v": 71 },
  { "f": "is_active", "o": "eq", "v": true }
]
js
const filters = btoa(JSON.stringify([{ f: 'product_variation_id', o: 'in', v: [299, 300] }]))
fetch(`/api/theme/product-variation-expected-restocks?filters=${encodeURIComponent(filters)}&paginate=0`)
  • Conditions are AND-ed. "f": ["code", "sku"] checks several fields with OR.
  • v is required (it may be null where the field allows it).
  • Operators: eq, neq, gt, gte, lt, lte, in, nin (numbers, dates, enums), contains, starts_with, ends_with (strings). in / nin take an array.
  • Additional data are filtered as additional_data.<key> where the definition allows it (e.g. additional_data.product_variation_type).
  • Unknown field or bad value → 400 InvalidResourceParameters.

sort, search and pagination ​

ParameterDescription
sortsort=-stock_state,id – comma list, - for descending; only fields the resource allows
searchfull-text search (products only), max 100 characters; adds sort field relevance
paginate0 = all items, no _meta; lists paginate by default
pagepage number from 1
per_pageitems per page, default 100

filters, sort and search are rejected on detail endpoints.

Errors ​

json
{
  "type": "InvalidResourceParameters",
  "message": "…",
  "id": "6f1c2f0e-…",
  "errors": [{ "field": "name.ces", "message": "…" }]
}
StatustypeWhen
400InvalidResourceParametersbad embed, only, filters, sort, search, pagination
401Unauthenticateda session is required
403Unauthorizedthe session lacks the permission
404NotFound / ShopNotRecognizedmissing resource / unknown hostname
422ValidationErrorinvalid body; errors lists the fields (name.ces, price.price.CZK, …)
500GeneralErrorserver error; stack only outside production