Getting started
Install @inklethq/sdk, authenticate with a personal access token, and push your first content to an inklet display.
Install
npm install @inklethq/sdkNode.js 22 or newer is required.
Create a token
Personal access tokens are issued in the Portal dashboard. Keep the token in your environment, never in source control:
INKLET_PAT=your-token-hereInitialize the client
import { Inklet } from "@inklethq/sdk";
const inklet = new Inklet({ pat: process.env.INKLET_PAT! });Construction is side-effect free — configuration is validated, but no request is made until you call something. CommonJS works too:
const { Inklet } = require("@inklethq/sdk");Find a display
const page = await inklet.displays.list({ limit: 20 });
for (const display of page.items) {
console.log(display.id, display.name, display.online);
}Push something
Auto Push uses inklet AI and requires Pro. Free accounts can follow the same setup with Hardcode Push, which accepts a finished PNG or JPEG without AI processing.
const result = await inklet.push.auto({
title: "Grocery list",
assets: [inklet.assets.text("Milk, eggs, coffee")],
});
console.log(result.contentId, result.analysisId, result.state);Wait for it to land
The call above returns as soon as inklet has your assets and has accepted the
Analysis — usually with state: "queued" and no Presentation IDs yet. Wait for
the run to finish:
const analysis = await inklet.analyses.wait(result.analysisId);
if (analysis.outcome === "no_change") {
console.log("nothing worth showing:", analysis.noChangeReason);
} else {
console.log("presentations:", analysis.presentationIds);
}A failed Analysis throws AnalysisFailedError. To watch the run instead of
waiting on it, see Analysis events.
A complete example
import { Inklet, InkletError } from "@inklethq/sdk";
import { readFile } from "node:fs/promises";
const inklet = new Inklet({ pat: process.env.INKLET_PAT! });
async function main() {
const chart = inklet.assets.image({
data: await readFile("chart.png"),
filename: "chart.png",
contentType: "image/png",
});
const result = await inklet.push.auto({
idempotencyKey: `daily-brief-${new Date().toISOString().slice(0, 10)}`,
title: "Daily brief",
intent: "Lead with the number, keep the chart secondary",
assets: [
inklet.assets.text("Revenue is up 12% week over week."),
chart,
],
});
console.log(`analysis ${result.analysisId} (${result.state})`);
}
main().catch((error) => {
if (error instanceof InkletError) {
console.error(error.code, error.status, error.requestId);
}
process.exitCode = 1;
});The idempotency key above is derived from the date, so re-running the script on the same day replays the same push rather than creating a second one. See Idempotency.
Next
- Authentication — tokens, environments, and pointing at a Compute Hub
- Plans and AI features — Free vs. Pro, quotas, and history depth
- Pushing content — the differences between Auto, Manual, and Hardcode
- Lifecycle — states, idempotency, and knowing when a frame is real
- Analyses — the full surface behind
push.*
Introduction
The server-side TypeScript SDK for inklet e-ink displays — push text, links, images, and PDFs, and let inklet handle layout, routing, and rendering.
Authentication
How the inklet SDK authenticates with a personal access token, why it is server-only, and how to point it at a Compute Hub instead of the cloud.