Instnt Print v1.0.0
Print labels en bonnen vanaf elk systeem dat een HTTP-verzoek kan doen. Geen driver, geen wachtrij op een pc: je stuurt wat erop moet, en er komt papier uit.
Alles gaat over sjablonen. Een sjabloon legt de vorm vast; jij stuurt alleen de gegevens die per keer verschillen.
In vijf minuten
Maak een sleutel aan in het dashboard onder Sleutels, kijk welke printers en templates je hebt, en stuur er iets naartoe.
# wat heb ik?
curl https://instntprint.com/v1/printers \
-H "Authorization: Bearer $SLEUTEL"
# print een bon
curl -X POST https://instntprint.com/v1/jobs \
-H "Authorization: Bearer $SLEUTEL" \
-H "Idempotency-Key: bon-1043" \
-H "Content-Type: application/json" \
-d '{
"printer": "Kassa balie",
"template": "Kassabon",
"data": {
"bonnummer": "1043",
"totaal": "17,45",
"regels": [
{"aantal": "2", "omschrijving": "Koffie", "bedrag": "6,40"}
]
}
}'
Zonder template kan ook — dan zijn het gewoon regels tekst op het label dat in de printer zit:
curl -X POST https://instntprint.com/v1/jobs \
-H "Authorization: Bearer $SLEUTEL" \
-H "Content-Type: application/json" \
-d '{"lines": ["Magazijn 3", "Stelling B", "vak 12"]}'
Sleutels
Elke aanroep draagt een integratiesleutel in de
Authorization-header. De sleutel bepaalt bij welke
organisatie het hoort — niet iets in het verzoek zelf. Zo kan niemand
met de printernaam van een ander papier laten komen.
Een sleutel die begint met lbl_test_ doet alles behalve
printen: de template wordt gerenderd, de opdracht komt in je
overzicht, maar er komt geen papier uit. Bouw daarmee, en zet hem om
als het klopt.
Houd een sleutel op je eigen server. Alles wat in een webpagina of app staat, kan een gebruiker lezen.
Twee keer versturen
Netwerken haperen, en een kassa waar iemand twee keer op afrekenen
drukt hoort niet twee bonnen te printen. Geef daarom bij elke opdracht
een Idempotency-Key mee: een tekst die díe ene gebeurtenis
beschrijft, zoals een bonnummer of een ordernummer.
Stuur je hem nog eens, dan krijg je het eerste antwoord terug met
Idempotent-Replay: true in de header — en er komt niets
uit de printer.
Als het misgaat
Fouten komen terug met een gewone HTTP-code en een uitleg in gewone
taal. 404 is een naam die niet bestaat, 400
een verzoek dat niet klopt, 503 een printer die niet
bereikbaar is. Die laatste is meestal tijdelijk: probeer het opnieuw
met dezelfde idempotentiesleutel, dan kan er niets dubbel gebeuren.
Terug horen
Een opdracht wordt aangenomen en daarna geprint — soms meteen, soms een
minuut later omdat de printer nog uit stond. Je kunt blijven vragen met
GET /v1/jobs/{id}, maar makkelijker is het om ons te laten
bellen.
Meld een adres aan met POST /v1/webhooks, of in het
dashboard onder Meldingen. Je krijgt een geheim terug dat je
bewaart.
POST /v1/webhooks
{"url": "https://jouwsysteem.nl/instnt",
"events": ["job.done", "job.failed"]}
Wat er binnenkomt
POST https://jouwsysteem.nl/instnt
X-Instnt-Event: job.done
X-Instnt-Delivery: whd_…
X-Instnt-Timestamp: 1772100000
X-Instnt-Signature: sha256=…
{"event": "job.done",
"created_at": 1772100000.4,
"data": {"id": "job_…", "status": "done", "printer": "Kassa",
"template": "Kassabon", "copies": 1, "error": null}}
De handtekening nakijken
Dat is één regel, en sla hem niet over: zonder controle kan iedereen die je adres raadt jouw systeem laten denken dat er iets geprint is.
# Python
verwacht = hmac.new(geheim.encode(),
tijdstip.encode() + b"." + lichaam,
hashlib.sha256).hexdigest()
klopt = hmac.compare_digest(f"sha256={verwacht}", handtekening)
Weiger ook wat ouder is dan een paar minuten — dan kan een onderschept bericht niet later opnieuw worden aangeboden.
Als jouw kant even weg is
Wij proberen het drie keer: meteen, na twintig seconden en na twee
minuten. Alles wat met 2xx antwoordt geldt als aangekomen.
Blijft het misgaan, dan zetten we de webhook na vijfentwintig
mislukkingen op rij uit — je ziet in het dashboard waarom.
Antwoord snel en doe het werk daarna. Een ontvanger die er tien seconden over doet, houdt de volgende bezorging op.
Iemand anders laten printen
Het omgekeerde geval: een webshop of formulierendienst die wél een webhook kan versturen, maar waarvan je de uitgaande aanroep niet kunt aanpassen. Die stuurt zijn eigen JSON, in zijn eigen vorm.
Maak in het dashboard onder Meldingen een inkomend adres aan.
Dat ziet eruit als /api/in/… met een lang, willekeurig
stuk erachter — dat stuk is het geheim, dus deel het adres alleen met
het systeem dat het nodig heeft. Je zegt erbij welk veld van hen bij
welk veld van jouw template hoort:
{"klant": "$.customer.name",
"totaal": "$.total",
"zaak": "Café Instnt Coffee"}
Alles dat met $. begint is een pad in hún bericht —
$.items[0].sku mag ook. De rest is een vaste waarde die er
altijd bij hoort. Een pad dat niet bestaat valt weg in plaats van de
hele afdruk te laten stuklopen.
Voor bonnen met artikelregels wijs je hun lijst aan, en zeg je per rij welk veld waar vandaan komt.
Zit er in hun bericht een id, order_id of
reference, dan gebruiken we dat als idempotentiesleutel.
Webhooks worden opnieuw verstuurd als het antwoord wegvalt — dat is
juist hun kracht — en zonder sleutel levert dat een tweede bon op.
Endpoints
POST /v1/jobs
Print één label of bon
Stuur een sjabloonnaam met de gegevens die erin moeten, of lines met kale tekstregels.
Antwoordt met 202 en een opdracht-id: de printer kan uit staan, en daar mag jouw systeem niet op wachten. Wil je het tóch meteen weten, geef dan ?wait=true mee — dan komt er 200 zodra hij klaar is.
Parameters
| Naam | Waar | Wat het doet |
|---|---|---|
wait | query | Wacht tot de printer klaar is. |
Idempotency-Key | header | Een tekst die deze ene gebeurtenis beschrijft — een bonnummer, een ordernummer. Stuur je hem twee keer, dan krijg je het eerste antwoord terug en komt er geen tweede bon uit. Onmisbaar zodra er een netwerk tussen zit. |
Wat je stuurt
| Veld | Soort | Wat het doet |
|---|---|---|
printer | string | De naam uit het dashboard. Heb je er één, dan mag dit weg. |
template | string | |
data | object | De velden van het sjabloon. Een lijst (zoals de regels van een bon) zet je hier als array onder zijn eigen naam. |
lines | array | Zonder sjabloon: kale tekstregels op het label dat in de printer zit. |
copies | integer | |
label | string | Ander formaat dan wat er volgens de instellingen in zit. |
cut | boolean | Alleen bij bonprinters. |
drawer | boolean | Open de kassalade. |
reverse | boolean | Print het ontwerp een halve slag gedraaid, voor een printer die ingebouwd staat. |
sample | boolean | Vul lege velden met aannemelijke inhoud. Voor een proefdruk. |
idempotency_key | string |
Voorbeeld
{
"printer": "Kassa balie",
"template": "Kassabon",
"data": {
"bonnummer": "1043",
"totaal": "17,45",
"regels": [
{
"aantal": "2",
"omschrijving": "Koffie",
"bedrag": "6,40"
}
]
}
}Wat je terugkrijgt
| Code | Betekenis |
|---|---|
202 | Aangenomen; staat in de rij. |
200 | Klaar (bij |
404 | Onbekende printer of sjabloon. |
400 | Er staat iets niet goed in het verzoek — bij meerdere printers zonder keuze bijvoorbeeld. |
503 | De printer is niet bereikbaar. |
POST /v1/jobs/batch
Print een reeks
Elke rij wordt een label. Naar een bonprinter wordt de hele reeks juist één bon — veertig regels horen op één bon te staan, niet veertig bonnetjes te worden.
Elke rij krijgt een eigen sleutel, afgeleid van die van de reeks. Een herhaalde aanroep levert dus geen dubbele labels op, ook niet als hij halverwege afbrak.
Wat je stuurt
| Veld | Soort | Wat het doet |
|---|---|---|
printer | string | |
template | string | |
rows verplicht | array | Per rij de velden voor één label. |
into | string | Bij een bon: onder welke lijstnaam de rijen het sjabloon in gaan. |
idempotency_key | string |
Voorbeeld
{
"into": "regels"
}Wat je terugkrijgt
| Code | Betekenis |
|---|---|
202 | Aangenomen. |
GET /v1/jobs/{id}
Hoe staat het met een opdracht
Parameters
| Naam | Waar | Wat het doet |
|---|---|---|
id | path |
Wat je terugkrijgt
| Code | Betekenis |
|---|---|
200 | De opdracht. |
404 | Onbekende opdracht. |
GET /v1/webhooks
Welke webhooks er staan
Wat je terugkrijgt
| Code | Betekenis |
|---|---|
200 | De webhooks van jouw organisatie. |
POST /v1/webhooks
Een webhook aanmelden
Wij bellen jouw adres zodra er iets gebeurt, in plaats van dat jij blijft vragen. Elk bericht is ondertekend met het geheim dat je hier terugkrijgt: X-Instnt-Signature is sha256= gevolgd door een HMAC-SHA256 over tijdstip.lichaam, met X-Instnt-Timestamp als tijdstip. Weiger wat ouder is dan een paar minuten.
Mislukt de bezorging, dan proberen we het nog twee keer: na twintig seconden en na twee minuten.
Wat je stuurt
| Veld | Soort | Wat het doet |
|---|---|---|
url verplicht | string | |
events verplicht | array |
Voorbeeld
{
"url": "https://jouwsysteem.nl/instnt",
"events": [
"job.done",
"job.failed"
]
}Wat je terugkrijgt
| Code | Betekenis |
|---|---|
201 | Aangemeld. Bewaar het geheim. |
400 | Het adres wijst naar een netwerk in plaats van naar buiten, of er is geen gebeurtenis gekozen. |
DELETE /v1/webhooks/{id}
Een webhook afmelden
Parameters
| Naam | Waar | Wat het doet |
|---|---|---|
id | path |
Wat je terugkrijgt
| Code | Betekenis |
|---|---|
200 | Afgemeld. |
GET /v1/printers
Welke printers er zijn
Met kind erbij: label of receipt. Daarmee weet je waar een sjabloon naartoe kan zonder het aan de modelnaam te hoeven raden.
Wat je terugkrijgt
| Code | Betekenis |
|---|---|
200 | De printers van jouw organisatie. |
GET /v1/templates
Welke sjablonen er zijn
Met per sjabloon de velden die het verwacht, en welk soort invoer erbij hoort — genoeg om er een formulier van te bouwen zonder de vorm te kennen.
Wat je terugkrijgt
| Code | Betekenis |
|---|---|
200 | De sjablonen van jouw organisatie. |
POST /v1/preview
Een voorbeeld als afbeelding
Hetzelfde verzoek als printen, maar er komt een PNG terug in plaats van papier. Handig om te laten zien wat er gaat gebeuren.
Wat je terugkrijgt
| Code | Betekenis |
|---|---|
200 | De afdruk als afbeelding. |