Basis
| Base URL | |
|---|---|
| Formaat | JSON (Content-Type: application/json), UTF-8 |
| Authenticatie | API key in de header Authorization: Bearer <key> (of X-API-Key: <key>). Keys beginnen met sbx_ en worden aangemaakt door een beheerder in de Spec Builder onder Instellingen → API-koppelingen. |
| Versie | v1 |
Productkoppeling
Elk product in de Spec Builder heeft een artikelcode (bijv. AC126). Werkbeschrijvingen (productiedocumenten) hangen aan dat product. Een binnenkomend recept wordt zo aan een product gekoppeld:
- Is jullie
product.ideerder al aan een product gekoppeld, dan wordt die koppeling gebruikt. - Anders wordt gezocht op
product.articleCode(hoofdletterongevoelig). Bij precies één match wordt de koppeling automatisch gemaakt en onthouden. - Geen match: het recept wordt wél opgeslagen, en een beheerder kan het later handmatig koppelen.
product.id mee, en waar mogelijk de articleCode. De productnaam wordt alleen voor weergave gebruikt, niet om te koppelen.POST/api/v1/recipes
Lever een receptversie aan, één bericht per product. Dit kan vanaf een knop of automatisch na een receptwijziging.
Een receptversie is uniek op product.id + recipe.version. Dezelfde combinatie opnieuw sturen werkt die versie bij en maakt geen dubbele aan. Is er niets veranderd, dan is het antwoord "unchanged". Een nieuwe recipe.version wordt als nieuwe versie bewaard, zodat de historie behouden blijft.
Velden
| Veld | Type | Omschrijving | |
|---|---|---|---|
product.id | string | verplicht | Vaste ID van het eindproduct in jullie systeem (max 128 tekens) |
product.name | string | verplicht | Naam van het eindproduct |
product.articleCode | string | aanbevolen | Artikelcode in de Spec Builder (bijv. AC104), gebruikt voor automatisch koppelen. Ontbreekt deze, dan wordt product.sku geprobeerd. |
product.salesProduct | boolean | aanbevolen | Het vinkje "salesproduct" uit het ERP. Alleen eindproducten worden bewaard: bij false wordt het bericht genegeerd (antwoord "status": "ignored"). Ontbreekt het veld, dan wordt het bericht als eindproduct behandeld. |
product.sku, product.code | string | optioneel | Worden bewaard ter referentie |
recipe.version | string | verplicht | Versie van het recept, bijv. "2026-09-01" of "v3" |
recipe.description | string | optioneel | Omschrijving van het recept |
recipe.unit | string | optioneel | Eenheid van het eindproduct, bijv. Box |
recipe.productionLocation | string | optioneel | Productielocatie |
recipe.shelfLifeDays | number | optioneel | Houdbaarheid in dagen |
recipe.ingredients | array | verplicht | 1–500 ingrediënten |
…ingredients[].name | string | verplicht | Naam van het ingrediënt |
…ingredients[].quantity | number | verplicht | Hoeveelheid ingrediënt per eenheid eindproduct, ≥ 0 (decimale punt) |
…ingredients[].unit | string | verplicht | Eenheid, bijv. g, ml, Piece |
…ingredients[].id, .sku | string | optioneel | ID en grondstofcode in jullie systeem (code wordt ook geaccepteerd) |
source | string | optioneel | Naam van het verzendende systeem, bijv. "snackboxtogo-erp" |
sentAt | string | optioneel | Verzendtijdstip (ISO 8601) |
Het oudere platte formaat (recipeVersion en ingredients op het hoogste niveau) wordt ook nog geaccepteerd.
Voorbeeld
curl -X POST /api/v1/recipes \
-H "Authorization: Bearer sbx_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"product": { "id": "01K…", "articleCode": "AC104", "name": "GETAWAY CAFE Panini Ham & Cheese", "sku": "RIM02", "code": "SC-0012", "salesProduct": true },
"recipe": {
"version": "2026-09-01",
"description": "…",
"unit": "Box",
"productionLocation": "…",
"shelfLifeDays": 270,
"ingredients": [
{ "id": "01G…", "sku": "…", "name": "Ciabatta 100gr", "quantity": 1, "unit": "Piece" }
]
},
"source": "snackboxtogo-erp",
"sentAt": "2026-10-02T09:00:00.000Z"
}'
Antwoord
201 bij een nieuwe versie, 200 bij een update of ongewijzigde versie.
{
"id": "4a8b086e-7f77-481d-bf69-5200735798ec",
"status": "created", // "created" | "updated" | "unchanged" | "ignored" (geen salesproduct)
"linkedProduct": { // null als (nog) niet gekoppeld
"id": "183b8534-27e4-431a-bd31-fe8f1a9c34da",
"articleCode": "AC104",
"name": "Breakfast sandwich",
"workInstructions": 1 // aantal werkbeschrijvingen bij dit product
}
}
GET/api/v1/products
Lijst van producten in de Spec Builder, om jullie producten aan de onze te kunnen mappen. Het antwoord is een JSON-array (geen data-wrapper).
[
{ "id": "183b8534-…", "articleCode": "AC104", "name": "Breakfast sandwich", "workInstructions": 1 }
]
GET/api/v1/ping
Controleer of een API key werkt. Antwoord: { "ok": true, "key": "<naam van de key>" }
Foutcodes
| Status | Betekenis |
|---|---|
400 | Ongeldige payload. details bevat per veld wat er mis is. |
401 | Ontbrekende, ongeldige of ingetrokken API key. |
429 | Te veel mislukte authenticatiepogingen; probeer het na 15 minuten opnieuw. |
{ "error": "Ongeldige payload", "details": ["recipeVersion is verplicht"] }