inklet docs

Displays

Reading inklet displays — list, retrieve, queue, the confirmed presentation — and switching what a panel shows.

Displays are bound to your account through the Portal or the mobile app; the SDK observes them, and can change which already-rendered frame a panel is showing.

list()

const page = await inklet.displays.list({ limit: 20 });
list(options?: ListDisplaysOptions): Promise<DisplayPage>

Prop

Type

Returns a cursor page:

Prop

Type

Paging through everything:

let cursor: string | undefined;
const all = [];

do {
  const page = await inklet.displays.list({ cursor, limit: 50 });
  all.push(...page.items);
  cursor = page.nextCursor ?? undefined;
} while (cursor);

A limit outside 1–50, or a non-integer, throws ConfigurationError locally.

retrieve()

const display = await inklet.displays.retrieve("display_123");

Throws NotFoundError if the id is unknown, and ConfigurationError if the id is not a non-empty string.

listQueue()

What is waiting to go on the panel, oldest first within a priority, optionally within a time range:

const queue = await inklet.displays.listQueue(display.id, {
  from: new Date("2026-08-01T00:00:00Z"),
  to: new Date(),
  limit: 20,
});
listQueue(displayId: string, options?: ListDisplayQueueOptions): Promise<DisplayQueuePage>

Prop

Type

from and to accept a Date or anything new Date() parses; both are sent as ISO strings. An unparseable value, or to earlier than from, throws ConfigurationError.

Each item:

Prop

Type

The queue only ever holds queued Presentations. Once one is delivered it leaves the queue, and the frame it replaces expires rather than going back in. For the display's full history — the published, confirmed, and expired ones too — use presentations.list({ displayId }).

current()

The confirmed Presentation a display is showing, or null:

const current = await inklet.displays.current(display.id, { format: "png" });

if (current?.image) {
  console.log(current.image.url);
} else {
  console.log("nothing confirmed yet");
}
current(displayId: string, options?: { format?: "png" | "raw2" | "raw4" }): Promise<Presentation | null>

null is a normal answer, not an error — a display that has never confirmed a frame has no current Presentation. Handle it before reading .image.

Changing what is on the panel

Picking what a panel shows needs no AI and no new Content. Neither call below consumes AI or push quota.

setCurrent()

await inklet.displays.setCurrent(display.id, presentation.id);
setCurrent(displayId: string, presentationId: string, options?: CallOptions): Promise<Display>

The Presentation must be one of yours, of kind: "display", already delivered to this display, and finished rendering. An expired one can be reactivated — that is how "go back to the previous image" works. Anything else is a ConflictError:

details.reasonMeaning
targetlessThe Presentation has no target display, so it cannot go on a panel.
not_deliveredIt was never delivered to any display.
other_displayIt was delivered to a different panel.
not_renderedIt has no rendered image yet.

Branch on error.details.reason, not on error.message. The four reasons above are the stable part. The whole envelope is 409 with code: "presentation_not_deliverable" and details: { displayId, reason, presentationId }.

The frame that was on the panel becomes expired; it does not go back into the queue. The switch lands on pendingPresentationId, and currentPresentationId follows once the panel confirms — which for an offline panel is its next sync.

advance()

const { changed } = await inklet.displays.advance(display.id);

Rotates to the next queued Presentation, highest priority first and oldest first within a priority. changed: false means the queue was empty, which is a normal 200 and changes nothing — not an error. Otherwise the effect matches setCurrent().

Neither setCurrent() nor advance() is retried automatically. A retried advance() after a lost response would skip a second Presentation, so after a network error read the display and check pendingPresentationId before calling it again.

waitUntilCurrent()

await inklet.displays.waitUntilCurrent(display.id, presentation.id, {
  timeoutMs: 10 * 60_000,
});

Polls until the display reports presentationId as its confirmed current Presentation. pollIntervalMs defaults to 1,000 ms and timeoutMs to 120,000 ms. Up to three failed reads in a row — a dropped connection, a timeout, or HTTP 408, 429, or 5xx — are retried with back-off.

A timeout throws OperationTimeoutError and does not cancel the switch — the panel still shows the Presentation once it syncs. error.details carries displayId, presentationId, pendingPresentationId, and timeoutMs.

The Display type

Prop

Type

FieldNotes
name / nicknamename is the bound device name; nickname is user-set and may be null.
tagsFree-form labels — a practical routing key for Manual pushes.
onlineWhether the panel is currently reachable.
syncIntervalMinutesHow often it wakes to ask for work.
nextSyncAtWhen to expect the next pickup.
pendingPresentationIdHanded over but not yet confirmed.

Capabilities

Prop

Type

Read these before sending format-sensitive content — particularly for Hardcode pushes, where you control the pixels.

On this page