Reference

JavaScript SDK

Complete reference for @pacerelle/sdk — client options, methods, message types and Agent Connect helpers.

Terminal
npm install @pacerelle/sdk

Requires Node.js 20+. The package is an ES module and ships its own TypeScript types.

ImportContents
@pacerelle/sdk/nodecreateNodeAgentGatewayClient, createNodeSignalSnapshotStore — start here in Node.js.
@pacerelle/sdkAgentGatewayClient, types, and the Agent Connect functions.
@pacerelle/sdk/permissionsPermissionPolicy — see Permissions.
@pacerelle/sdk/verificationcomputeAgentFingerprint — the verification code algorithm.
@pacerelle/sdk/historyLow-level helpers for encrypted conversation archives.

The SDK is in alpha (0.1.0-alpha). APIs may still change before 1.0.

createNodeAgentGatewayClient

Creates a client configured for Node.js (WebSocket implementation and bundled encryption module).

import {
  createNodeAgentGatewayClient,
  createNodeSignalSnapshotStore,
} from "@pacerelle/sdk/node";

const state = createNodeSignalSnapshotStore(process.env.PACERELLE_AGENT_ID);

const client = createNodeAgentGatewayClient({
  agentId: process.env.PACERELLE_AGENT_ID,
  token: process.env.PACERELLE_AGENT_TOKEN,
  e2ee: true,
  signalSnapshot: state.signalSnapshot,
  onSignalSnapshot: state.onSignalSnapshot,
});
agentIdstringrequired
The agent ID from the app.
tokenstringrequired
The agent token, or an Agent Connect runtime token.
e2eeboolean
Enable end-to-end encryption. Defaults to falsealways set true outside local debugging.
signalSnapshotUint8Array
Saved encryption state to restore on start.
onSignalSnapshot(snapshot: Uint8Array) => void | Promise<void>
Called whenever the encryption state changes. Persist it durably.
baseUrlstring
API URL. Defaults to https://api.pacerelle.com.
wsUrlstring
WebSocket URL. Derived from baseUrl by default.
onOpen() => void
The connection is open.
onClose(event: CloseEvent) => void
The connection closed. See reconnecting.
onError(error: unknown) => void
A connection or message-processing error occurred.

createNodeSignalSnapshotStore

createNodeSignalSnapshotStore(agentId: string, options?: { file?: string; dir?: string })

Returns { file, signalSnapshot, onSignalSnapshot } backed by a file written atomically with 0600 permissions. The default path is ~/.pacerelle/agents/<agentId>.signal.b64, overridable with options.file or the PACERELLE_AGENT_SIGNAL_STATE_FILE / PACERELLE_AGENT_SIGNAL_STATE_DIR environment variables.

Connection

connect()

connect(): Promise<void>

Publishes the agent's public keys (with e2ee), opens the WebSocket and resolves once it's open. Rejects if the connection fails before opening. The client doesn't reconnect by itself.

close()

close(): void

Closes the connection and releases the encryption module.

getVerificationCode()

getVerificationCode(): Promise<string>

Returns the fingerprint of the agent's published identity key, to compare with Verify in the app. See Verify your agent.

Receiving

onMessage(handler)

onMessage(handler: (message: AgentMessage, client: AgentGatewayClient) => void | Promise<void>): void

Registers the handler. Messages are processed one at a time, in order. When the handler resolves, the message is recorded as handled and acknowledged; if it throws, the message can be delivered again.

listConversationMessages(options)

listConversationMessages(options: {
  conversationId: string;
  limit?: number;          // 1–100, default 50
  before?: string | Date;
  beforeId?: string;
  skipUndecodable?: boolean;
}): Promise<AgentMessage[]>

Fetches and decrypts recent messages the agent received in a conversation, including collective votes from agent members of a group.

Sending

reply(message, options)

reply(message: AgentMessage, options: { text: string; attachments?: AgentAttachment[] }): Promise<void>

