Skip to main content
AlonChat

SDK and CLI

Use the official TypeScript SDK and command-line client for AlonChat agents

SDK and CLI#

The SDK and CLI are thin clients for the public AlonChat API. Customer chat uses POST /api/v1/chat/{agentId}. Every other merchant operation comes from one project catalog shared with the API, MCP, and dashboard. Neither package contains the agent runtime, and an operation that is merely present in an installed package is not permission to run it.

CallEndpoint
ChatPOST /api/v1/chat/{agentId}
Discover permitted operationsGET /api/v1/operations
An operation with its own routeThat route, such as GET /api/v1/billing/usage
Any other permitted operationPOST /api/v1/operation-executions/{operationId}
Durable taskGET /api/v1/tasks/{taskId}
Approval receiptGET /api/v1/approvals/{approvalId}

@alonchat/contracts is the generated metadata used by these clients. Most applications should install @alonchat/sdk instead of using the contracts package directly.

TypeScript SDK#

Install the package in a server-side Node.js or TypeScript application:

bash
npm install @alonchat/sdk
ts
import { AlonChatClient } from '@alonchat/sdk'

const alonchat = new AlonChatClient({
  apiKey: process.env.ALONCHAT_API_KEY!,
})

const result = await alonchat.sendMessage({
  agentId: process.env.ALONCHAT_AGENT_ID!,
  message: 'What time do you close?',
  idempotencyKey: crypto.randomUUID(),
})

console.log(result.response)
console.log(result.conversationId)
console.log(result.presentation) // present only when this turn has buttons or media

idempotencyKey is required. The SDK sends it as the Idempotency-Key header. Pass conversationId on the next call to continue the thread. result.presentation is optional ordered Workflow content, buttons, and media. Render only what was returned. Custom widgets fall back to conversation on API chat; test their controls in the embedded web widget.

A Workflow button continues with interaction copied from that presentation, plus a new idempotency key:

ts
await alonchat.sendMessage({
  agentId: process.env.ALONCHAT_AGENT_ID!,
  message: 'Tuesday at 2 PM',
  conversationId: result.conversationId,
  idempotencyKey: crypto.randomUUID(),
  interaction: {
    type: 'workflow_button',
    runId: 'RUN_UUID',
    nodeId: 'NODE_ID',
    payload: 'BUTTON_PAYLOAD',
  },
})

Continue the same thread:

ts
const next = await alonchat.sendMessage({
  agentId: process.env.ALONCHAT_AGENT_ID!,
  message: 'What about Sunday?',
  conversationId: result.conversationId,
  idempotencyKey: crypto.randomUUID(),
})

Read subscription and usage information:

ts
const subscription = await alonchat.getBillingSubscription()
const usage = await alonchat.getBillingUsage()

console.log(subscription.status, subscription.plan.displayName)
console.log(usage.credits.remaining)

Subscription, plan, usage, and invoice reads all require billing_read:

ts
const plans = await alonchat.listBillingPlans()
const invoices = await alonchat.listBillingInvoices({ limit: 20 })

These reads do not reveal card details or change the plan. Chat still returns creditsRemaining without billing_read.

Discover the operations this key may call, then execute one by its published id. Use the schema from discovery for input. For a write, pass the same idempotencyKey when retrying that same request.

ts
const operations = await alonchat.discoverOperations()
const receipt = await alonchat.executeOperation('agent_setup.inspect', {
  agentId: process.env.ALONCHAT_AGENT_ID!,
})

agent_setup.inspect requires agent_design_read. Do not assume an id exists for every key. discoverOperations() is the list that key can use.

Receipt statusWhat to do
completedRead receipt.data
acceptedPoll tasks get until state is completed, failed, or cancelled. queued, running, and input_required are not finished.
pending_approvalShow the owner-review path and wait. Read the approval before treating the work as finished.
failedRead error.code and error.resolution

If the result is OUTCOME_UNCERTAIN, reconcile that attempt before sending the same consequential action under a new idempotency key.

Upload a file or spreadsheet#

uploadFileSource(...) sends a document. uploadStructuredDataFile(...) sends a CSV or Excel file. Both require the knowledge.write scope. Keep prepareIdempotencyKey and finalizeIdempotencyKey stable when retrying the same file. If you omit them, each call mints new keys and starts a new attempt.

A document upload from the SDK, CLI, or MCP can return pending_approval before any bytes are stored. The owner approves that request in AlonChat; then retry the same two keys. A spreadsheet upload is not held by that approval gate. In either case, a finished call is not proof that training or import has finished. Read the receipt and the source's processing or review status. The SDK rechecks the server after an interrupted transfer and does not overwrite an existing object.

Permission failures and invalid sessions are not bypassed. On UPLOAD_RENEWAL_INCOMPLETE, read the error receipt for the pending action. A rate-limit error includes retryAfterSeconds and is not retried immediately.

