Waarom een REST API voor de Zebra ZC350?
De Zebra ZC350 is een uitstekende kaartprinter, maar de standaard-aansturing is dat niet. Wie de printer wil koppelen aan een eigen workflow zit in de praktijk vast aan drie ongemakken: een Windows-werkplek per printer, een USB-kabel tussen werkplek en hardware, en een vendor-driverstack (CardStudio plus Silex SX Virtual Link) die je per werkstation installeert en onderhoudt. Voor één receptie misschien acceptabel; voor een corporate of multi-site setup een operationele nachtmerrie.
ConoCard biedt een alternatief op het juiste niveau: een HTTP-server die de printer over IP aanstuurt. Eén POST-call met de gewenste kaartdata, de server doet print, encode, contactloze UID-uitlezing en registratie in 2N Access Commander, en geeft JSON terug. Geen driver, geen USB, geen werkplek-installs.
De primaire endpoint: POST /api/issue
Eén endpoint dekt 90% van de operationele behoefte. Je geeft door wat er op de kaart moet, voor wie de pas is, en optioneel welke printer (bij multi-printer setups). De server handelt de rest af.
Authenticatie
Alle calls vereisen een bearer-token in de Authorization-header. Tokens worden constant-time vergeleken (geen timing-leaks). De service is secure-by-default: zonder geconfigureerd token weigert ConoCard te starten.
Authorization: Bearer your-token-here
Request body (voorbeeld)
{
"guest": {
"name": "Jane Doe",
"reference": "booking-1234"
},
"validity": {
"from": "2026-06-01T15:00:00Z",
"until": "2026-06-05T11:00:00Z"
},
"printer": "192.168.1.42"
}
Response (JSON)
{
"status": "issued",
"uid": "04A5B6C7D8E9",
"printed_at": "2026-05-30T13:42:18Z",
"registered_in": "2n-access-commander",
"audit_id": "01HXYZ..."
}
Codevoorbeelden
curl
curl -X POST https://conocard.local/api/issue \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"guest":{"name":"Jane Doe"},"printer":"192.168.1.42"}'
Python (requests)
import requests, os
r = requests.post(
"https://conocard.local/api/issue",
headers={"Authorization": f"Bearer {os.environ['CONOCARD_TOKEN']}"},
json={
"guest": {"name": "Jane Doe"},
"printer": "192.168.1.42",
},
timeout=30,
)
r.raise_for_status()
print(r.json()["uid"])
PHP
// guzzlehttp/guzzle
$client = new GuzzleHttp\Client();
$resp = $client->post('https://conocard.local/api/issue', [
'headers' => ['Authorization' => 'Bearer ' . $token],
'json' => ['guest' => ['name' => 'Jane Doe'], 'printer' => '192.168.1.42'],
]);
$uid = json_decode($resp->getBody(), true)['uid'];
Node.js (fetch)
const res = await fetch("https://conocard.local/api/issue", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.CONOCARD_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ guest: { name: "Jane Doe" }, printer: "192.168.1.42" }),
});
const { uid } = await res.json();
Audit-log: JSON-Lines direct naar je SIEM
Elke uitgifte — succes én fout — wordt geschreven naar een append-only audit-log in JSON-Lines-formaat. Eén regel per gebeurtenis, direct inleesbaar door Splunk, ELK, Microsoft Sentinel of een andere SIEM. Geen parsers, geen schema-conversies.
{"ts":"2026-05-30T13:42:18Z","event":"issue.success","uid":"04A5B6C7D8E9","printer":"192.168.1.42","source":"api/jane.doe"}
{"ts":"2026-05-30T13:43:02Z","event":"issue.error","reason":"printer_unreachable","printer":"192.168.1.43"}
Meerdere printers vanaf één server
Eén instance kan meerdere ZC350's tegelijk bedienen via een gedeelde control-plane met source-IP demux. In de praktijk: configureer de printer-IP per request, of leg een vooraf gedefinieerde mapping vast in de service-config. Geen één-op-één relatie tussen server en printer.
Voor multi-site scenario's draaien meestal één instance per locatie (in een Linux-VM of Windows-server), of een centrale instance met VPN-koppeling naar de locaties. Een centraal multi-site managementdashboard staat op de roadmap.
ConoCard REST API vs. de Zebra-stack
| Aspect | Zebra CardStudio + Silex | ConoCard REST API |
|---|---|---|
| Aansturing | USB-tether per werkplek | HTTP over IP |
| OS | Windows-only | Linux + Windows |
| Driver-install per werkplek | Ja | Nee |
| Authenticatie | OS-gebruiker | Bearer-token, secure-by-default |
| Audit-trail | Geen gestandaardiseerd | Append-only JSON-Lines |
| UID-readback in dezelfde sessie | Apart, los proces | Inline in de response |
| Multi-printer per host | Niet schaalbaar | Source-IP demux |
| Integratie met externe systemen | Geen API | REST + webhook-output |
Veelgestelde vragen
Heb ik een Zebra-driver nodig?
Nee. De ZC350 wordt volledig over IP aangestuurd via een herimplementatie van het Silex SX-200 USB-over-IP-protocol. Geen Zebra-driver, geen CardStudio, geen Silex SX Virtual Link.
Welke endpoints zijn er?
De primaire endpoint is POST /api/issue. Daarnaast zijn er health- en status-endpoints (GET /api/health, GET /api/status) voor monitoring en service-checks.
Wat als de printer niet bereikbaar is?
De call geeft een 503 met een gestructureerde foutreden (printer_unreachable). De gebeurtenis landt ook in de audit-log zodat je later kunt analyseren wanneer en hoe vaak dit gebeurt.
Kan ik vanuit een mobile app aanroepen?
Ja. De endpoint is HTTP-only — alles wat HTTP spreekt (een mobiele app, een Access Commander-box, een receptionist-tablet) kan een issuance aanvragen.
Hoe verhoudt dit zich tot CardStudio?
CardStudio is een desktop-tool per werkplek, zonder API. ConoCard vervangt dat patroon door één server-side service die over IP werkt. Zie de CardStudio alternatief-pagina voor de migratiekant.