import type { AgentCallConfig, PhoneNumber, ProvisionOptions, Message, SendSMSOptions, InboxOptions, SmsConversation, SmsConversationDetail, SmsConversationReplyResult, Call, InitiateCallOptions, InitiateAICallOptions, CallTranscript, RecordingUrlResponse, Webhook, CreateWebhookOptions, UsageData, UpgradeResponse, PaginatedResponse, WaitForOTPOptions, Contact, ContactUpdate, PurgeContactResult, NextCallContextResponse, Memory, MemoryTimelineResponse, MemoryCandidate, MemoryUpdate, ApproveCandidateResult, CallReport, CallReportSummary, Brief, SetByokKeyResult, DisableByokResult, InboundAiConfigResponse, OutboundDefaults, OutboundDefaultsResponse, SetPremiumVoiceResult, PremiumVoicesResponse, SynthesizeSpeechOptions, SynthesizeSpeechResult, Schedule, CreateScheduleOptions } from './types'; /** * AgentCall SDK client. * * @example * ```typescript * import AgentCall from 'agentcall' * * const client = new AgentCall('ac_live_xxxxxxxxxxxxx') * const number = await client.numbers.provision({ country: 'US' }) * ``` */ export declare class AgentCall { private apiKey; private baseUrl; private timeout; /** Phone number management (provision, list, release). */ numbers: NumbersResource; /** SMS messaging (send, inbox, OTP detection). */ sms: SMSResource; /** Two-way AI SMS conversation threads (list, get with messages). */ smsConversations: SmsConversationsResource; /** Voice calls (initiate, hangup, history, report, transcript). */ calls: CallsResource; /** Standalone text-to-speech in the same voices the AI uses on calls. */ tts: TtsResource; /** Webhook subscriptions for real-time events. */ webhooks: WebhooksResource; /** Usage and billing data. */ usage: UsageResource; /** Account-level flags (plan info, cross-call memory toggle). */ account: AccountResource; /** Auditable Call Memory: callers seen across this agent's numbers, plus the pre-call context renderer. */ contacts: ContactsResource; /** Auditable Call Memory: Current Truth + timeline + candidates. */ memory: MemoryResource; /** Auditable Call Memory: list and filter CallReport rows across calls. */ reports: ReportsResource; /** Auditable Call Memory: owner-facing brief inbox (digest of calls needing attention). */ briefs: BriefsResource; /** Proactive scheduling: make a number's agent text FIRST (reminders, digests). */ schedules: SchedulesResource; /** * Create a new AgentCall client. * * @param apiKey - API key starting with `ac_live_`. * @param config - Optional configuration overrides. * @param config.baseUrl - API base URL. Defaults to `https://api.agentcall.co`. * @param config.timeout - Request timeout in ms. Defaults to 30000. * @throws {Error} If `apiKey` is empty or missing. */ constructor(apiKey: string, config?: Partial>); /** @internal */ _request(method: string, path: string, body?: unknown): Promise; /** * @internal Send a request that returns a binary body (e.g. synthesized * audio). On a non-2xx the API still returns a JSON error envelope, which * we parse and throw as an AgentCallError. No retry — a paid synthesis * should fail fast rather than re-bill on a transient blip. */ _requestBinary(method: string, path: string, body?: unknown): Promise<{ bytes: Uint8Array; contentType: string; headers: Headers; }>; } declare class NumbersResource { private client; constructor(client: AgentCall); /** * Provision a new phone number. * * Free plan allows 1 local number. Pro plan allows unlimited numbers of all types. * * Not auto-retried on 5xx or network errors. The endpoint has no idempotency * key, so a replay of an ambiguous failure could mint a second number that * the carrier bills for. On `carrier_error` or a timeout, call `list()` to * see whether the number actually landed before deciding to retry. * * Failed attempts do not consume the provisioning budget (10/hour, 100/24h), * which counts numbers actually created. A `provisioning_rate_limit` error * carries a `Retry-After` header with the wait. * * @param options - Provisioning options (country, type, label). * @returns The newly provisioned phone number. * @throws {AgentCallError} `plan_limit` if quota exceeded or type not available on plan. * @throws {AgentCallError} `provisioning_rate_limit` if the hourly budget is spent. */ provision(options?: ProvisionOptions): Promise; /** * List all provisioned phone numbers. * * @param params - Optional filters and pagination. * @param params.limit - Max results per page (default 20). * @param params.cursor - Pagination cursor from a previous response. * @param params.country - Filter by country code (e.g. `US`). * @param params.type - Filter by number type (e.g. `local`). * @returns Paginated list of phone numbers. */ list(params?: { limit?: number; cursor?: string; country?: string; type?: string; }): Promise>; /** * Get a single phone number by ID. * * @param numberId - The phone number ID (e.g. `num_abc123`). * @returns The phone number details. * @throws {AgentCallError} `not_found` if the number doesn't exist or isn't owned by you. */ get(numberId: string): Promise; /** * Release (deactivate) a phone number. Stops billing immediately. * This action is irreversible — the number cannot be re-provisioned. * * @param numberId - The phone number ID to release. * @throws {AgentCallError} `not_found` if already released or doesn't exist. */ release(numberId: string): Promise; /** * Update a phone number's mutable fields. Supports renaming via the label * field (pass null to clear), changing the inbound AI voice, and changing * the inbound AI language. All edits are partial: changing voice or * language never wipes the rest of the inbound config (systemPrompt, * firstMessage, contextWebhook, etc. are preserved). At least one field * must be provided. * * @param numberId - The phone number ID to update. * @param updates - Fields to update. * @param updates.label - Optional new human-readable label (max 100 chars), or null to clear. * @param updates.voice - Optional new inbound AI voice. The number must already have inbound AI configured. * @param updates.language - Optional new inbound AI language. `'auto'` matches the caller; specific ISO-639-1 codes pin the AI to that language. The number must already have inbound AI configured. * @returns The updated phone number. * @throws {AgentCallError} `not_found` if the number doesn't exist or isn't owned by you. * @throws {AgentCallError} `validation_error` if label exceeds 100 chars or voice/language are not recognized. * @throws {AgentCallError} `inbound_ai_not_configured` if voice or language is provided but the number has no inbound AI configured. */ update(numberId: string, updates: { label?: string | null; voice?: string; language?: 'auto' | 'en' | 'es' | 'fr' | 'de' | 'it' | 'pt' | 'nl' | 'ja' | 'ko' | 'zh' | 'hi' | 'ar' | 'ru' | 'id' | 'tr' | 'pl' | 'uk' | 'vi' | 'ta' | 'ms' | 'ro' | 'el' | 'cs' | 'sv' | 'hu' | 'da' | 'fi' | 'no' | 'sk' | 'hr' | 'bg'; }): Promise; /** * Configure inbound AI voice on a number. When someone calls this number, * a managed AI voice agent answers and follows the system prompt. * Free tier: 5 minutes/month free, no card required. Once the trial is * exhausted, inbound AI calls hang up until the 1st of next month (UTC) * or until the user upgrades to Pro for unlimited inbound AI at $0.40/min. * Available on US and Canada numbers. * * @param numberId - The phone number ID to configure. * @param options - AI configuration. * @param options.systemPrompt - Instructions for the AI when answering. * @param options.voice - AI voice: alloy, ash, ballad, cedar, coral, echo, marin, sage, shimmer, verse. Marin and cedar are the newest natural-sounding picks. * @param options.firstMessage - What the AI says when it picks up. * @param options.maxDurationSecs - Max call duration in seconds (default 600). * @param options.notify - Optional post-call notifications. After every call, * AgentCall summarizes the transcript via LLM and sends a plain-English * summary (caller, intent, urgency, callback time) by email, by text, or both. * Spam calls are auto-suppressed. * @param options.notify.emailTo - Email address to receive the call summary (max 200 chars). * @param options.notify.smsTo - Phone number (E.164) to receive a short call-summary * text. Optional, off by default. The text is sent from the number that took the * call and billed as one outbound SMS. US-local sender numbers only; if the number * cannot deliver A2P SMS, AgentCall falls back to email. Respects STOP opt-out and a * per-number daily cap. * @param options.notify.businessName - Business name shown in the summary (max 100 chars). * @param options.notify.agencyName - Agency/brand name used in the sign-off (max 50 chars). * @param options.record - Opt in to call recording. When true, every inbound * call to this number is recorded and the recording.saved webhook fires * the $0.01/min `call_recording` meter on top of the inbound AI voice rate. * The dashboard auto-prepends a TCPA disclosure to firstMessage when this * is enabled. Defaults to false. * @param options.contextWebhook - Pre-call context webhook. When set, AgentCall * HMAC-signs and POSTs to your URL on every inbound call connect; the response's * `contextBlock` is merged onto the system prompt before the AI answers. Use this * to inject a live brief, current priorities, or recent emails so the AI speaks * with up-to-date context instead of a static prompt. Fail-open: any error leaves * the call running with the static prompt. * @param options.contextWebhook.url - Your HTTPS webhook endpoint. * @param options.contextWebhook.signingSecret - Shared secret used for HMAC-SHA256 signing. * You verify the X-AgentCall-Signature header on the inbound request. Write-only: * the secret is accepted on configure but is not returned in any get/list response; * responses expose `contextWebhook.hasSigningSecret` (boolean) in its place so you * can confirm the secret is configured without reading the value back. * @param options.contextWebhook.timeoutMs - How long AgentCall waits for your response * before falling back to the static prompt. Default 800ms, capped at 1500. * @param options.contextWebhook.headers - Optional extra HTTP headers AgentCall sends * alongside the HMAC-signed request (for your own auth layer on top, if needed). */ configureInboundAi(numberId: string, options: { systemPrompt: string; voice?: string; /** * Spoken language. `'auto'` (default) matches the caller's language * naturally. Specific ISO-639-1 codes pin the AI to that language * even if the caller speaks another. Stored separately from the * system prompt so swapping language never wipes the prompt. */ language?: 'auto' | 'en' | 'es' | 'fr' | 'de' | 'it' | 'pt' | 'nl' | 'ja' | 'ko' | 'zh' | 'hi' | 'ar' | 'ru' | 'id' | 'tr' | 'pl' | 'uk' | 'vi' | 'ta' | 'ms' | 'ro' | 'el' | 'cs' | 'sv' | 'hu' | 'da' | 'fi' | 'no' | 'sk' | 'hr' | 'bg'; firstMessage?: string; maxDurationSecs?: number; /** * Transfer-to-human number (E.164). When set, the AI can hand a live * call off to this number: when the caller asks for a real person (or * the AI cannot help), the AI says a short handoff line and the call is * transferred, presenting the original caller's number to whoever * answers. If nobody answers within about 25 seconds the AI resumes * and takes a message. The human portion of a transferred call bills * at the standard $0.035/min voice rate; AI minutes stop at handoff. * `null` or unset = no transfer (the AI takes a message). */ transferTo?: string | null; notify?: { emailTo?: string; smsTo?: string; businessName?: string; agencyName?: string; }; record?: boolean; contextWebhook?: { url: string; signingSecret: string; timeoutMs?: number; headers?: Record; }; /** * Two-way SMS handling. `'ai'` = inbound texts get an LLM reply from * AgentCall (managed gpt-4o-mini). `'relay'` = AgentCall runs no LLM and * forwards each inbound text to your own agent (`agentWebhook`), which * replies via `client.smsConversations.reply()`. `'off'` (default) = * OTP parsing only. STOP/START is always handled first. */ smsMode?: 'off' | 'ai' | 'relay'; /** Optional system prompt for SMS replies (smsMode 'ai'). Falls back to systemPrompt. */ smsSystemPrompt?: string; /** * Action bridge. When set, the SMS agent can call your declared tools; * AgentCall HMAC-signs and POSTs each tool call to this URL and feeds * your JSON `result` back to the agent. Same security model as * contextWebhook; per-tool timeout caps at 8000ms. */ actionWebhook?: { url: string; signingSecret: string; timeoutMs?: number; headers?: Record; }; /** * Tools the SMS agent may call via the action bridge (max 8). Each is * passed to the model verbatim as a function definition. */ tools?: Array<{ name: string; description: string; parameters: Record; }>; /** * Relay target for `smsMode: 'relay'`. AgentCall HMAC-POSTs each inbound * text to this URL; your own agent replies via * `client.smsConversations.reply()`. AgentCall runs no LLM on this path. */ agentWebhook?: { url: string; signingSecret: string; timeoutMs?: number; headers?: Record; }; /** * Relay sender allowlist (E.164). When set and non-empty, `smsMode: * 'relay'` only forwards texts from these numbers to your agent (so your * personal agent answers only you); others are silently dropped. A * sender-ID gate, not cryptographic auth. */ allowedSenders?: string[]; }): Promise; /** * Get the current inbound config for a number, or null if not configured. * `carrierTier` is `'primary'` or `'fallback'` — vendor-neutral identifier * for the underlying carrier pool. Inbound AI voice is supported on the * primary tier today. * * BYOK status lives inside `config`: * - `config.voiceMode` is `'managed'` or `'byok'` * - `config.hasByokKey` is true when a key is saved * - `config.byokOpenaiApiKeyPreview` is a redacted preview (e.g. `'sk-...AbCd'`) * - `config.byokConfiguredAt` is the ISO 8601 timestamp * * The full key is never returned. */ getInboundConfig(numberId: string): Promise; /** * Disable inbound AI on a number. Future calls will be hung up by the carrier. */ disableInboundAi(numberId: string): Promise; /** * Save a BYOK (bring-your-own-key) OpenAI key for this number and switch * voice billing to BYOK mode. The key is validated against the voice API * before saving (atomic: only commits if the test passes). Both inbound * and outbound AI calls on this number will then use the saved key and * bill at $0.10/min on Pro instead of $0.40/min managed. The underlying * OpenAI usage is paid directly by the customer. * * The key is encrypted at rest (AES-256-GCM) and is never returned in * any response. Only a redacted preview is exposed. * * Pro plan only. * * @param numberId - The phone number ID to enable BYOK on. * @param apiKey - Your OpenAI API key (sk-... or sk-proj-...). * @throws {AgentCallError} `byok_key_invalid` (422) if the key fails validation. * @throws {AgentCallError} `plan_limit_byok` (403) if the agent is not on Pro. */ setByokKey(numberId: string, apiKey: string): Promise; /** * Clear the saved BYOK key on a number and flip voice billing back to * managed mode ($0.40/min on Pro, AgentCall pays OpenAI). Preserves * every other inbound config field (systemPrompt, voice, notify, etc.) * so disabling BYOK does not wipe the number's setup. * * @param numberId - The phone number ID to revert to managed mode. */ disableByok(numberId: string): Promise; /** * Save a reusable outbound AI agent on this number. The dashboard's * Place AI call dialog hydrates from this blob, so the customer doesn't * retype the prompt + voice + language for every outbound call from the * same number. Useful for appointment-setters, lead follow-up, recurring * check-in agents that call different recipients with the same persona. * * Independent of the inbound AI receptionist — saving an outbound agent * never touches the inbound config on the same number, and vice versa. * * Pro plan only. * * @param numberId - The phone number ID to save the agent on. * @param options - The outbound agent shape (systemPrompt required; * firstMessage / voice / language / maxDurationSecs / record / templateId * optional). Saving overwrites any existing saved agent on this number. * @throws {AgentCallError} `plan_limit_voice_ai` (403) if the agent is not on Pro. */ setOutboundDefaults(numberId: string, options: OutboundDefaults): Promise; /** * Read the saved outbound AI agent on a number, or null when none is configured. * * @param numberId - The phone number ID to read defaults for. */ getOutboundDefaults(numberId: string): Promise; /** * Clear the saved outbound AI agent on a number. The Place AI call dialog * then falls back to the generic defaults. Does not affect the inbound AI * receptionist on the same number. * * @param numberId - The phone number ID to clear defaults from. */ clearOutboundDefaults(numberId: string): Promise; /** * Enable Premium Voice on a number, or change its premium voice. Premium * Voice answers inbound calls with a higher-quality, brandable voice and * bills at $0.59/min on top of the Pro plan. The same call both enables * premium (first time) and swaps the voice (subsequent calls), so it is * idempotent and safe to retry. * * The number must already have inbound AI configured * (`configureInboundAi`). Pick a `voiceId` from * `client.calls.premiumVoices()`. Provisioning into the premium provider * is atomic: the number only flips to premium if provisioning succeeds. * * Pro plan only, and a payment method must be on file (premium is metered). * * @param numberId - The phone number ID to enable Premium Voice on. * @param voiceId - A premium voice id from `client.calls.premiumVoices()`. * @throws {AgentCallError} `number_not_found` (404) if the number doesn't exist or isn't owned by you. * @throws {AgentCallError} `invalid_premium_voice` (400) if `voiceId` isn't a recognized premium voice. * @throws {AgentCallError} `payment_method_required` (402) if no card is on file (response carries `setupUrl`). * @throws {AgentCallError} `plan_limit_premium_voice` (403) if the agent is not on Pro (response carries `upgradeUrl`). * @throws {AgentCallError} `inbound_ai_required` (409) if the number has no inbound AI configured yet. * @throws {AgentCallError} `premium_voice_provisioning_failed` (502) / `premium_voice_unavailable` (503) on a transient provider issue. */ setPremiumVoice(numberId: string, voiceId: string): Promise; /** * Disable Premium Voice on a number, reverting it to the standard voice. * Preserves every other inbound config field (systemPrompt, voice, * firstMessage, language, notify, contextWebhook, record). Pro-gated like * `setPremiumVoice`. Idempotent: disabling an already-standard number is a * no-op that still returns the standard state. * * @param numberId - The phone number ID to revert to the standard voice. * @throws {AgentCallError} `number_not_found` (404) if the number doesn't exist or isn't owned by you. */ disablePremiumVoice(numberId: string): Promise; } declare class SMSResource { private client; constructor(client: AgentCall); /** * Send an SMS from a provisioned phone number. * * Free plan: 10 outbound SMS/month. Received texts do not count against the * quota. Pro plan: unlimited, billed per message. * * @param options - SMS options (from, to, body). * @param options.from - Your provisioned number in E.164 format. * @param options.to - Destination number in E.164 format. * @param options.body - Message text, max 1600 characters. * @param options.idempotencyKey - Retry-safe key scoped per phone number. A * duplicate key replays the original response without re-texting. When * omitted, the SDK generates one automatically so its own automatic * retries (429/5xx/network errors) can never double-send. * @returns The created message with delivery status. * @throws {AgentCallError} `plan_limit` if SMS quota exceeded. * @throws {AgentCallError} `destination_not_verified` (403) if the account is * new and may not contact this number yet. New accounts can text numbers * they own, anyone who contacted them first (30-day window), and * individually verified numbers. To lift it on Pro, submit a business * verification (`POST /v1/business-verification`) or verify the single * number (`POST /v1/verified-destinations`). It also lifts on its own after * 7 days on Pro. Retrying will not help. * @throws {AgentCallError} `validation_error` if `from` number isn't yours. * @throws {Error} If `to` is not a valid E.164 phone number. */ send(options: SendSMSOptions): Promise; /** * Get inbound messages for a phone number. * * @param numberId - The phone number ID to query. * @param options - Optional filters and pagination. * @param options.limit - Max results per page (default 20). * @param options.cursor - Pagination cursor from a previous response. * @param options.since - Only return messages after this ISO 8601 timestamp. * @param options.otpOnly - If `true`, only return messages with detected OTP codes. * @returns Paginated list of inbound messages. */ inbox(numberId: string, options?: InboxOptions): Promise>; /** * Get a single message by ID. * * @param messageId - The message ID (e.g. `msg_xyz789`). * @returns The message details including OTP if detected. * @throws {AgentCallError} `not_found` if the message doesn't exist. */ get(messageId: string): Promise; /** * Poll the inbox until an OTP code arrives. Designed for AI agent signup/verification flows. * * Repeatedly checks the inbox for messages with extracted OTP codes. Returns as soon as * one is found, or `null` if the timeout is reached. * * @param numberId - The phone number ID to watch for incoming OTPs. * @param options - Polling options. * @param options.timeout - Max wait time in ms (default 60000 = 60s). * @param options.pollInterval - Time between polls in ms (default 2000 = 2s). * @param options.since - Only consider messages after this ISO 8601 timestamp. * @returns The OTP code string (e.g. `"482913"`), or `null` if timeout. * * @example * ```typescript * const otp = await client.sms.waitForOTP('num_abc123', { timeout: 90000 }) * if (otp) console.log(`Got OTP: ${otp}`) * ``` */ waitForOTP(numberId: string, options?: WaitForOTPOptions): Promise; } declare class SmsConversationsResource { private client; constructor(client: AgentCall); /** * List two-way AI SMS conversation threads for this agent, newest activity * first. * * @param params - Optional pagination. * @param params.limit - Max results per page (default 20). * @param params.cursor - Pagination cursor from a previous response. * @returns Paginated list of conversations. */ list(params?: { limit?: number; cursor?: string; }): Promise>; /** * Get a single SMS conversation thread, including its recent messages * (up to the last 50, oldest first). * * @param conversationId - The conversation ID (e.g. `smsconv_abc123`). */ get(conversationId: string): Promise; /** * Send a reply into a conversation thread. This is the reply path for * LLM-direct-text / relay mode: your own agent calls this when it has an * answer and AgentCall sends + threads the SMS. The reply is blocked if the * recipient has opted out (STOP). Pass `idempotencyKey` to make a crashed or * retried agent safe: a duplicate key returns `{ status: 'duplicate' }` * without sending again. * * @param conversationId - The conversation ID (e.g. `smsconv_abc123`). * @param options.body - The reply text (1-1600 chars). * @param options.idempotencyKey - Optional dedup key, scoped to your agent. * When omitted, the SDK generates one automatically so its own automatic * retries can never double-send the reply. */ reply(conversationId: string, options: { body: string; idempotencyKey?: string; }): Promise; } declare class CallsResource { private client; constructor(client: AgentCall); /** * Initiate an outbound phone call. * * Free plan: 5 minutes/month. Pro plan: unlimited + recording available. * Recording costs $0.01/min and requires Pro plan. * * @param options - Call options. * @param options.from - Your provisioned number in E.164 format. * @param options.to - Destination number in E.164 format. * @param options.webhookUrl - Optional HTTPS URL for call status events. * @param options.record - Enable recording (Pro plan only). * @param options.idempotencyKey - Retry-safe key scoped per phone number. A * duplicate key replays the original response without placing a second * call. When omitted, the SDK generates one automatically so its own * automatic retries (429/5xx/network errors) can never double-dial. * @returns The initiated call with status and ID. * @throws {AgentCallError} `plan_limit_standard_calls` on the Free plan (plain calls are Pro-only; use `initiateAI` or inbound AI instead). * @throws {AgentCallError} `plan_limit` if call minutes exhausted or recording on Free plan. * @throws {AgentCallError} `redial_limit_exceeded` after 3 attempts to the same destination in a UTC day (numbers you own or verified are exempt). * @throws {Error} If `to` is not a valid E.164 phone number. * * Plain calls carry no live audio: the callee hears a short automated line * identifying the call as coming from an AI agent, then silence. Use * `initiateAI` when the agent needs to talk. */ initiate(options: InitiateCallOptions): Promise; /** * List call history. * * @param params - Optional pagination. * @param params.limit - Max results per page (default 20). * @param params.cursor - Pagination cursor from a previous response. * @returns Paginated list of calls. */ list(params?: { limit?: number; cursor?: string; }): Promise>; /** * Get a single call by ID. * * @param callId - The call ID (e.g. `call_abc123`). * @returns The call details including duration and recording URL if available. * @throws {AgentCallError} `not_found` if the call doesn't exist. */ get(callId: string): Promise; /** * Terminate an active call. * * @param callId - The call ID to hang up. * @throws {AgentCallError} `not_found` if the call doesn't exist or is already completed. */ hangup(callId: string): Promise; /** * Start an AI-powered voice call. The AI handles the conversation autonomously and returns a transcript when the call ends. * Pro plan only. Available on US and Canada numbers. Costs $0.40/min. * * For CSV / batch flows, pass `useSavedAgent: true` to hydrate the * systemPrompt + voice + language + firstMessage + maxDurationSecs + * record fields from the saved outbound agent on the from-number * (set via `client.numbers.setOutboundDefaults()`). Per-call body * fields override saved values. Pass `idempotencyKey` to make retries * safe: a second request with the same key replays the original * response and does NOT place a duplicate carrier call. * * @param options - AI call options. * @param options.from - Your provisioned phone number (ID or E.164). * @param options.to - Destination number in E.164 format. * @param options.systemPrompt - Instructions for the AI during the call. Required UNLESS `useSavedAgent: true`. * @param options.voice - AI voice (default: shimmer when no saved agent). 10 options including the natural-sounding marin and cedar. Preview at GET /v1/calls/voices. * @param options.firstMessage - What the AI says first when the call connects. * @param options.maxDurationSecs - Max duration in seconds (default 600). * @param options.useSavedAgent - Hydrate omitted fields from the saved outbound agent on the from-number. * @param options.idempotencyKey - Retry-safe key scoped per phone number. Max 200 chars. * When omitted, the SDK generates one automatically so its own automatic * retries (429/5xx/network errors) can never double-dial. * @returns The initiated AI call with status and voice info. * @throws {AgentCallError} `plan_limit_voice_ai` if not on Pro plan. * @throws {AgentCallError} `carrier_not_supported` if the number isn't on a supported carrier (US/Canada only). * @throws {AgentCallError} `no_saved_agent` if `useSavedAgent: true` but the number has no saved agent. * @throws {AgentCallError} `system_prompt_required` if both `systemPrompt` and `useSavedAgent` are omitted. */ initiateAI(options: InitiateAICallOptions): Promise; /** * Get the transcript for a completed AI voice call. * * @param callId - The AI call ID. * @returns The transcript with conversation entries, summary, and duration. * @throws {AgentCallError} `call_not_found` if the call doesn't exist. * @throws {AgentCallError} `transcript_not_found` if the call completed but has no transcript. */ getTranscript(callId: string): Promise; /** * Get the Auditable Call Memory report for a completed AI call. * * The report is the structured analysis the post-call extractor produces: * summary, intent, urgency, extracted facts/preferences/decisions, the * `nextCallContext` paragraph, and the MemoryCandidate rows linked to * this call. Reports become available 5-30 seconds after the call ends * (the extractor runs in a background queue). * * @param callId - The AI call ID. The call must be `completed`. * @returns The full report with candidates, or null when the report is * still being extracted (HTTP 202 from the API). Throw on 404 / other. */ getReport(callId: string): Promise; /** * Get a short-lived signed URL for the recording of a completed call. * The URL is good for ~1 hour and can be played directly via an HTML * `