Python SDK

Updated

API reference for the Conversational AI Platform (Preview) features of the Agora agents Python SDK, including saved agents, sessions, secrets, numbers, and campaigns.

Preview documentation

You're reading the Conversational AI Platform (Preview) SDK docs. Switch to Main.

The agora-agents Python SDK supports the Conversational AI Platform (Preview) alongside the Voice Agent API. This page covers the Platform features: saved agents, Platform sessions, secret sets, phone numbers, campaigns, and the low-level client.v3 namespace.

The vendor classes, such as OpenAI and DeepgramSTT, and the builder methods, such as with_llm(), are shared with the Voice Agent API. For those, see the Python SDK reference for Voice Agents.

Install

Platform support is in the SDK preview, version 3.0.0a3. You need Python 3.8 or later. Install the SDK in your project's virtual environment, and specify the version, because the default agora-agents release doesn't support the Platform API:

pip install agora-agents==3.0.0a3

The package imports as agora_agent. Import the classes you use, for example:

from agora_agent import Agent, Agora, Area, SavedAgent, secret_ref

Agora

Create a client with one of the following authentication methods. To choose one, see Choose an authentication method.

  • Token authentication: Pass your App ID and App Certificate. The SDK generates a ConvoAI token for each Platform request.

    import os
    from agora_agent import Agora, Area
    
    client = Agora(
        area=Area.US,
        app_id=os.environ["AGORA_APP_ID"],
        app_certificate=os.environ["AGORA_APP_CERTIFICATE"],
    )
  • Basic HTTP authentication: Pass your App ID, customer ID, and customer secret. The SDK sends Authorization: Basic <base64_credentials> with each request.

    import os
    from agora_agent import Agora, Area
    
    client = Agora(
        area=Area.US,
        app_id=os.environ["AGORA_APP_ID"],
        customer_id=os.environ["AGORA_CUSTOMER_ID"],
        customer_secret=os.environ["AGORA_CUSTOMER_SECRET"],
    )
ParameterTypeDescription
areaAreaRequired. The region for Voice Agent API routing. Platform requests use the Platform origin.
app_idstrRequired. Your Agora App ID.
app_certificatestrYour App Certificate. With token authentication, the SDK uses it to generate a token for each request. With Basic authentication, it's optional, and the SDK uses it only to generate the agent's RTC token.
auth_tokenstrA token you generated yourself, instead of app_certificate. The SDK sends Authorization: agora token=<auth_token>. The token must include the ConvoAI service.
customer_idstrYour customer ID, for Basic authentication. Set it with customer_secret. Don't combine it with auth_token.
customer_secretstrYour customer secret, for Basic authentication.
v3V3OptionsPlatform request settings: V3Options(base_url=None, headers={}). base_url overrides the Platform origin, which defaults to https://preview.ai.agora.io. You can also set the AGORA_AGENTS_V3_BASE_URL environment variable. The option takes precedence.

Without an App Certificate, the SDK can't generate the agent's RTC token. To start an RTC session with a Basic client and no App Certificate, pass the RTC token when you create the session.

For asyncio applications, use AsyncAgora. It takes the same parameters, and its methods are awaitable.

The client exposes the following Platform resources:

AttributeDescription
client.v3The low-level Platform namespace: agents, secrets, numbers, sessions, and campaigns. See Low-level API.
client.secretsThe same object as client.v3.secrets.
client.numbersThe same object as client.v3.numbers.
client.campaignsThe same object as client.v3.campaigns.

Agent

Agent is an immutable builder. Each builder method returns a new Agent. To save a configuration on the Platform, build it with the vendor classes and call save().

from agora_agent import Agent, DeepgramSTT, OpenAI, OpenAITTS

agent = (
    Agent(client=client)
    .with_stt(DeepgramSTT(model="nova-3", language="en-US"))
    .with_llm(OpenAI(model="gpt-4.1-mini"))
    .with_tts(OpenAITTS(model="tts-1", voice="alloy"))
    .with_variable("customer_name", type="str", required=True)
)

saved_agent = agent.save(name="Support agent")

Variables

with_variable(name, definition=None, **fields) -> Agent

Declares a variable and returns a new Agent. Pass the fields as keyword arguments, or as a dictionary in definition. The definition is validated locally.

FieldTypeDescription
typestrRequired. The data type: "str", "int", "float", "bool", "date", or "datetime".
requiredboolWhether every session must pass a value.
optionslistThe allowed values, 1 to 100 unique items.
extractboolWhether to extract the value after the session ends. Requires description.
descriptionstrUp to 2,000 characters. Required when extract is True.

