Aller au contenu principal

Node SDK (server)

@jodaprint/node

Classes​

JodaPrintApiError​

An error answer from the REST API ({ error: { code, message, details }, requestId }).

Extends​

  • Error

Constructors​

Constructor​

new JodaPrintApiError(status, code, message, retryable, details, requestId): JodaPrintApiError

Parameters​
status​

number

code​

AnyErrorCode | "NETWORK_ERROR"

message​

string

retryable​

boolean

details​

Record<string, unknown> | undefined

requestId​

string | undefined

Returns​

JodaPrintApiError

Overrides​

Error.constructor

Properties​

code​

readonly code: AnyErrorCode | "NETWORK_ERROR"

details​

readonly details: Record<string, unknown> | undefined

name​

readonly name: "JodaPrintApiError" = "JodaPrintApiError"

Overrides​

Error.name

requestId​

readonly requestId: string | undefined

retryable​

readonly retryable: boolean

status​

readonly status: number


JodaPrintClient​

Client for the JodaPrint REST API v1 (cloud mode). Runs on Node 18+, Deno and Bun.

Constructors​

Constructor​

new JodaPrintClient(options): JodaPrintClient

Parameters​
options​

ClientOptions

Returns​

JodaPrintClient

Properties​

devices​

readonly devices: object

get​

get: (id) => Promise<Device>

Parameters​
id​

string

Returns​

Promise<Device>

list​

list: (query) => ListResult<Device>

Parameters​
query?​

DeviceListQuery = {}

Returns​

ListResult<Device>

jobs​

readonly jobs: object

cancel​

cancel: (id) => Promise<Job>

Parameters​
id​

string

Returns​

Promise<Job>

create​

create: (job, opts) => Promise<Job>

Creates a cloud job; retried safely thanks to an idempotency key (generated if absent).

Parameters​
job​

CreateJob

opts?​

RequestOptions = {}

Returns​

Promise<Job>

get​

get: (id) => Promise<Job>

Parameters​
id​

string

Returns​

Promise<Job>

list​

list: (query) => ListResult<Job>

Parameters​
query?​

JobListQuery = {}

Returns​

ListResult<Job>

preview​

preview: (id) => Promise<Uint8Array<ArrayBufferLike>>

The receipt a sandbox job printed, as PNG bytes (jp_test_ keys).

Parameters​
id​

string

Returns​

Promise<Uint8Array<ArrayBufferLike>>

reprint​

reprint: (id, opts) => Promise<Job>

Prints a finished job again (needs its content to be retained).

Parameters​
id​

string

opts?​

RequestOptions = {}

Returns​

Promise<Job>

printers​

readonly printers: object

get​

get: (id) => Promise<Printer>

Parameters​
id​

string

Returns​

Promise<Printer>

list​

list: (query) => ListResult<Printer>

Parameters​
query?​

PrinterListQuery = {}

Returns​

ListResult<Printer>

receipts​

readonly receipts: object

preview​

preview: (document, options) => Promise<Uint8Array<ArrayBufferLike>>

Renders an A8 receipt document to PNG, as the agent prints it (no printing).

Parameters​
document​

ReceiptDocument

options?​

PreviewOptions = {}

Returns​

Promise<Uint8Array<ArrayBufferLike>>

templates​

readonly templates: object

get​

get: (id) => Promise<Template>

Parameters​
id​

string

Returns​

Promise<Template>

list​

list: () => Promise<Page<Template>>

Every template of the organization; print one with jobs.create({ templateId, data }).

Returns​

Promise<Page<Template>>

Methods​

me()​

me(): Promise<Record<string, unknown>>

The API key's organization, mode and scopes.

Returns​

Promise<Record<string, unknown>>


ListResult​

A page of results that is also an async iterator over every item of every page:

const first = await client.jobs.list({ state: "failed" }); // { data, nextCursor } for await (const job of client.jobs.list({ state: "failed" })) { ... }

Type Parameters​

T​

T

Implements​

  • PromiseLike<Page<T>>
  • AsyncIterable<T>

Constructors​

Constructor​

new ListResult<T>(load, cursor?): ListResult<T>

Parameters​
load​

(cursor) => Promise<Page<T>>

cursor?​

string

Returns​

ListResult<T>

Methods​

[asyncIterator]()​

[asyncIterator](): AsyncIterator<T>

Returns​

