Skip to main content

How tools work

When a caller says something that matches a tool’s trigger (defined in its description field), the agent fires that tool automatically mid-conversation. The key thing to understand: tools are attached to LLM models, not to agents directly.
Agent  →  LLM Model  →  Tools
One LLM model can have multiple tools. Every agent that uses that model inherits all its tools automatically. To give an agent a new tool, update the LLM model it is linked to — not the agent itself. If you haven’t built an agent yet, start with the Quickstart first.

Tool types

TypeWhat the agent doesBest for
api_callCalls your HTTP endpointLookups, CRM updates, custom logic
transfer_callTransfers to a phone numberRouting to humans
extract_informationSaves structured data from the conversationCapturing name, email, budget
end_callHangs up the callCompleting a flow cleanly
send_smsSends a text messageFollow-ups, confirmations
send_emailSends an emailLead handoffs, summaries
schedule_calendar_eventBooks a calendar eventDemo scheduling, appointments
Whenever a tool talks to a third-party provider — send_sms, send_email, or schedule_calendar_event — you’ll need a credential_id pointing at an integration for that provider. api_call, transfer_call, extract_information, and end_call don’t need one.

Step 1 — Create a tool

send_sms

Sends a text message when triggered. No credential_id needed — the SMS is sent from the same number used to make the call (your purchased OneInbox number or your Twilio/Telnyx number registered with OneInbox).
curl -X POST https://api.oneinbox.ai/v1/tools \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "notify_team_sms",
    "type": "send_sms",
    "description": "SMS the team when a lead is captured. Trigger when the caller shares their contact details.",
    "messaging_config": {
      "to": "caller",
      "body_template": "New lead: {name} ({phone})"
    }
  }'
FieldWhat it does
descriptionHow the agent decides when to fire this tool — write it as a trigger condition
messaging_config.to"caller" to text whoever is on the call, or an explicit E.164 number to notify your team
messaging_config.body_templateMessage text. Use {variable_name} (single braces) for dynamic values. Use {{caller}} to auto-insert the caller’s phone number
The SMS sends from the same number used for the call — make sure that number has SMS capability enabled. When purchasing a number via OneInbox or registering your own Twilio/Telnyx number, verify that it supports SMS before using this tool.
{{caller}} is a built-in variable that auto-resolves to the caller’s phone number at call time — the system fills it in automatically. Never ask the caller for their number just to include it in the message body.

send_email

Sends an email when triggered. Use this to deliver lead summaries to your sales team, send follow-up emails to callers, or notify someone when a key moment happens in a call.
curl -X POST https://api.oneinbox.ai/v1/tools \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "notify_team_email",
    "type": "send_email",
    "description": "Email the sales team when a lead is captured. Trigger when the caller expresses interest.",
    "credential_id": "<resend_or_sendgrid_credential_id>",
    "messaging_config": {
      "to": "sales@example.com",
      "subject_template": "New lead: {name}",
      "body_template": "{summary}"
    }
  }'
FieldWhat it does
descriptionHow the agent decides when to fire this tool — write it as a trigger condition
credential_idUUID of a resend or sendgrid integration. The email sends from that integration’s from_email — which must be on a domain you’ve verified with the provider, or the send fails with HTTP 403
messaging_config.toRecipient email address. Use {{email}} to send to the caller’s email address
messaging_config.subject_templateEmail subject line. Use {variable_name} (single braces) for dynamic values
messaging_config.body_templateEmail body text. Use {variable_name} (single braces) for dynamic values pulled from the conversation
Want every call to auto-send a summary SMS/email without a tool call? Set post_call_sms / post_call_email directly on the agent instead — see Agents. Tools fire mid-call based on a trigger; post-call config fires once, automatically, after every call ends.
{{email}} resolves from the dynamic_variables object passed when the call is initiated — for example "dynamic_variables": {"email": "caller@example.com"} in the outbound call request. Pass the caller’s email at dial time and use {{email}} anywhere in to, subject_template, or body_template to insert it automatically.

schedule_calendar_event

Books a calendar event when triggered. Use this when you want the agent to schedule a demo or follow-up meeting directly during the call.
curl -X POST https://api.oneinbox.ai/v1/tools \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "book_demo",
    "type": "schedule_calendar_event",
    "description": "Book a product demo when the caller asks to schedule a meeting or demo. Trigger phrases: schedule, book a demo, set up a call.",
    "credential_id": "<calcom_credential_id>",
    "calendar_config": {
      "event_type_id": 123456,
      "duration_minutes": 30,
      "timezone": "America/New_York"
    }
  }'