A variable name starts with a lowercase letter and contains up to 64 lowercase letters, digits, and underscores.

Save an agent

save(*, name=None, agent_id=None) -> SavedAgent

Saves the configuration and returns a SavedAgent. Without agent_id, it creates a new agent. Names aren't unique, so saving twice creates two agents. To update a saved agent, prefer saved_agent.update(). With AsyncAgora, use await agent.save_async(...).

Start a session without saving

create_session(*, channel, agent_uid=None, remote_uids=None, ...) -> AgentSession

Creates a session from the builder without saving it. The SDK starts an ephemeral session on the Platform when the configuration has a secret reference or a variable, or when you set a Platform session option such as max_duration, values, labels, or data_policy. Otherwise, it uses the Voice Agent API. For the parameters, see Session parameters.

How the builder maps to the Platform

  • Credentials: A model without an API key uses managed mode. A model with an API key uses BYOK. A saved agent must use a secret_ref() as the key. An ephemeral session also accepts a key value.
  • Instructions and messages: The LLM's system messages become the agent's instructions. Its other messages become messages. greeting_message and greeting_configs become the agent's greeting.
  • Pipeline: Only cascaded ASR, LLM, and TTS pipelines are supported. An MLLM configuration can't be saved or used in a Platform session.
  • Unsupported fields: Builder settings without a Platform equivalent, such as SAL, advanced features, labels, RTC settings, and pipeline IDs, make save() raise an UnsupportedFieldError that lists them.

Secret references

secret_ref(secret_set: str, key: str) -> SecretRef

Returns the reference $secrets.<set>.<key> for a key in a secret set. It validates both names locally and makes no request. Each name contains 1 to 64 letters, digits, and underscores.

SavedAgent

A handle to an agent saved on the Platform. With AsyncAgora, the handle is AsyncSavedAgent, and its methods are awaitable.

MemberDescription
idThe agent ID.
nameThe agent name.
etagThe agent's ETag when the handle was loaded or saved.
dataThe saved configuration, as returned by the Platform.
rawThe client.v3.agents resource.
SavedAgent.get(client, agent_id)Class method. Loads a saved agent.
create_session(...)Creates a session that runs this agent. Returns an AgentSession. See Session parameters.
update(config, *, name=None)Saves a revised Agent to this agent ID, and keeps its name unless you pass name. The Agent must use the same client. Returns a new SavedAgent.
delete()Deletes the agent.
assign_number(number, *, max_call_duration_seconds=None, max_silence_duration_ms=None)Routes inbound calls on a phone number to this agent. number is an E.164 string, a number ID, or a number dictionary. Returns the updated number.
unassign_number(number)Removes this agent from a number's inbound routing.
list_numbers()Returns the numbers assigned to this agent. Scans all project numbers.

A handle is a snapshot. If another process changes the agent, load it again with SavedAgent.get().

Session parameters

saved_agent.create_session() and agent.create_session() take keyword arguments. The following apply to Platform sessions:

ParameterTypeDescription
channelstrRequired. The RTC channel.
tokenstrThe RTC token for the agent's UID. The SDK doesn't generate it for Platform sessions.
agent_uidstrThe agent's UID in the channel. Omit it, or pass "0", to have the Platform assign one.
remote_uidslist[str]Required. The UID of the user the agent talks to. Pass exactly one.
valuesdictValues for the agent's variables.
labelsdict[str, str]Labels returned in notification events.
idle_timeoutintSeconds without a user before the session ends, 0 to 3600.
max_durationintThe maximum session length in seconds, 1 to 3600.
graceful_stopdictLets the agent finish speaking before it stops: {"enabled": True, "timeout_ms": 10000}. timeout_ms is 0 to 120000.
data_policydictWhether Agora retains the session's conversation data: {"retention": "30_days"} or {"retention": "none"}.
encryptiondictRTC media encryption settings.
audio_scenariostrThe RTC audio scenario, such as "aiserver".
geofencedictRestricts the regions the session connects through: {"area": ..., "exclude_area": ...}.
idempotency_keystrAn Idempotency-Key for the start request. Retry an uncertain start with the same key: if the first attempt started the session, the retry fails with 409 IdempotencyKeyConflict instead of starting another. Use a new key for a new session.

AgentSession

A session handle. On the Platform, the following methods are available:

