XCAICX docs Product Contact

Getting started

Build the SDK, run the test suite, and watch a complete commercial loop — an OEM buying units, a camera activating, frames being metered, an invoice coming out — on your own machine in about ten minutes.

What you need#

RequirementVersionNotes
CMake≥ 3.16
C++ compilerC++17GCC 7+, Clang 6+, MSVC 2019+
OpenSSL≥ 1.1.1Ed25519 verification. libssl is optional and only needed for HTTPS.
Python≥ 3.11Licensing server, xcaicxctl, and the Python binding
ONNX RuntimeoptionalRequired for production inference. See Backends.

OpenSSL is the only hard dependency, and it is already in every camera BSP. Everything else in the core is in-tree.

1. Build everything and run the tests#

bash
make all

That creates a virtualenv, configures and builds the core, generates the test fixtures, and runs all four suites:

text
test_license              45 checks   signatures, forgery, binding, expiry/grace,
                                      rollback, revocation
test_engine               63 checks   ABI safety, entitlements, stream caps, formats,
                                      zones, quota
server/tests              16 checks   activation, seat accounting, replay dedupe,
                                      revocation, invoicing
bindings/python/tests     14 checks   binding correctness, error mapping, metering

138 checks in total. The build is clean under -Wall -Wextra -Wpedantic.

Note

The licence suites deliberately run tokens minted by the Python signer through the C++ verifier. Those are two independent implementations of the same format, and the drift between them is the thing that actually breaks in the field — so it is the thing the tests aim at.

2. Start the licensing authority#

In one terminal:

bash
make server

This runs the FastAPI licensing authority on :8000. On first run it generates a signing keypair under server/keys/ if one does not exist.

Do not

The signing key is the root of trust for every licence you will ever issue. If it leaks, anyone can mint licences for your SDK and the only remedy is shipping new firmware with a new compiled-in public key. For anything beyond local evaluation, read Running the authority before you generate the key you intend to keep.

3. Watch the whole commercial loop#

In a second terminal:

bash
make demo

The demo registers an OEM, sells them a batch, boots the SDK on a camera holding only the batch key, activates it, runs frames through the pipeline, ships the usage spool, and rates the period:

text
[2] registering an OEM customer and selling a batch
    batch      : B-2026-1C4417D5  (5 units)

[3] booting the SDK on a camera that holds only the batch key
    activated as : LIC-D3ACF708DB6048AB
    bound device : b2cd209a6826bd8b33c0fdaad6304106
    batch now    : 1/5 activated

[4] running 20 frames through the pipeline
    event: LINE_CROSS       zone=doorway track=1
    event: ZONE_ENTER       zone=packing-bay track=1
    metered inferences: 20

[5] heartbeat: shipping the usage spool to the server
    server recorded: 20 inferences, 20 frames, 1 record(s)

[6] fleet and invoice
    XCAICX OEM Industrial (detection + defect + PPE)

Every step in that output corresponds to something documented here: activation is Licensing, the events are Zones, tripwires & events, the counting is Metering & billing, and the endpoints are the REST API.

4. Point it at your own frames#

The fastest way to see the SDK on real imagery is the Python binding, which accepts anything with the buffer protocol — including a numpy array straight out of OpenCV.

python
import cv2
import xcaicx

cap = cv2.VideoCapture(0)

with xcaicx.Engine(license_path="unit.token", state_dir="./state") as eng:
    with eng.stream("webcam", modules=xcaicx.Module.DETECT) as s:
        while True:
            ok, frame = cap.read()
            if not ok:
                break
            h, w = frame.shape[:2]
            result = s.process(frame, width=w, height=h,
                               fmt=xcaicx.PixelFormat.BGR8)
            for d in result.detections:
                x, y, bw, bh = d.box.to_pixels(w, h)
                cv2.rectangle(frame, (x, y), (x + bw, y + bh), (0, 255, 0), 2)
                cv2.putText(frame, f"{d.class_name} {d.score:.2f}", (x, y - 6),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
            cv2.imshow("xcaicx", frame)
            if cv2.waitKey(1) == 27:
                break

numpy is not a dependency of the binding — it just works if you already have it.

Careful

What you will see from the reference backend on a webcam is edges and blobs, classified by aspect ratio. That is the honest behaviour of a heuristic detector and exactly why production deployments ship models. If it looks unimpressive on real imagery, the demo is working correctly.

Where to go next#

Commercial software. Use requires a valid XCAICX licence token. Questions an integrator cannot answer from this page belong in an email to [email protected] — and, usually, in a fix to this page.

© 2026 AZMX AI · xcaicx.com