Official server-side JavaScript and TypeScript SDK for Inklet.
The v0.1 release supports PAT authentication, Display and Presentation reads, Content lifecycle operations, and high-level Auto, Manual, and Hardcode Push workflows.
- Node.js 20 or newer
- An Inklet personal access token (PAT)
- A trusted server environment
Never expose a PAT in a browser bundle. The SDK rejects browser use before a request is sent.
npm install @inklethq/sdkimport { Inklet } from "@inklethq/sdk";
const inklet = new Inklet({
pat: process.env.INKLET_PAT!,
});CommonJS is supported too:
const { Inklet } = require("@inklethq/sdk");
const inklet = new Inklet({ pat: process.env.INKLET_PAT });secretKey remains available as a compatibility alias for pat; do not pass
both options. Client construction validates configuration without making a
network request.
The default service address is https://dev.iminklet.com. A controlled local
or test service can be selected with baseUrl.
const page = await inklet.displays.list({ limit: 20 });
const display = await inklet.displays.retrieve(page.items[0].id);
const queue = await inklet.displays.listQueue(display.id, {
from: new Date("2026-08-01T00:00:00Z"),
limit: 20,
});
const current = await inklet.displays.current(display.id, { format: "png" });
if (current) {
const presentation = await inklet.presentations.retrieve(current.id, {
format: "raw2",
});
}displays.current() is read-only and returns null when the Display has no
confirmed Presentation.
Asset helpers validate supported content types and the 10 MiB per-binary-asset limit. Binary assets are uploaded directly to temporary storage URLs; the PAT is sent only to Inklet API endpoints.
Auto Push lets Inklet choose compatible Displays.
const result = await inklet.push.auto({
idempotencyKey: "daily-brief-2026-08-12",
title: "Daily brief",
intent: "Make the key update easy to scan",
assets: [
inklet.assets.text("Revenue is up 12% week over week."),
inklet.assets.link("https://example.com/report"),
],
});Manual Push targets one Display while allowing Inklet to process and lay out the supplied assets.
import { readFile } from "node:fs/promises";
const image = inklet.assets.image({
data: await readFile("chart.png"),
filename: "chart.png",
contentType: "image/png",
});
const result = await inklet.push.manual({
displayId: "display_123",
assets: [image, inklet.assets.text("This week's trend")],
});Hardcode Push targets one Display and accepts exactly one PNG or JPEG. Inklet keeps the existing server behavior: it automatically scales the submitted image to the Display output size. The SDK intentionally does not require the source image dimensions to match the panel.
import { readFile } from "node:fs/promises";
const result = await inklet.push.hardcode({
displayId: "display_123",
image: inklet.assets.image({
data: await readFile("poster.jpg"),
filename: "poster.jpg",
contentType: "image/jpeg",
}),
});All high-level Push methods return the Content, generated idempotency key, and
known Presentation IDs. When idempotencyKey is omitted, the SDK generates
one and returns it in the result. For caller-controlled retries, supply and
reuse your own key.
Push processing is asynchronous. A successful call commonly returns a
processing Content with no Presentation IDs yet. Poll
inklet.contents.retrieve(result.contentId) until the Content becomes ready
or failed. A ready Content means its Presentation IDs are persisted; an
individual Presentation may briefly remain preparing while the render worker
finishes the PNG, RAW2, and RAW4 files.
The lower-level Content resource is available when an application needs to control individual lifecycle calls:
const content = await inklet.contents.retrieve("content_123");
const contents = await inklet.contents.list({ mode: "manual", state: "ready" });
const confirmed = await inklet.contents.confirm(content.id);contents.create() and contents.refreshUploadTickets() are also public, but
most applications should use inklet.push.*, which handles upload tickets,
one ticket refresh/retry, and confirmation.
Every SDK error extends InkletError. Backend error codes, status, request ID,
and structured details are preserved.
import {
AuthenticationFailedError,
InkletError,
RateLimitError,
} from "@inklethq/sdk";
try {
await inklet.displays.list();
} catch (error) {
if (error instanceof AuthenticationFailedError) {
// Replace or reactivate the PAT.
} else if (error instanceof RateLimitError) {
// Retry according to your application policy.
} else if (error instanceof InkletError) {
console.error(error.code, error.requestId, error.details);
}
}Authenticated requests refuse absolute URLs and cross-origin redirects. Credentials are redacted from errors, and storage uploads never include the PAT.
npm ci
npm run check
npm run pack:checknpm run check builds ESM and CommonJS output, runs strict TypeScript checks,
and executes the test suite.