Your catalogue in emails
catalogue · catalog · products API · items API · plans · services · product feed · recommendations · recommended products · items:write · items:read
Emails can show products: best sellers, the newest additions, a category, items you choose, or a pick for each person. They come from your catalogue in Azimea. A connected shop fills it on its own; if you sell from your own system (plans, services, a custom shop), send the items through the API.
Calls use https://dashboard.azimea.com/api/v1 and an API key with items:write (and items:read to read one back).
Send an item
Section titled “Send an item”POST /items adds an item or updates it. id is your own id: sending the
same id again updates the same item, and a field you leave out keeps its value.
curl https://dashboard.azimea.com/api/v1/items \ -H "Authorization: Bearer $AZIMEA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "id": "plan-pro", "kind": "plan", "name": "Pro plan", "description": "Unlimited projects and priority support.", "url": "https://example.com/pricing#pro", "imageUrl": "https://example.com/img/pro.png", "price": 49, "comparePrice": 59, "currency": "EUR", "categories": ["plans"], "attributes": { "billing": "monthly", "seats": 5 } }'var response = await http.PostAsJsonAsync("items", new{ id = "plan-pro", kind = "plan", name = "Pro plan", url = "https://example.com/pricing#pro", imageUrl = "https://example.com/img/pro.png", price = 49m, comparePrice = 59m, currency = "EUR", categories = new[] { "plans" }});await fetch('https://dashboard.azimea.com/api/v1/items', { method: 'POST', headers: { Authorization: `Bearer ${process.env.AZIMEA_API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 'plan-pro', kind: 'plan', name: 'Pro plan', url: 'https://example.com/pricing#pro', imageUrl: 'https://example.com/img/pro.png', price: 49, comparePrice: 59, currency: 'EUR', categories: ['plans'], }),});$ch = curl_init('https://dashboard.azimea.com/api/v1/items');curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AZIMEA_API_KEY'), 'Content-Type: application/json'], CURLOPT_POSTFIELDS => json_encode([ 'id' => 'plan-pro', 'kind' => 'plan', 'name' => 'Pro plan', 'url' => 'https://example.com/pricing#pro', 'price' => 49, 'currency' => 'EUR', 'categories' => ['plans'], ]),]);$result = json_decode(curl_exec($ch), true);requests.post( "https://dashboard.azimea.com/api/v1/items", headers={"Authorization": f"Bearer {os.environ['AZIMEA_API_KEY']}"}, json={ "id": "plan-pro", "kind": "plan", "name": "Pro plan", "url": "https://example.com/pricing#pro", "price": 49, "currency": "EUR", "categories": ["plans"], },)The fields
Section titled “The fields”| Field | Rules |
|---|---|
id |
Required: your own id, at most 100 characters (catalog.item_id_missing). |
name |
Required, at most 300 characters (catalog.item_name_missing). |
kind |
product, plan, service or other; a new item is a product unless you say otherwise. |
description |
At most 5,000 characters. |
url, imageUrl |
Full addresses starting with https:// (catalog.item_url_invalid), at most 2,000 characters. |
price, comparePrice |
Zero or more; comparePrice (the price before a discount) must be higher than price (catalog.item_price_invalid). |
currency |
The three-letter code, such as EUR or RON (catalog.item_currency_invalid). |
inStock, stockQuantity |
A new item is in stock. stockQuantity is a whole number of zero or more. |
categories |
At most 20, each a short name: they drive the “one category” and “for each person” recommendations. |
attributes |
At most 50 fields, each a short lowercase key with a text, number or yes/no value. |
active |
A new item is active. false stops recommending it but keeps its history. |
The catalogue holds at most 100,000 items (catalog.items_limit).
Many items at once
Section titled “Many items at once”POST /items/batch takes up to 1,000 items, each written or refused
on its own. The answer counts the created, updated and failed items and gives one result per item, by its position in
your request. More than 1,000 refuses the whole call (catalog.batch_too_large). A batch counts as one call for the rate
limit, so a nightly sync of your whole catalogue in batches of 1,000 is the usual pattern.
Read or remove an item
Section titled “Read or remove an item”GET /items/{externalId}reads one item you sent, by your own id.DELETE /items/{externalId}removes it, so emails stop recommending it. To keep its history instead (for example a plan you no longer sell), send it again with"active": false.
Both see only the items your system sent. Items synced from a connected shop are not found or changed here: they
change in the shop and follow on their own (catalog.item_read_only).
How emails use the catalogue
Section titled “How emails use the catalogue”In the email editor, a recommendation block shows 2 to 8 items, chosen when the email is sent:
| Choice | What it shows |
|---|---|
| Best sellers | What sold most in the last 30 days. |
| Newest | The latest items added to the catalogue. |
| One category | The newest items of the category you choose. |
| Chosen by you | The items you pick, in your order. |
| For each person | Items from the categories the person bought in, never what they already bought; someone who has not bought yet sees your best sellers. |
Only items that are active and in stock are shown, at the price they have on the day the email goes out. So keep
prices, stock and active up to date from your system, and the emails stay right without editing them.