Anatomy of a tool
Two pieces:- The schema — an OpenAI-style function definition
(
{type: "function", function: {name, description, parameters}}) that tells the LLM what the tool does and what arguments it takes. - The endpoint — the URL ThunderPhone’s servers call when the LLM decides to use the tool. The request is JSON POST with the LLM’s chosen arguments as the body.
1. Choose a storage strategy
Inline on the agent
Attach a one-off tool to the agent’s
tools array. Simple, but
not reusable.Saved integration
Store the tool as a reusable integration
and link it from many agents. Recommended for anything used more
than once.
2. Create the integration
id (a UUID).
3. Sandbox-test the endpoint
Before you link the integration to an agent, fire a signed request from ThunderPhone’s servers to confirm connectivity:Response
400 code=url_not_allowed.
4. Link the integration to an agent
Attach viaintegration_ids when you create or update an agent:
get_weather when the caller asks
about conditions” — or it can discover them implicitly from the
schema descriptions.
5. Implement the endpoint
When the agent invokes the tool, ThunderPhone sends a signed POST to yourendpoint_url:
6. Test the loop
Run a mic session against the agent and ask the question your tool handles (“What’s the weather in 94110?”). The transcript’s structured history shows the full round trip:GET /v1/calls/{call_id}/history.
Common gotchas
Agent never calls the tool
Agent never calls the tool
The LLM decides based on the tool’s description. If the caller’s
question doesn’t match the description, the model won’t invoke
the tool. Tighten the description (add common synonyms and
phrasing) or mention it explicitly in the agent prompt (“When the
caller asks about weather, use
get_weather.”).Tool returns too much data
Tool returns too much data
Responses over 6 kB are truncated in the transcript preview. Return
just the fields the LLM needs — not your whole row.
Timeouts
Timeouts
Tool endpoints have a 10-second default timeout. If you need longer,
handle it asynchronously: return
{"status": "pending", "request_id": "..."}
and surface the result via a separate tool call.Versioning
Versioning
Every integration
PATCH creates a new revision. Inspect
GET /v1/integrations/{id}/versions
to see who changed what. If you break a tool’s schema, you can
roll back manually by PATCH-ing an older snapshot back in.Next steps
Integrations reference
CRUD, transfer, version history.
Function Tools spec
Full JSON schema grammar and the signed-endpoint contract.
Verify signatures
Apply the webhook-signature pattern to tool endpoints.
Transcript + history API
Inspect the full round-trip of a tool call.