Skip to content

API overview

Every capability of a MyCustomerDisplay device is exposed through one JSON API, available over two transports:

  • REST + WebSocket, over the USB network link (http://10.99.0.1) — the primary, recommended path for any host with a network stack.
  • NDJSON over the USB serial link (a CDC-ACM port) — the same operations, framed as newline-delimited JSON, for hosts that would rather not bring up a network interface (or that talk to the device from a browser via WebSerial).

Both transports carry the same contract: the same paths, the same request/response JSON shapes, the same event topics, the same error codes. api/openapi.yaml in the repository is the normative source of the contract; this site follows it. Anything you build against one transport works, unmodified in shape, against the other.

flowchart LR
    subgraph HOST["Host machine"]
        APP["Your application"]
    end
    subgraph LINK["Single USB cable"]
        NET["Network link\nHTTP + WebSocket\n10.99.0.1"]
        SER["Serial link\nNDJSON over CDC-ACM"]
    end
    subgraph DEV["MyCustomerDisplay device"]
        API["displayd — one API contract"]
    end
    APP -->|REST / WS| NET --> API
    APP -->|NDJSON| SER --> API

Which transport should I use?

Network (REST/WS) Serial (NDJSON)
Setup Composite USB gadget interface; no drivers on Windows/Linux/macOS Same cable, a second USB function (CDC-ACM); serial port drivers are OS built-in
Throughput Full network speed ~1–5 Mbit/s effective
Binary uploads (bundles, splash images, OTA) Native streaming Chunked base64 — functional but slow; discouraged for large payloads
Concurrency Parallel requests Serialized, correlated by request id
Best for Most integrations, especially anything uploading content or update bundles Simple hosts, embedded control boards, in-browser WebSerial pages, or as an automatic fallback

If you use the Go client library, you don't have to choose: it tries the network transport first and falls back to serial automatically, exposing the active transport if your application wants to react to degraded mode.

Versioning

  • The API is versioned under /api/v1. Backward-incompatible changes would move to /api/v2; the current contract only ever adds fields/endpoints/values within v1.
  • All JSON payloads are UTF-8, field names are snake_case (a few fields that mirror an external standard — like NdefRecord.recordType for future Web NFC compatibility — are the documented exception).
  • The device serves its own OpenAPI document at GET /api/v1/openapi.yaml, so a host can introspect the exact contract a given firmware version implements.

No authentication

The API is fully usable without authentication. This is a deliberate design choice, not an oversight: the USB link itself is the trust boundary (physical possession of the cable is what grants control), and every capability — including factory reset and firmware updates — is reachable without a login step. Do not expose 10.99.0.1 beyond the point-to-point USB link (e.g. don't NAT/route it onto a shared network) — nothing on the device will stop a second party from controlling it if they can reach that address.

What's next