Skip to main content
An agent is the reusable unit of call behavior. Every call in CallingBox, inbound or outbound, is handled by an agent. You configure the persona, voice, tools, structured returns, and voicemail behavior once on the agent; individual calls are cheap executions that reference the agent by id.

Inbound vs outbound

Every agent has a type of either inbound or outbound. The type is fixed at creation time and determines how the agent is used.
TypeWho starts the callHow numbers are used
outboundYour code calls POST /v1/calls with the agent idThe agent’s attached numbers are valid caller IDs. The primary number is the default.
inboundSomeone dials one of the agent’s attached numbersCallingBox answers the incoming call and runs the agent.
A phone number can be attached to at most one inbound agent (that’s who answers). The same number can also be used as a caller ID by any number of outbound agents.

What lives on the agent

These fields are set on the agent and inherited by every call it handles:
FieldDescription
nameHuman label to identify the agent in the dashboard.
personaIdentity and policy: who the agent is, how it talks, what it never does. Falls back to a sensible default if omitted.
instructionsDefault task for calls this agent handles.
voiceTTS voice id.
languageBCP-47 language code.
returnsSchema for structured data extraction.
toolsIn-call tools the agent can invoke.
webhook_urlDefault per-call webhook URL for every call this agent handles.
voicemail_actionhangup or leave_message.
primary_number_idDefault caller ID for outbound; the number the agent “owns” for inbound.

What can be overridden per call

Outbound calls can override a small set of agent defaults at dispatch time. Inbound calls always use the agent’s configuration as-is (no per-call override).
FieldOverride behavior
instructionsReplaces the agent’s default instructions for this call. Not merged.
from_numberMust be another number attached to the same agent. Defaults to the agent’s primary_number_id.
contextArbitrary JSON the agent can reference mid-call.
webhook_urlOverrides the agent’s default for this call only.
metadataArbitrary key/value you can read off the call record later.
Everything else (persona, voice, returns, tools, language, voicemail_action) is locked to the agent for that execution.

Create an outbound agent

from callingbox import Callingbox

client = Callingbox()

agent = client.agents.create(
    name="Appointment reminders",
    type="outbound",
    instructions="Confirm dental appointments. Offer to reschedule if needed.",
    returns={"confirmed": "boolean", "reschedule_to": "string"},
    number_ids=["pn_abc123"],
    primary_number_id="pn_abc123",
)

print(agent.id)

Create an inbound agent

The shape is identical. Only the type and how you dispatch it change. An inbound agent with an attached number starts answering the moment it’s created.
agent = client.agents.create(
    name="Front desk",
    type="inbound",
    instructions="Answer calls for Bright Smiles Dental. Help with hours, directions, and appointment questions.",
    returns={"caller_name": "string", "reason": "string"},
    number_ids=["pn_xyz789"],
)
See Inbound calls for the full inbound flow.

Attach or detach numbers later

You can change an agent’s number attachments at any time.
client.agents.attach_number(agent.id, number_id="pn_new", set_as_primary=True)
client.agents.detach_number(agent.id, number_id="pn_old")
client.agents.set_primary_number(agent.id, number_id="pn_new")

Archive an agent

Agents are archived (soft-deleted). Historical calls remain available.
client.agents.archive(agent.id)

Outbound calls

Dispatch a call from an outbound agent.

Inbound calls

Let an inbound agent answer your numbers.

Structured results

Define the returns schema on your agent.

In-call tools

Give your agent mid-call actions.