AsyncIterator<T>

Implementation of​

AsyncIterable.[asyncIterator]

then()​

then<A, B>(onfulfilled?, onrejected?): Promise<A | B>

Attaches callbacks for the resolution and/or rejection of the Promise.

Type Parameters​
A​

A = Page<T>

B​

B = never

Parameters​
onfulfilled?​

((value) => A | PromiseLike<A>) | null

The callback to execute when the Promise is resolved.

onrejected?​

((reason) => B | PromiseLike<B>) | null

The callback to execute when the Promise is rejected.

Returns​

Promise<A | B>

A Promise for the completion of which ever callback is executed.

Implementation of​

PromiseLike.then


WebhookVerificationError​

Extends​

  • Error

Constructors​

Constructor​

new WebhookVerificationError(reason, message): WebhookVerificationError

Parameters​
reason​

WebhookErrorReason

message​

string

Returns​

WebhookVerificationError

Overrides​

Error.constructor

Properties​

reason​

readonly reason: WebhookErrorReason

Interfaces​

ClientOptions​

@jodaprint/node: server-side JodaPrint SDK. Signs browser SDK requests, calls the REST API v1 and verifies webhooks. Uses only fetch and WebCrypto: Node 18+, Deno and Bun.

Properties​

apiKey​

apiKey: string

jp_live_... or jp_test_...

baseUrl?​

optional baseUrl?: string

Default https://api.jodaprint.dev (the JodaPrint cloud).

fetch?​

optional fetch?: {(input, init?): Promise<Response>; (input, init?): Promise<Response>; }

Call Signature​

(input, init?): Promise<Response>

MDN Reference

Parameters​
input​

RequestInfo | URL

init?​

RequestInit

Returns​

Promise<Response>

Call Signature​

(input, init?): Promise<Response>

MDN Reference

Parameters​
input​

string | Request | URL

init?​

RequestInit

Returns​

Promise<Response>

maxRetries?​

optional maxRetries?: number

Retries for 429, 5xx and network errors. Default 3.

maxRetryDelayMs?​

optional maxRetryDelayMs?: number

Longest wait between retries, including Retry-After. Default 60 s.

retryBaseMs?​

optional retryBaseMs?: number

First backoff step (doubles each retry). Default 500 ms.

timeoutMs?​

optional timeoutMs?: number

Per attempt. Default 30 s.


Device​

Properties​

activated​

activated: boolean

agentVersion​

agentVersion: string

arch​

arch: string

createdAt​

createdAt: string

groupId​

groupId: string | null

id​

id: string

lastSeenAt​

lastSeenAt: string | null

name​

name: string

os​

os: string

status​

status: "online" | "offline"


DeviceListQuery​

Extends​

  • ListQuery

Properties​

cursor?​

optional cursor?: string

Inherited from​

ListQuery.cursor

limit?​

optional limit?: number

Page size (1-100).

Inherited from​

ListQuery.limit

status?​

optional status?: "online" | "offline"


Job​

Properties​

attempt​

attempt: number

contentRetained​

contentRetained: boolean

Whether the content is still stored (needed to reprint).

createdAt​

createdAt: string

deviceId​

deviceId: string | null

dispatchedAt​

dispatchedAt: string | null

errorCode​

errorCode: string | null

errorMessage​

errorMessage: string | null

events?​

optional events?: JobEvent[]

expiresAt​

expiresAt: string | null

hasPreview​

hasPreview: boolean

Sandbox jobs (jp_test_ keys): jobs.preview(id) returns the printed receipt as PNG.

id​

id: string

idempotencyKey​

idempotencyKey: string | null

metadata​

metadata: Record<string, unknown>

mode​

mode: "live" | "test"

test: created with a jp_test_ key (sandbox).

printedAt​

printedAt: string | null

printerId​

printerId: string | null

source​

source: "local" | "cloud"

state​

state: JobState

templateId​

templateId: string | null

The template the job was printed from, if any.

type​

type: string

updatedAt​

updatedAt: string


JobEvent​

Properties​

at​

at: string

errorCode​

errorCode: string | null

state​

state: JobState


JobListQuery​

Extends​

  • ListQuery

Properties​

cursor?​

optional cursor?: string

Inherited from​

ListQuery.cursor

deviceId?​

optional deviceId?: string

from?​

optional from?: string

ISO 8601 bounds on createdAt.

