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
readonlycode:AnyErrorCode|"NETWORK_ERROR"
details
readonlydetails:Record<string,unknown> |undefined
name
readonlyname:"JodaPrintApiError"="JodaPrintApiError"
Overrides
Error.name
requestId
readonlyrequestId:string|undefined
retryable
readonlyretryable:boolean
status
readonlystatus: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
readonlydevices:object
get
get: (
id) =>Promise<Device>
Parameters
id
string
Returns
Promise<Device>
list
list: (
query) =>ListResult<Device>
Parameters
query?
DeviceListQuery = {}
Returns
ListResult<Device>
jobs
readonlyjobs: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
readonlyprinters:object
get
get: (
id) =>Promise<Printer>
Parameters
id
string
Returns
Promise<Printer>
list
list: (
query) =>ListResult<Printer>
Parameters
query?
PrinterListQuery = {}
Returns
ListResult<Printer>
receipts
readonlyreceipts: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
readonlytemplates: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
readonlyreason: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?
optionalbaseUrl?:string
Default https://api.jodaprint.dev (the JodaPrint cloud).
fetch?
optionalfetch?: {(input,init?):Promise<Response>; (input,init?):Promise<Response>; }
Call Signature
(
input,init?):Promise<Response>
Parameters
input
RequestInfo | URL
init?
RequestInit
Returns
Promise<Response>
Call Signature
(
input,init?):Promise<Response>
Parameters
input
string | Request | URL
init?
RequestInit
Returns
Promise<Response>
maxRetries?
optionalmaxRetries?:number
Retries for 429, 5xx and network errors. Default 3.
maxRetryDelayMs?
optionalmaxRetryDelayMs?:number
Longest wait between retries, including Retry-After. Default 60 s.
retryBaseMs?
optionalretryBaseMs?:number
First backoff step (doubles each retry). Default 500 ms.
timeoutMs?
optionaltimeoutMs?: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?
optionalcursor?:string
Inherited from
ListQuery.cursor
limit?
optionallimit?:number
Page size (1-100).
Inherited from
ListQuery.limit
status?
optionalstatus?:"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?
optionalevents?: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?
optionalcursor?:string
Inherited from
ListQuery.cursor
deviceId?
optionaldeviceId?:string
from?
optionalfrom?:string
ISO 8601 bounds on createdAt.
limit?
optionallimit?:number
Page size (1-100).
Inherited from
ListQuery.limit
printerId?
optionalprinterId?:string
state?
optionalstate?:JobState
to?
optionalto?:string
ListQuery
Extended by
JobListQueryDeviceListQueryPrinterListQuery
Properties
cursor?
optionalcursor?:string
limit?
optionallimit?:number
Page size (1-100).
NodeRequestLike
A Node/Express-style request (IncomingMessage, possibly with a parsed body).
Extends
AsyncIterable<Uint8Array|string>
Properties
body?
optionalbody?:unknown
method?
optionalmethod?: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
footer?
optionalfooter?:boolean
Add the free plan's "Printed with JodaPrint" line.
paper?
optionalpaper?:"58mm"|"80mm"
profile?
optionalprofile?: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?
optionalcursor?:string
Inherited from
ListQuery.cursor
deviceId?
optionaldeviceId?:string
limit?
optionallimit?:number
Page size (1-100).
Inherited from
ListQuery.limit
status?
optionalstatus?: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?
optionalidempotencyKey?:string
Same key within 24 h returns the first job and prints nothing (A7).
signal?
optionalsignal?: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?
optionalnonce?: () =>string
Nonce generator (tests). Default: 16 random bytes, base64url.
Returns
string
now?
optionalnow?: () =>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?
optionalorgId?:string
params?
optionalparams?: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?
optionalmaxBodyBytes?:number
Largest accepted body in bytes. Default 1 MB.
methods?
optionalmethods?: readonlystring[]
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
constDEFAULT_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
constSIGNED_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
header
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>>