CumulusDocs
Open Studio
On this page

Calls and results reference

Prepare a call command, persist it, then send it with placeCall. Use the returned run_id to wait for completion or artifacts. The helpers keep timeouts and reconnects bounded; they do not change the published agent or assign numbers implicitly. assignIntegration is the separate operation for applying phone number bindings.

Import from @cumulus/sdk/runtime. This page documents SDK 0.3.4. Follow the calls and results guide for a worked workflow.

Start with a working example

typescript
import { Cumulus } from "@cumulus/sdk";
import {
  prepareCall, placeCall, waitUntilEnded, waitForRecording, waitForAnalysis,
  paginate, watchRunEvents, type PreparedCall,
} from "@cumulus/sdk/runtime";

export async function callAgent(client: Cumulus, agentId: string, to: string,
  persistCommand: (command: PreparedCall) => Promise<void>) {
  const command = prepareCall({ channel: "phone", agent_id: agentId, to,
    test: true }); // A test phone run still dials the supplied destination.
  await persistCommand(command);
  const run = await placeCall(client, command);
  const ended = await waitUntilEnded(client, run.run_id, { timeoutMs: 120_000 });
  return { runId: ended.run_id, state: ended.state, outcome: ended.outcome };
}

export async function artifacts(client: Cumulus, runId: string) {
  const recording = await waitForRecording(client, runId);
  const analysis = await waitForAnalysis(client, runId);
  return { recording, analysis };
}

export async function listAllRuns(client: Cumulus) {
  const runs = [];
  for await (const run of paginate(cursor =>
    client.runs.list({ query: { limit: 100, ...(cursor ? { cursor } : {}) } }))) {
    runs.push(run);
  }
  return runs;
}

export async function follow(client: Cumulus, runId: string,
  consume: (event: unknown) => Promise<void>) {
  for await (const event of watchRunEvents(client, runId, { maxReconnects: 3 })) {
    await consume(event);
  }
}

Prepare and start a call

prepareCall

Validate and freeze a phone RunsCreateRequest without sending it. Default idempotencyKey is a new UUID; an explicit key must be 8–255 printable non-space ASCII characters. Persist the PreparedCall so retries reuse the same body and key.

Related types and helpers: PreparedCall.

Complete TypeScript declaration
TypeScript declaration
/** Pure preparation. Persist this command before the first send; test:true still dials. */
export declare function prepareCall(body: CallBody, options?: {
    idempotencyKey?: string;
}): PreparedCall;

placeCall

Verify the prepared body digest and send runs.create with the saved request key. Return the admitted run. This is the point where a real phone call can be started.

placeCall(client, command) · Optional arguments: signal.

Resolves to the created run, including its run_id and current state.

Use Awaited<ReturnType<typeof placeCall>> for the exact inferred result type in your application. Full TypeScript declaration.

Related types and helpers: Cumulus · PreparedCall · components.

Wait for results and artifacts

waitUntilEnded

Poll runs.get until completed, failed, cancelled, rejected or expired. Return the terminal run; completion alone does not imply a successful business outcome.

waitUntilEnded(client, runId) · Optional arguments: options.

Resolves to the run after its state becomes terminal.

Use Awaited<ReturnType<typeof waitUntilEnded>> for the exact inferred result type in your application. Full TypeScript declaration.

Related types and helpers: Cumulus · WaitOptions · components.

waitForRecording

Poll runs.recording until its state is ready, partial, failed, not_required or expired. Inspect the returned state before using the artifact URL.

Related types and helpers: Cumulus · WaitOptions · components.

Complete TypeScript declaration
TypeScript declaration
export declare function waitForRecording(client: Cumulus, runId: string, options?: WaitOptions): Promise<{
    run_id: string;
    state: "pending" | "recording" | "processing" | "ready" | "partial" | "failed" | "not_required" | "expired";
    url: string | null;
    url_expires_at: string | null;
    media_url: string | null;
    media_url_expires_at: string | null;
    content: components["schemas"]["ContentRef"] | null;
}>;

waitForAnalysis

Poll runs.analysis while its state is pending, running or processing, then return the settled response. Inspect its state and content before using the analysis.