limit?​

optional limit?: number

Page size (1-100).

Inherited from​

ListQuery.limit

printerId?​

optional printerId?: string

state?​

optional state?: JobState

to?​

optional to?: string


ListQuery​

Extended by​

  • JobListQuery
  • DeviceListQuery
  • PrinterListQuery

Properties​

cursor?​

optional cursor?: string

limit?​

optional limit?: number

Page size (1-100).


NodeRequestLike​

A Node/Express-style request (IncomingMessage, possibly with a parsed body).

Extends​

  • AsyncIterable<Uint8Array | string>

Properties​

body?​

optional body?: unknown

method?​

optional method?: string


NodeResponseLike​

Properties​

statusCode​

statusCode: number

Methods​

end()​

end(body?): unknown

Parameters​
body?​

string

Returns​

unknown

setHeader()​

setHeader(name, value): unknown

Parameters​
name​

string

value​

string

Returns​

unknown


Page​

Every list answers a page; pass nextCursor as cursor for the next one.

Type Parameters​

T​

T

Properties​

data​

data: T[]

nextCursor​

nextCursor: string | null


PreviewOptions​

Options of a receipt preview.

Properties​

optional footer?: boolean

Add the free plan's "Printed with JodaPrint" line.

paper?​

optional paper?: "58mm" | "80mm"

profile?​

optional profile?: string

Printer profile (default generic-80mm).


Printer​

Properties​

agentPrinterId​

agentPrinterId: string

The ID the agent uses for this printer.

alias​

alias: string | null

capabilities​

capabilities: string[]

codepage​

codepage: string | null

connection​

connection: string

deviceId​

deviceId: string

id​

id: string

Cloud printer ID: use it as printerId when creating jobs.

isDefault​

isDefault: boolean

kind​

kind: string

lastStatusAt​

lastStatusAt: string | null

name​

name: string

paper​

paper: string | null

status​

status: string


PrinterListQuery​

Extends​

  • ListQuery

Properties​

cursor?​

optional cursor?: string

Inherited from​

ListQuery.cursor

deviceId?​

optional deviceId?: string

limit?​

optional limit?: number

Page size (1-100).

Inherited from​

ListQuery.limit

status?​

optional status?: string


RequestOptions​

@jodaprint/node: server-side JodaPrint SDK. Signs browser SDK requests, calls the REST API v1 and verifies webhooks. Uses only fetch and WebCrypto: Node 18+, Deno and Bun.

Properties​

idempotencyKey?​

optional idempotencyKey?: string

Same key within 24 h returns the first job and prints nothing (A7).

signal?​

optional signal?: AbortSignal


Signature​

The answer the browser SDK expects.

Properties​

keyId​

keyId: string

nonce​

nonce: string

sig​

sig: string

ts​

ts: number

Unix seconds.


SignerOptions​

Properties​

keyId​

keyId: string

The signing key's ID from the dashboard (sk_...).

nonce?​

optional nonce?: () => string

Nonce generator (tests). Default: 16 random bytes, base64url.

Returns​

string

now?​

optional now?: () => number

Clock in milliseconds (tests).

Returns​

number

orgId​

orgId: string

privateKey​

privateKey: string | CryptoKey

The Ed25519 private key shown once in the dashboard: PEM ("-----BEGIN PRIVATE KEY-----") or the raw 32-byte seed in base64. A WebCrypto CryptoKey also works.


SignPayload​

What the browser SDK asks your backend to sign.

Properties​

method​

method: string

orgId?​

optional orgId?: string

params?​

optional params?: unknown


SignRequestHandler()​

Type Parameters​

Req​

Req

Call Signature​

SignRequestHandler(req): Promise<Response>

Fetch style: Next.js route handlers, Bun, Deno, Hono, Cloudflare Workers.

Parameters​
req​

Request

Returns​

Promise<Response>

Call Signature​

SignRequestHandler(req, res): Promise<void>

Node style: Express, Nest (@Req/@Res), node:http.

Parameters​
req​

Req & NodeRequestLike

res​

NodeResponseLike

Returns​

Promise<void>


SignRequestOptions​

Type Parameters​

Req​

Req

Properties​

authorize​

authorize: (req, payload) => boolean | Promise<boolean>

Decides whether this caller may print: check your session here. It also receives the payload, so you can limit printers or job types. Required: the endpoint signs whatever an authorized caller asks.