FieldWhat it does
descriptionTrigger condition — tell the agent exactly when to fire this (e.g. “when the caller agrees to a meeting”)
credential_idUUID of a calcom integration. Required — the tool checks availability and books against this Cal.com account
calendar_config.event_type_idThe Cal.com event type ID to book against. Find it in your Cal.com dashboard URL or via GET https://api.cal.com/v2/event-types
calendar_config.duration_minutesLength of the event in minutes
calendar_config.timezoneIANA timezone string for the booking (e.g. "Asia/Kolkata", "Asia/Tokyo", "Europe/London", "America/New_York"). Defaults to UTC if omitted — set this to the caller’s timezone so the booked slot appears at the correct local time
The agent must collect the attendee’s name and email during the call — both are required by Cal.com to complete the booking. If the requested slot has no availability (e.g. outside your Cal.com working hours), the booking fails with HTTP 400.

api_call

Calls your own HTTP endpoint during the call. Use this to look up information (e.g. order status, account details), push data to your CRM, or trigger custom business logic based on what the caller says.
curl -X POST https://api.oneinbox.ai/v1/tools \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "check_inventory",
    "type": "api_call",
    "description": "Look up inventory by SKU when the caller asks about stock or availability.",
    "url": "https://api.example.com/inventory",
    "method": "POST",
    "headers": {
      "Authorization": "Bearer <your_secret>"
    },
    "parameters": [
      {
        "name": "sku",
        "type": "string",
        "required": true,
        "description": "Product SKU the caller mentioned"
      }
    ],
    "run_in_background": true,
    "speak_during_execution": true
  }'
FieldWhat it does
urlYour endpoint URL — must be publicly reachable
methodHTTP method (GET, POST, PUT, PATCH)
headersAny auth headers your endpoint requires
parametersFields the agent extracts from the conversation and passes to your API as the request body
run_in_backgroundtrue = agent keeps talking while the API call runs in parallel. false = agent pauses and waits for the response
speak_during_executiontrue = agent says something like “Let me check that for you…” while the API call is in progress

Nested parameters (full JSON Schema)

parameters only supports a flat list of fields. If your endpoint needs nested objects, arrays, or enums, use parameters_schema instead — a raw JSON Schema object, validated server-side before save. Use one or the other, not both:
curl -X POST https://api.oneinbox.ai/v1/tools \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "create_ticket",
    "type": "api_call",
    "description": "Open a support ticket when the caller reports an issue.",
    "url": "https://api.example.com/tickets",
    "method": "POST",
    "parameters_schema": {
      "type": "object",
      "properties": {
        "subject": { "type": "string", "description": "Ticket subject" },
        "priority": { "type": "string", "enum": ["low", "high"] },
        "items": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": { "sku": { "type": "string" } },
            "required": ["sku"]
          }
        }
      },
      "required": ["subject"]
    }
  }'

transfer_call

Transfers the caller to a real phone number. Use this when the caller asks to speak with a human or needs to reach a specific team. OneInbox supports two transfer modes — cold (default) and warm.
ModeWhat happens
Cold (default)Blind SIP REFER — caller is immediately handed off. The human picks up with no prior context.
WarmAgent calls the human first, briefs them with the caller’s context, then connects the caller once the human is ready. Caller hears hold music during the briefing.

Cold transfer

The default. The caller is transferred instantly — no briefing, no hold music. Use this when speed matters more than context handoff (e.g. routing to a general support queue).
curl -X POST https://api.oneinbox.ai/v1/tools \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "transfer_to_support",
    "type": "transfer_call",
    "description": "Transfer to a human agent when the caller asks to speak to a person or escalate. Trigger phrases: talk to someone, speak to a human, I want a real person.",
    "transfer_to": "+15105550100"
  }'
Omitting transfer_config entirely is equivalent to transfer_config.mode: "cold".

Warm transfer

The agent calls the human first, gives them a briefing (caller’s name, reason for calling, any relevant context), then bridges the caller in once the human is ready. The caller hears hold music during the consult. Use this when the human needs context before picking up — e.g. transferring to a sales manager for a high-value lead.
curl -X POST https://api.oneinbox.ai/v1/tools \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "warm_transfer_to_supervisor",
    "type": "transfer_call",
    "description": "Warm transfer to a supervisor when the caller needs escalation.",
    "transfer_to": "+15105550100",
    "transfer_config": {
      "mode": "warm",
      "extra_instructions": "Greet the supervisor, give them the caller'\''s name and issue, and ask if they'\''re ready before connecting."
    }
  }'
FieldWhat it does
transfer_toE.164 phone number to transfer the caller to
descriptionTrigger condition — be specific so the agent knows exactly when to fire this tool
transfer_config.mode"cold" (default) — blind handoff; "warm" — agent briefs human first
transfer_config.extra_instructionsWarm mode only — guides what the agent should say to the human during the briefing

