Snackbox To-Go Spec Builder — API

Recepten (eindproduct, receptversie, ingrediënten en hoeveelheden) aanleveren aan de Spec Builder.

Basis

Base URL
FormaatJSON (Content-Type: application/json), UTF-8
AuthenticatieAPI 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.
Versiev1

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:

  1. Is jullie product.id eerder al aan een product gekoppeld, dan wordt die koppeling gebruikt.
  2. Anders wordt gezocht op product.articleCode (hoofdletterongevoelig). Bij precies één match wordt de koppeling automatisch gemaakt en onthouden.
  3. Geen match: het recept wordt wél opgeslagen, en een beheerder kan het later handmatig koppelen.
Stuur dus altijd jullie eigen vaste 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

VeldTypeOmschrijving
product.idstringverplichtVaste ID van het eindproduct in jullie systeem (max 128 tekens)
product.namestringverplichtNaam van het eindproduct
product.articleCodestringaanbevolenArtikelcode in de Spec Builder (bijv. AC104), gebruikt voor automatisch koppelen. Ontbreekt deze, dan wordt product.sku geprobeerd.
product.salesProductbooleanaanbevolenHet 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.codestringoptioneelWorden bewaard ter referentie
recipe.versionstringverplichtVersie van het recept, bijv. "2026-09-01" of "v3"
recipe.descriptionstringoptioneelOmschrijving van het recept
recipe.unitstringoptioneelEenheid van het eindproduct, bijv. Box
recipe.productionLocationstringoptioneelProductielocatie
recipe.shelfLifeDaysnumberoptioneelHoudbaarheid in dagen
recipe.ingredientsarrayverplicht1–500 ingrediënten
…ingredients[].namestringverplichtNaam van het ingrediënt
…ingredients[].quantitynumberverplichtHoeveelheid ingrediënt per eenheid eindproduct, ≥ 0 (decimale punt)
…ingredients[].unitstringverplichtEenheid, bijv. g, ml, Piece
…ingredients[].id, .skustringoptioneelID en grondstofcode in jullie systeem (code wordt ook geaccepteerd)
sourcestringoptioneelNaam van het verzendende systeem, bijv. "snackboxtogo-erp"
sentAtstringoptioneelVerzendtijdstip (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

StatusBetekenis
400Ongeldige payload. details bevat per veld wat er mis is.
401Ontbrekende, ongeldige of ingetrokken API key.
429Te veel mislukte authenticatiepogingen; probeer het na 15 minuten opnieuw.
{ "error": "Ongeldige payload", "details": ["recipeVersion is verplicht"] }