Parameters​
req​

Req

payload​

Required<SignPayload>

Returns​

boolean | Promise<boolean>

maxBodyBytes?​

optional maxBodyBytes?: number

Largest accepted body in bytes. Default 1 MB.

methods?​

optional methods?: readonly string[]

Methods this endpoint signs. Default: every signed local method.


Template​

A label or receipt template made in the dashboard (Prompt 8.1). Print it with jobs.create({ templateId, data, ... }).

Properties​

content​

content: string

Template text with {{variables}}.

createdAt​

createdAt: string

id​

id: string

name​

name: string

paper​

paper: string | null

type​

type: "zpl" | "epl" | "receipt" | "html"

updatedAt​

updatedAt: string


WebhookEvent​

The body JodaPrint POSTs to a webhook endpoint.

Type Parameters​

T​

T = Record<string, unknown>

Properties​

createdAt​

createdAt: string

data​

data: T

id​

id: string

organizationId​

organizationId: string

type​

type: string

Type Aliases​

CreateJob​

CreateJob = Omit<ContentJobRequest, "printer"> | Omit<TemplateJobRequest, "printer"> & { alias?: never; deviceId?: never; printerId: string; } | { alias?: string; deviceId: string; printerId?: never; }

A cloud job: the A7 job request (content, or templateId with its variables in data) plus exactly one target.


Signer​

Signer = (payload) => Promise<Signature>

Parameters​

payload​

SignPayload

Returns​

Promise<Signature>


WebhookErrorReason​

WebhookErrorReason = "malformed_header" | "timestamp_out_of_tolerance" | "signature_mismatch" | "invalid_body"

Variables​

DEFAULT_BASE_URL​

const DEFAULT_BASE_URL: "https://api.jodaprint.dev" = "https://api.jodaprint.dev"

The JodaPrint cloud API. Self-hosted and white-label clouds pass their own baseUrl.


SIGNED_METHODS​

const SIGNED_METHODS: readonly ["printers.list", "printers.status", "print", "jobs.get", "jobs.cancel", "drawer.open", "subscribe"]

Local methods that need a signature (A6); agent.info never does.

Functions​

createSigner()​

createSigner(options): Signer

Returns a function that signs browser SDK requests per A10.1: v1\n{method}\n{orgId}\n{ts}\n{nonce}\n{sha256_hex(canonical_json(params))}.

Parameters​

options​

SignerOptions

Returns​

Signer


importPrivateKey()​

importPrivateKey(key): Promise<CryptoKey>

Imports a PEM (PKCS#8) or raw-seed Ed25519 private key with WebCrypto.

Parameters​

key​

string | CryptoKey

Returns​

Promise<CryptoKey>


parseSignatureHeader()​

parseSignatureHeader(header): object

Parses t=<unix seconds>,v1=<hex>[,v1=<hex>…] (several v1 values during secret rotation).

Parameters​

string

Returns​

object

signatures​

signatures: string[]

timestamp​

timestamp: number


signRequestHandler()​

signRequestHandler<Req>(signer, options): SignRequestHandler<Req>

Creates the signing endpoint for the browser SDK (mount it at, for example, POST /jodaprint/sign):

app.post("/jodaprint/sign", express.json(), signRequestHandler(signer, { authorize: (req) => Boolean(req.session.user), }));

// Next.js app/jodaprint/sign/route.ts export const POST = signRequestHandler(signer, { authorize: (req) => isLoggedIn(req) });

Type Parameters​

Req​

Req = Request

Parameters​

signer​

Signer

options​

SignRequestOptions<Req>

Returns​

SignRequestHandler<Req>


verifyWebhook()​

verifyWebhook<T>(rawBody, signatureHeader, secret, toleranceSec?, nowSec?): Promise<WebhookEvent<T>>

Checks the JodaPrint-Signature header of a webhook request and returns the parsed event. rawBody must be the exact bytes received (verify before any JSON parsing or re-serialization). Rejects signatures older or newer than toleranceSec (replays).

Type Parameters​

T​

T = Record<string, unknown>

Parameters​

rawBody​

string | Uint8Array<ArrayBufferLike>

signatureHeader​

string | null | undefined

secret​

string

toleranceSec?​

number = 300

nowSec?​

number = ...

Returns​

Promise<WebhookEvent<T>>