Analyses
The Analysis resource — run the inklet agent over uploaded Content and the user's history, target a display or a viewport, and wait for the result.
An Analysis is the unit of work. A Content is only the material you submitted; nothing is read, laid out, or rendered until an Analysis references it.
const { content } = await inklet.contents.upload({
assets: [inklet.assets.text("Dentist at 9am tomorrow")],
});
const analysis = await inklet.analyze({
contentIds: [content.id],
intent: "Make a reminder card",
});
const done = await inklet.analyses.wait(analysis);
console.log(done.outcome, done.presentationIds);inklet.analyze() and inklet.direct() are shorthands for
inklet.analyses.analyze() and inklet.analyses.direct().
analyze()
analyze(input?: AnalyzeInput): Promise<Analysis>Prop
Type
| Option | What it does |
|---|---|
contentIds | The Contents to analyze. Naming them rules out no_change: every Content you name appears in at least one Presentation, or the Analysis fails with no_presentable_content. |
context | submitted — only the Contents you named. history — the agent may also retrieve the user's earlier Contents. |
scope | { since: "72h" }, the look-back window for history. A relative duration matching /^\d+[mhd]$/. |
target | Omit to let the agent choose Displays, { displayId } or { displayIds } to pin them, { output } for a display-free Scene or PNG. |
intent | A sentence of direction for the agent. |
title | Overrides the title inklet would generate. |
idempotencyKey | Generated when omitted. See Idempotency. |
context defaults to submitted when contentIds is non-empty and to
history when it is empty. context: "submitted" with no contentIds throws
ConfigurationError, and so does scope on anything but history.
analyze() is never retried automatically. If it fails — a timeout, a dropped
connection, a 5xx — the Analysis may already exist, so call it again with
error.idempotencyKey, the key it sent (generated when you passed none), rather
than a fresh one.
direct()
One uploaded image shown as sent, with no AI:
direct(input: DirectInput): Promise<Analysis>Prop
Type
A direct Analysis requires exactly one contentId, context: "submitted", and
a target. inklet scales the image to the target geometry server-side, which is
what Hardcode Push uses underneath.
create()
create(input: CreateAnalysisRequest, idempotencyKey: string): Promise<Analysis>The same request with mode explicit and the key required —
analyze() and direct() are wrappers over it that generate a key when you do
not supply one.
Targets
type AnalysisTargetInput =
| { displayId: string }
| { displayIds: readonly string[] }
| { output: PresentationOutputRequest };Exactly one of the three keys, or ConfigurationError. Omitting target
entirely is the fourth option, and the one that lets the agent route for you.
An { output } target produces a display-free Presentation — Scene JSON and
PNG renditions, no panel involved. See
Generating without a display.
A targetless Analysis needs at least one display it can actually use. When
the account has none that fits, POST /analyses fails immediately with
422 and code: "no_compatible_display", which the SDK surfaces as an
ApiError. Give a target — including an { output } target — when there
may be no panel.
retrieve() and list()
const analysis = await inklet.analyses.retrieve("analysis_123");
const page = await inklet.analyses.list({
state: "completed",
trigger: "scheduled",
limit: 20,
});Prop
Type
trigger is api for the ones you started and scheduled for the ones
inklet runs on the user's behalf. An out-of-range state, trigger, or
limit throws ConfigurationError locally.
wait()
wait(
analysisOrId: Analysis | string,
options?: WaitForAnalysisOptions,
): Promise<Analysis>Polls until the Analysis is completed and returns it. A failed Analysis
throws AnalysisFailedError, with the backend's own code on
error.details.backendCode.
| Option | Default | Range |
|---|---|---|
pollIntervalMs | 1000 | 100–60,000 |
timeoutMs | 120000 | 1–1,800,000 — a hard deadline for the whole wait, including a read in flight |
signal | — | Aborting throws OperationAbortedError, and cancels a read in flight |
A state this SDK does not know is not treated as final. Up to three failed reads in a row — a dropped connection, a timeout, or HTTP 408, 429, 500, 502, 503, or 504 — are retried with back-off before the error is thrown.
The 120-second default suits a submitted Analysis. Analyses with
context: "history" run one at a time per user, and scheduled ones queue
behind them, so raise timeoutMs for those. A timeout throws
OperationTimeoutError but does not cancel the Analysis —
analyses.retrieve() still returns it once it finishes.
The Analysis type
Prop
Type
States
queued ──→ running ──→ completed
└─→ failedqueued and running are not terminal; completed and failed are. See
Lifecycle.
Outcome
outcome is null until the Analysis finishes, then one of two answers.
| Outcome | Meaning |
|---|---|
presentations | presentationIds is populated. |
no_change | The agent looked and decided nothing was worth showing. noChangeReason says why. |
no_change is a normal completion, not a failure, and it is only reachable
when the Analysis named no contentIds. Name a Content and inklet either
covers it or fails the Analysis with no_presentable_content.
Scope and the history window
Prop
Type
since is resolved to an absolute sinceAt when the Analysis is created, so
an Analysis that sits in queued still reads the window it was created with.
The plan caps how far back history reaches, and an earlier since is clamped
to that floor rather than rejected — compare scope.sinceAt against what you
asked for when you need to tell a user how much was really covered. See
Plans.
Following a run
An Analysis publishes an ordered event stream while it works. It has its own page:
archive()
const { url, expiresAt } = await inklet.analyses.archive("analysis_123");A short-lived download URL for the run archive. Throws NotFoundError with
code: "archive_not_found" when there is none — while the Analysis is still
running, or after retention has expired.
Contents
The Content resource in the inklet SDK — upload assets to storage, refresh upload tickets, and read what a Content became.
Analysis events
The public inklet Analysis event stream — the closed set of event types, their payloads, and how to follow a run live with watch, timeline, and listEvents.