extract_information

Silently captures structured data from the conversation as it happens — the agent doesn’t announce it to the caller. Use this to save lead qualification data, capture names and emails, or record key facts from the call.
curl -X POST https://api.oneinbox.ai/v1/tools \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "lead_capture",
    "type": "extract_information",
    "description": "Extract lead info from the conversation. Run this once the caller has shared their name and contact details.",
    "extraction_schema": {
      "fields": [
        {
          "name": "full_name",
          "type": "string",
          "required": true,
          "description": "Caller full name"
        },
        {
          "name": "email",
          "type": "string",
          "description": "Caller email address"
        },
        {
          "name": "interested",
          "type": "boolean",
          "description": "Whether the caller expressed interest"
        }
      ]
    }
  }'
FieldWhat it does
descriptionTells the agent when to run the extraction — not a phrase trigger, but a condition (e.g. “once the caller has answered the qualifying questions”)
extraction_schema.fieldsList of fields to extract. Each field has a name, type (string, boolean, number), optional required, and a description that guides the extraction
The captured data is available in the call record after the call ends.

end_call

Hangs up the call cleanly. Use this at the end of a flow — after a booking, after the caller says goodbye, or when the agent has completed its task. Without this tool, the call continues until the silence timeout is reached.
curl -X POST https://api.oneinbox.ai/v1/tools \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "hangup",
    "type": "end_call",
    "description": "End the call cleanly after the agent has completed its task or the caller says goodbye."
  }'

Step 2 — Attach tools to your LLM model

Creating a tool makes it available in your account, but the agent can’t use it yet. You need to attach it to the LLM model linked to your agent. Use the llm_id from your agent’s create response — this is the AI brain that decides what to do during a call.
curl -X PATCH https://api.oneinbox.ai/v1/models/<llm_id> \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "tool_ids": ["<tool_id_1>", "<tool_id_2>"]
  }'
Every agent linked to this llm_id picks up the change immediately — no restart required.

Step 3 — Reference tools in your system prompt

The description on each tool is the trigger signal — the LLM reads it to decide when to fire the tool automatically. The system prompt gives the agent context and ordering for how to use tools in the flow. Reference tools by their name field (the name you set when creating the tool), not by tool ID. The LLM matches the name to the tool it has available and fires it at the right moment.
You are a helpful sales assistant for Acme Corp.

When the caller shares their name and email, use the lead_capture tool immediately.

After capturing their info, ask if they'd like to receive a follow-up SMS. If they say yes, use notify_team_sms.

If at any point the caller asks to speak to a human, use transfer_to_human.

After the task is complete or the caller says goodbye, use end_call.

Keep all replies under two sentences. Be warm and direct.
Write the description as a trigger condition (“Fire when the caller says X” or “Run once the caller has answered the qualifying questions”). The system prompt then reinforces the order and flow. Both are read by the LLM — the description drives when, the system prompt drives how.

Reading tool results after a call

After the call ends, the extracted data and tool activity appear in the call record. Stop the call first, wait a few seconds, then fetch:
# 1. Stop the call
curl -X POST https://api.oneinbox.ai/v1/calls/<call_id>/stop \
  -H "Authorization: Bearer <api_key>"

# 2. Wait 2–3 seconds, then fetch
curl https://api.oneinbox.ai/v1/calls/<call_id> \
  -H "Authorization: Bearer <api_key>"
{
  "id": "call_abc123",
  "status": "completed",
  "messages": [
    { "role": "agent", "content": "Hi! How can I help?" },
    { "role": "user",  "content": "My name is Sama, my email is sama@acme.com" }
  ],
  "outcome": "Interested",
  "analysis": {
    "summary": "Caller expressed interest and shared contact details."
  }
}
messages and analysis are only available after the call ends — both are empty while the call is active.

Manage tools

List all tools

Retrieve every tool in your account. Useful for finding tool IDs when you need to attach or update them.
curl https://api.oneinbox.ai/v1/tools \
  -H "Authorization: Bearer <api_key>"

Update a tool

Change a tool’s name, description, or config. For example, update the trigger description to make the agent more (or less) sensitive to firing it.
curl -X PATCH https://api.oneinbox.ai/v1/tools/<tool_id> \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{ "description": "Updated trigger description" }'

Delete a tool

Remove a tool permanently. If the tool is attached to an LLM model, detach it first by PATCHing the model with an updated tool_ids array that excludes the deleted tool’s ID.
curl -X DELETE https://api.oneinbox.ai/v1/tools/<tool_id> \
  -H "Authorization: Bearer <api_key>"

API reference

Create tool · List tools · Update tool · Delete tool