Entities
The data you push is a stream of entities — one NDJSON line per entity in a snapshot, one operation
per entity in an /events batch. Every entity shares one envelope; only the payload differs by kind.
The envelope
{
"kind": "<entity_kind>",
"external_id": "<your-stable-id>",
"lang": "<locale | null>",
"translation_of": "<external_id | null>",
"payload": { /* kind-specific */ }
}
kind— the discriminator; one of the 16 kinds below.external_id— your stable, opaque id. Canonical shape<source>:<kind>:<id>(e.g.wc:product:iphone-15-pro,laravel:category:42). The backend stores it verbatim and upserts on it; parent references use the same shape.lang/translation_of— optional locale tag and a pointer to the original entity for translations.
In an /events batch the same fields appear inside each operation, with type (upsert / delete)
and an optional deleted_at.
The 16 kinds
| Kind | Purpose |
|---|---|
site | Single-row store basics — name, url, locale, currency, timezone. |
environment | Single-row technical landscape — platform, plugins, capabilities (diagnostic). |
product | The catalog item. Richest payload; carries inline variations. |
variation | A single product variation (inline in product, or standalone in a delta). |
category | Product category; supports a parent reference + optional available_filters / available_sorts that ground the bot's filtering & sorting (see Capabilities). |
tag | Product tag. |
attribute | A taxonomy-level attribute (e.g. pa_color) and its possible values. |
page | A content page; content_text feeds retrieval. |
post | A blog post (same shape as page). |
cpt | A custom post type (same shape as page). |
menu | A navigation menu with a recursive item tree. |
menu_item | A flat, normalized navigation item. |
form | A site form (fields, submit endpoint, intent hint). |
popup | A site popup (triggers, intent hint). |
shipping_method | An offered shipping method. |
payment_method | An offered payment method. |
A backend that doesn't recognise a kind dead-letters it rather than failing the batch, so a newer producer can introduce a kind ahead of the backend.
Three rules that matter
These are the mistakes that silently produce wrong answers, so they are worth stating plainly:
- Money is integer minor units.
549.99 UAHis54999— never a float, never a string. Applies toprice_amount,regular_price_amount,sale_price_amount.currencyis a separate ISO-4217 string. categoriesandtagsare slug lists —["smartphones", "apple"], not objects, not numeric ids.page.content_textis plain text — strip HTML and decode entities; this is what retrieval reads. (content_htmlmay carry the original markup separately for rendering.)
Required fields
Almost everything is optional with a default. The fields you can't omit:
product→namepage/post/cpt→titleform→plugin,title,submit_endpointvariation(standalone) →parent_external_id
Unknown extra fields are ignored, so adding a field your backend doesn't know yet won't fail validation.
Product — the canonical payload
{
"kind": "product",
"external_id": "wc:product:iphone-15-pro-256gb",
"lang": "uk_UA",
"payload": {
"sku": "APL-IP15P-256",
"name": "Apple iPhone 15 Pro 256GB",
"slug": "iphone-15-pro-256gb",
"product_type": "variable",
"price_amount": 54999,
"regular_price_amount": 59999,
"currency": "UAH",
"description": "Флагман Apple з чіпом A18 Pro та титановим корпусом.",
"stock_status": "instock",
"stock_quantity": 14,
"permalink": "https://shop.example.com/product/iphone-15-pro-256gb/",
"categories": ["smartphones", "apple"],
"tags": ["new", "premium", "5g"],
"attributes": [
{ "name": "Колір", "slug": "pa_color", "options": ["Blue Titanium", "White Titanium"], "variation": true }
],
"variations": [
{ "external_id": "wc:variation:12345", "sku": "APL-IP15P-256-BLU",
"price_amount": 54999, "stock_status": "instock", "attributes": { "pa_color": "Blue Titanium" } }
],
"images": [
"https://cdn.example.com/iphone-15-pro-blue-1.jpg",
"https://cdn.example.com/iphone-15-pro-blue-2.jpg"
]
}
}
Notable fields: product_type is one of simple | variable | grouped | external; stock_status is a
string (instock / outofstock / onbackorder), never a bool; images is a flat URL list with the
primary first; variations are inline for variable products. A single variation can also be pushed
standalone in a delta with a parent_external_id.
Next
- Errors — the error shape and retry semantics.