Part of Conocido ICT — software built in-house
info@conocido.nl · +31 70 7820 100
ConoCard · Reference

Zebra ZC350 REST API

The complete REST spec to drive the Zebra ZC350 card printer server-side — driverless, over IP, from Linux or Windows. Including contactless UID readback in the same session and registration in 2N Access Commander.

Why a REST API for the Zebra ZC350?

The Zebra ZC350 is an excellent card printer, but its standard control path isn't. Anyone wanting to integrate the printer into their own workflow runs into three operational frictions: a Windows workstation per printer, a USB cable between workstation and hardware, and a vendor driver stack (CardStudio plus Silex SX Virtual Link) that has to be installed and maintained per workstation. Acceptable for a single reception desk — an operational nightmare for corporate or multi-site setups.

ConoCard offers an alternative at the right level: an HTTP server that drives the printer over IP. One POST call with the desired card data, and the server handles printing, encoding, contactless UID readback and registration in 2N Access Commander, returning JSON. No driver, no USB, no workstation installs.

The primary endpoint: POST /api/issue

One endpoint covers 90% of operational needs. You pass what should be on the card, who the card is for, and optionally which printer (in multi-printer setups). The server takes care of the rest.

Authentication

All calls require a bearer token in the Authorization header. Tokens are compared in constant time (no timing leaks). The service is secure by default: ConoCard refuses to start without a configured token.

Authorization: Bearer your-token-here

Request body (example)

{
  "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..."
}

Code samples

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 straight to your SIEM

Every issuance — success and failure — is written to an append-only audit log in JSON-Lines format. One line per event, ingestible directly by Splunk, ELK, Microsoft Sentinel or any other SIEM. No parsers, no schema conversions.

{"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"}

Multiple printers from one server

One instance can serve several ZC350s concurrently through a shared control plane with source-IP demux. In practice: configure the printer IP per request, or pre-define a mapping in the service config. No one-to-one relationship between server and printer.

For multi-site scenarios it's typical to run one instance per location (in a Linux VM or Windows server), or a central instance with VPN connectivity to the sites. A central multi-site management dashboard is on the roadmap.

ConoCard REST API vs. the Zebra stack

AspectZebra CardStudio + SilexConoCard REST API
Control pathUSB tether per workstationHTTP over IP
OSWindows onlyLinux + Windows
Driver install per workstationYesNo
AuthenticationOS userBearer token, secure by default
Audit trailNothing standardisedAppend-only JSON-Lines
UID readback in the same sessionSeparate, manualInline in the response
Multi-printer per hostNot scalableSource-IP demux
Integration with external systemsNo APIREST + webhook output

Frequently asked questions

Do I need a Zebra driver?

No. The ZC350 is driven entirely over IP through a reimplementation of the Silex SX-200 USB-over-IP protocol. No Zebra driver, no CardStudio, no Silex SX Virtual Link.

Which endpoints are exposed?

The primary endpoint is POST /api/issue. In addition there are health and status endpoints (GET /api/health, GET /api/status) for monitoring and service checks.

What if the printer is unreachable?

The call returns a 503 with a structured failure reason (printer_unreachable). The event also lands in the audit log so you can analyse later when and how often this happens.

Can I call from a mobile app?

Yes. The endpoint is HTTP only — anything that speaks HTTP (a mobile app, an Access Commander box, a reception tablet) can request an issuance.

How does this compare to CardStudio?

CardStudio is a per-workstation desktop tool without an API. ConoCard replaces that pattern with one server-side service over IP. See the CardStudio alternative page for the migration angle.

Live demo or quote?

We're happy to show the API in action on a physical ZC350. Schedule a demo or ask us directly.

Book a demo →