Related types and helpers: Cumulus · WaitOptions · components.

Complete TypeScript declaration
TypeScript declaration
export declare function waitForAnalysis(client: Cumulus, runId: string, options?: WaitOptions): Promise<{
    run_id: string;
    state: "pending" | "running" | "completed" | "failed" | "not_requested";
    evaluation_id: string | null;
    disposition: string | null;
    successful: boolean | null;
    fields: {
        [key: string]: unknown;
    };
    model: components["schemas"]["ModelIdentity"] | null;
    completed_at: string | null;
}>;

Read pages and events

paginate

Iterate items from a cursor-based list callback until next_cursor is null. Repeated cursors throw DefinitionError instead of looping indefinitely.

Complete TypeScript declaration
TypeScript declaration
export declare function paginate<T>(page: (cursor?: string) => Promise<{
    items: T[];
    next_cursor: string | null;
}>): AsyncGenerator<T>;

watchRunEvents

Yield durable events, reconnect from the last consumed frame, and stop after the run reaches a terminal state. Defaults: five reconnects and 500 ms between attempts. onCursor runs after the consumer resumes from the yielded event; persist it after durable processing and deduplicate event_id.

Related types and helpers: Cumulus · SemanticEvent.

Complete TypeScript declaration
TypeScript declaration
/** Reconnect from the last consumed SSE frame. Persist onCursor after durable handling; deduplicate by event_id. */
export declare function watchRunEvents(client: Cumulus, runId: string, options?: {
    signal?: AbortSignal;
    lastEventId?: string;
    maxReconnects?: number;
    reconnectMs?: number;
    onCursor?: (cursor: string) => void;
}): AsyncGenerator<SemanticEvent>;

Assign phone numbers

assignIntegration

Apply inbound and outbound number aliases to the receipt’s agent. Require a publication and verify it is the current head before updating numbers. Missing number bindings fail before their update; routing changes are explicit and independent of publication.

Related types and helpers: Cumulus · IntegrationDefinition · EnvironmentBindings · ApplyReceipt.

Complete TypeScript declaration
TypeScript declaration
/** Explicit routing only. The API pins the current head, so verify it matches the receipt first. */
export declare function assignIntegration(client: Cumulus, integration: IntegrationDefinition, bindings: EnvironmentBindings, receipt: ApplyReceipt): Promise<{
    number_id: string;
    e164: string;
    trunk_id: string;
    nickname: string | null;
    inbound_agent_id: string | null;
    outbound_agent_id: string | null;
    inbound_agent_version: number | null;
    outbound_agent_version: number | null;
    state: "pending" | "ready";
    created_at: string;
}[]>;

Handle wait timeouts

WaitTimeout

A bounded wait expired. code is wait_timeout; runId and phase identify what was being awaited. The run continues independently.

Complete TypeScript declaration
TypeScript declaration
export declare class WaitTimeout extends Error {
    readonly runId: string;
    readonly phase: string;
    readonly code = "wait_timeout";
    constructor(runId: string, phase: string);
}

Types and declarations

PreparedCall

Serializable phone call command: schema version, validated body, request key and canonical digest. Store it before sending.

Complete TypeScript declaration
TypeScript declaration
export interface PreparedCall {
    schemaVersion: 1;
    body: CallBody;
    idempotencyKey: string;
    digest: string;
}

WaitOptions

timeoutMs defaults to 120,000 and pollMs to 1,000. timeoutMs must be positive; pollMs must be at least 10. signal cancels waiting. Reaching the timeout does not cancel the run.

Complete TypeScript declaration
TypeScript declaration
export interface WaitOptions {
    timeoutMs?: number;
    pollMs?: number;
    signal?: AbortSignal;
}

Supporting types

These local type expressions appear in the signatures above. They are not separate package exports.

Complete TypeScript declaration
TypeScript declaration
type CallBody = Extract<components["schemas"]["RunsCreateRequest"], {
    channel: "phone";
}>;

Export index

Content version 5cce2092Customer SDKMarkdown source
Calls and runtime helpers · Cumulus developer docs