Open in
Python and TypeScript SDKs
Typed ThunderPhone clients for agents, calls, and the public API.
The ThunderPhone SDKs use the OpenAPI specification
for request and response types. They read THUNDERPHONE_API_KEY from your server's
environment. Create a key in the dashboard under Organization → Keys, and keep
it in your secret manager. Never include it in browser code.
TypeScript
Requires Node.js 18 or later. Both ESM and CommonJS are supported.
npm install @thunderphone/sdkimport { ThunderPhone } from "@thunderphone/sdk";
const api = new ThunderPhone();
const agent = await api.agents.create({
name: "Reception",
prompt: "Help callers with scheduling and business information.",
voice: process.env.THUNDERPHONE_VOICE!,
});
const call = await api.calls.place({
agent_id: agent.id,
from_number: process.env.FROM_NUMBER!,
to_number: process.env.TO_NUMBER!,
idempotency_key: "appointment-123",
});
const done = await api.calls.waitForCompletion(call.call_id, { timeoutMs: 300_000 });
if (done.status === "failed") throw new Error(done.end_reason ?? "Call failed");
console.log((await api.calls.transcript(call.call_id)).transcripts);Pass { apiKey, baseUrl } to configure the client explicitly. baseUrl defaults
to https://api.thunderphone.com, without /v1. All operations are available via
api.client.GET, .POST, .PUT, .PATCH, and .DELETE with typed paths and bodies.
waitForCompletion accepts an AbortSignal, timeoutMs, and pollIntervalMs.
Python
Requires Python 3.10 or later.
pip install thunderphoneimport os
from thunderphone import ThunderPhone, AgentRequest, PlaceCallRequest
with ThunderPhone() as api:
agent = api.agents.create(AgentRequest(
name="Reception",
prompt="Help callers with scheduling and business information.",
voice=os.environ["THUNDERPHONE_VOICE"],
))
call = api.calls.place(PlaceCallRequest(
agent_id=agent.id,
from_number=os.environ["FROM_NUMBER"],
to_number=os.environ["TO_NUMBER"],
idempotency_key="appointment-123",
))
done = api.calls.wait_for_completion(call.call_id, timeout=300)
if done.status == "failed":
raise RuntimeError(done.end_reason)
print(api.calls.transcript(call.call_id).transcripts)Pass api_key= and base_url= to configure the client explicitly. Every operation
also has typed sync and async functions under thunderphone.generated.api, with
models under thunderphone.generated.models. Pass client=api.client to use the
same authentication and client-identification header.
Calls and errors
Choose THUNDERPHONE_VOICE from GET /v1/voices. Set FROM_NUMBER to an
outbound-capable number connected to your carrier, and TO_NUMBER to your test
destination. Outbound calling requires sufficient balance and the organization's
outbound confirmation. ThunderPhone-provisioned demo numbers are inbound only.
Polling returns completed or failed calls; inspect the status before consuming
the transcript. Helpers raise ThunderPhoneError for unsuccessful HTTP responses
and expose status and body. Transport errors propagate. Requests that mutate
state are not retried automatically. Reuse an idempotency key only for the same
outbound-call request.
For direct tool use from a coding agent, connect to the MCP server. See the coding-agent guide for setup and the OpenAPI specification for every operation.