MethodDescription
start()Starts the session. Returns the session ID.
get_info()Retrieves the session. The result includes status.
update(properties)Updates a running session. Accepts only the RTC token, the conversation messages, and the LLM params. A params object replaces the current one.
stop()Stops the session.

say(), interrupt(), think(), and the history and turns methods raise on Platform sessions.

To read or stop a session by ID without a handle, use client.v3.sessions.get(agent_session_id=...) and client.v3.sessions.stop(agent_session_id=...).

Low-level API

client.v3 has one resource for each part of the Platform REST API. All arguments are keyword-only, and body fields use the REST API names, such as agent_name. Each method returns the parsed response as a dictionary.

To read response headers, such as ETag, call the method through with_raw_response. The result has .data, .headers, .etag, and .status_code.

raw = client.v3.agents.with_raw_response.get(agent_id=agent_id)
etag = raw.etag

Agents

MethodREST API
agents.create(agent_name, ...)Create an agent
agents.list(limit=None, cursor=None, order=None)List agents
agents.get(agent_id)Retrieve an agent
agents.update(agent_id, if_match, ...)Update an agent
agents.delete(agent_id)Delete an agent

Sessions

MethodREST API
sessions.start(agent_id, transport, ...)Start a session
sessions.start_ephemeral(agent, transport, ...)Start an ephemeral session
sessions.list(channel=None, status=None, started_after=None, started_before=None, limit=None, cursor=None)List sessions
sessions.get(agent_session_id)Retrieve a session
sessions.update(agent_session_id, transport=..., agent=...)Update a session
sessions.stop(agent_session_id)Stop a session

Secrets

MethodREST API
secrets.create(name, secrets)Create a secret set
secrets.list(limit=None, cursor=None, order=None)List secret sets
secrets.get(name)Retrieve a secret set
secrets.update(name, secrets, if_match=None)Update a secret set
secrets.replace(name, if_match, secrets)Replace a secret set
secrets.delete(name, if_match)Delete a secret set
secrets.set_key(name, key, value, if_match=None, if_none_match=None)Set a secret key
secrets.delete_key(name, key, if_match=None)Delete a secret key

Phone numbers

MethodREST API
numbers.create(number, sip_trunk, description=..., inbound=...)Create a phone number
numbers.list(limit=None, cursor=None, order=None)List phone numbers
numbers.get(number_id)Retrieve a phone number
numbers.update(number_id, if_match, ...)Update a phone number
numbers.delete(number_id)Delete a phone number

Campaigns

MethodREST API
campaigns.create(name, agent_id, transport, contacts, schedule, ...)Create a campaign
campaigns.list(status=None, limit=None, cursor=None, order=None)List campaigns
campaigns.get(campaign_id)Retrieve a campaign
campaigns.update(campaign_id, if_match, ...)Update a campaign
campaigns.delete(campaign_id)Delete a campaign
campaigns.pause(campaign_id, idempotency_key=None)Pause a campaign
campaigns.resume(campaign_id, idempotency_key=None)Resume a campaign
campaigns.cancel(campaign_id, idempotency_key=None)Cancel a campaign

Pagination

Each list() method returns one page: {"data": {"count", "list"}, "has_more", "next_cursor"}. To continue, pass next_cursor as cursor. Each resource also has iter_pages(...) and iter_all(...), which follow the cursors for you.

for session in client.v3.sessions.iter_all(status="STOPPED", limit=100):
    print(session["agent_session_id"])

sessions.list() returns running sessions by default. To list others, pass status, for example "STOPPED,FAILED".

Conditional writes and retries

Updates to agents, numbers, and campaigns, and deletes and replacements of secret sets, require the resource's current ETag in if_match. Get it from a raw response. If the resource changed since you read it, the request raises a PreconditionFailedError. Call error.latest() to reload the resource. It doesn't retry the write.

The SDK can retry GET requests. It never retries writes. To retry a session start safely, pass the same idempotency_key. Other operations don't support idempotency keys.

Errors

Import the following errors from agora_agent, except ApiError.

ErrorRaised when
ApiErrorThe Platform returns an error. It has status_code, headers, and body, which usually has reason and detail. Import it from agora_agent.core.api_error. For the reasons, see Status codes.
PreconditionFailedErrorA conditional write fails with 412. Subclass of ApiError.
UnsupportedFieldErrorThe builder has settings with no Platform equivalent. fields lists them. Raised before any request.
SecretRefNotSupportedErrorA secret reference is used on the Voice Agent API.
NumberNotFoundErrorassign_number() or unassign_number() can't find the number in the project.