Streaming#

ts
for await (const event of alonchat.streamMessage({
  agentId: process.env.ALONCHAT_AGENT_ID!,
  message: 'Explain your services',
  idempotencyKey: crypto.randomUUID(),
})) {
  if (event.type === 'token') process.stdout.write(event.token)
  if (event.type === 'done') console.log('\nConversation:', event.conversationId)
}

Command-Line Interface#

Run the CLI without installing it globally. auth login securely prompts for a project API key, verifies it against the operation catalog, and saves a local named profile:

bash
npx -y @alonchat/cli auth login
npx -y @alonchat/cli whoami
npx -y @alonchat/cli doctor

Use --profile NAME when you work with multiple projects. whoami reports the selected credential source and the number of agents and operations it can access without printing the key. doctor checks the saved credential, authenticated API access, agent visibility, and hosted MCP OAuth discovery.

For unattended CI or a one-off command, use an environment variable:

bash
ALONCHAT_API_KEY=sk-your-key npx -y @alonchat/cli chat \
  --agent your-agent-id \
  --message "What time do you close?" \
  --idempotency-key "close-time-001"

PowerShell:

powershell
$env:ALONCHAT_API_KEY = 'sk-your-key'
npx -y @alonchat/cli chat --agent your-agent-id --message 'What time do you close?' --idempotency-key 'close-time-001'

--idempotency-key is required for chat. The same value retries that exact message.

Billing commands:

bash
alonchat billing status --json
alonchat billing usage --json
alonchat billing plans --json
alonchat billing invoices --input '{"limit":20}' --json

Agent-workbench commands:

bash
alonchat agents inspect --input '{"agentId":"AGENT_UUID"}' --json
alonchat conversations list --input '{"agentId":"AGENT_UUID","limit":20}' --json
alonchat conversations get \
  --input '{"agentId":"AGENT_UUID","conversationId":"CONVERSATION_UUID"}' \
  --json
alonchat tasks get --input '{"taskId":"TASK_UUID"}' --json
alonchat approvals get --input '{"approvalId":"APPROVAL_UUID"}' --json

design validate and design draft take a complete JSON object in --input. Ellipses and JavaScript spread are rejected. Build that object from alonchat operations list --json, and keep one --idempotency-key for the same draft. A draft does not publish live changes.

File and spreadsheet uploads use the same SDK behavior:

bash
alonchat sources file upload --agent AGENT_UUID --file ./menu.pdf --idempotency-key "menu-v1" --json
alonchat structured-data upload --agent AGENT_UUID --file ./prices.csv --idempotency-key "prices-v1" --json

The idempotency key is split into stable prepare and finalize keys. A document upload can return pending_approval before the file is stored; retry the same key after the owner approves it. Finalization does not mean training or import has finished.

See Build agents with Codex or Claude for the proposal contract, evidence rules, permissions, and owner-review boundary.

Useful options:

OptionPurpose
--conversation-id UUIDContinue an existing thread
--idempotency-key KEYMake retries safe
--streamPrint progressive reply events
--jsonProduce machine-readable output
--base-url URLOverride the API origin for local development
--profile NAMESelect an explicitly saved credential profile
--confirmConfirm a destructive operation locally. Server approval still applies.
--interaction JSONSend a workflow_button selection with chat

You can also set ALONCHAT_BASE_URL in the CLI environment.

Install AlonChat's hosted OAuth MCP connection from the same CLI:

bash
alonchat mcp install --client codex --execute
alonchat mcp install --client claude --execute
alonchat mcp install --client cursor

Codex and Claude Code expose reviewed install commands. For Cursor and generic MCP clients, the CLI prints the configuration to add rather than silently editing another application's settings.

alonchat operations list --json queries AlonChat for the operations currently available to the credential. Names and schemas from that command are authoritative for the selected profile. --input must be one complete JSON value.

The installed SDK and CLI contain the versioned contracts they were built with. Server-side fixes to an existing operation require no package update. A newly published operation or contract change requires a newer SDK or CLI before the local client can call it.

Command results use the same receipt statuses as the SDK. completed has the result. accepted should be polled with tasks get until state is completed, failed, or cancelled. pending_approval waits for owner review. failed includes recovery instructions. --confirm only acknowledges a destructive command on your machine. Keep the same idempotency key for the same write. Do not retry an uncertain result under a new key.

Credentials#

Use a project API key with chat for customer messages. Add read_agents only when the integration must list agents, billing_read for subscription, plan, usage, or invoice reads, and knowledge.write for file or spreadsheet uploads. Restrict the key to one agent when possible. Saved profiles live in the current user's AlonChat configuration directory and are written atomically; use an environment variable or managed secret store in CI. An explicit --profile selection takes precedence over ALONCHAT_API_KEY, while the environment key takes precedence when no profile is selected.

Do not expose either package in browser-side code with a real API key.