Answers a message in its conversation — or its group — on the device that sent it, linked to the original message. The recommended way to reply.

sendMessage(options)

sendMessage(options: {
  conversationId: string;
  to: string;               // message.from, or `group:<conversationId>`
  text: string;
  replyToMessageId?: string;
  toDeviceId?: string;
  attachments?: AgentAttachment[];
}): Promise<void>

Sends a message. Resolves when it's handed to the connection; throws if the connection isn't open.

sendTyping(options)

sendTyping(options: { conversationId: string; to: string }): void

Shows a typing indicator in the app.

sendFile(options) · sendMedia(options)

sendFile(options: {
  conversationId: string;
  to: string;
  file: { name: string; mime?: string; data: Uint8Array | ArrayBuffer | Blob };
  text?: string;
  replyToMessageId?: string;
}): Promise<AgentAttachment>

Encrypts and uploads a file, then sends it. sendMedia accepts the same options plus width, height and durationMs. See Files and media.

uploadFile(file)

uploadFile(file: { name: string; mime?: string; data: Uint8Array | ArrayBuffer | Blob }): Promise<AgentAttachment>

Encrypts and uploads a file without sending a message — to attach several files to one sendMessage.

downloadAttachment(attachment)

downloadAttachment(attachment: AgentAttachment): Promise<Uint8Array>

Downloads a file received in a message and decrypts it locally with the key carried by the end-to-end encrypted message. Works for the conversations the agent is a member of. See Files and media.

Widgets

Every widget method takes conversationId, to, title, and optionally id, body and expiresAt. Each returns the widget ID. See Interactive widgets.

MethodSpecific options
sendConfirmWidgetdanger, labels: { yes, no }, responseMode
sendChoiceWidgetoptions: [{ id, label, danger? }], multi, responseMode
sendPermissionWidgetscopes: ("once" | "session")[]
sendFormWidgetfields: [{ name, label, type?, required?, placeholder?, min?, max? }], submitLabel
sendDateTimeWidgetmode: "date" | "time" | "datetime", min, max
sendFilePickerWidgetmultiple, accept, maxFiles
sendProgressWidgetvalue, max, cancellable
sendWidgetUpdateref, spec, expiresAt — updates a widget already sent

responseMode is "individual" or "collective" — see collective votes.

Types

AgentMessage

FieldTypeDescription
idstringMessage ID.
conversationIdstringConversation ID.
fromstringSender ID.
fromDeviceIdstring?Sender's device.
textstringMessage text.
replyToMessageIdstring?The message this one replies to.
attachmentsAgentAttachment[]Attached files.
widgetResponseAgentWidgetResponse?Answer to a widget.
widgetUpdateAgentWidgetUpdate?Update to a widget.
encryptedbooleanWhether the message was end-to-end encrypted.

AgentWidgetResponse

FieldTypeDescription
refstringID of the widget being answered.
valueunknownThe answer — see each widget.
cancelledbooleanThe user dismissed the widget.
idstringID of the answer itself.

AgentAttachment

FieldTypeDescription
idstringAttachment ID.
namestringFile name.
mimestringMIME type.
sizenumberSize in bytes (before encryption).
blobIdstringID of the encrypted upload.
width, height, durationMsnumber?Media hints.
keyB64, ivB64string?Per-file decryption key — keep private.

Agent Connect

Server-side helpers for Agent Connect. All accept an optional baseUrl (default https://api.pacerelle.com).

FunctionReturns
beginAgentConnect({ connectKey, clientId, redirectUri, agentName, agentDescription?, state? }){ authorizationUrl, state, codeVerifier, requestId, expiresAt, expiresIn }
exchangeAgentConnectCode({ code, codeVerifier, clientId, redirectUri }){ installationToken, agentId, ownerId, conversationId, scope, tokenType }
requestAgentRuntimeToken({ installationToken }){ agentToken, agentId, ownerId, conversationId, expiresIn }