OutEvalAI LogoOutEvalAI

Python SDK

Install, authenticate, and use the outcallerai package to call the OutCallerAI public API from Python services and scripts.

The outcallerai package provides a typed, synchronous Python client for the OutCallerAI public API powered by Pydantic models. Python 3.10 or later is required.

Installation

pip install outcallerai

Package: outcallerai on PyPI

Quick start

import os
from outcallerai import OutCallerAI

with OutCallerAI(os.environ["OUTCALLERAI_API_KEY"]) as client:
    workspace = client.workspace.get_workspace()
    print(workspace.name)

The context manager closes the underlying connection pool. For long-running services, create one client and reuse it.

Configuration

OptionTypeDefaultDescription
api_keystr(required)Workspace API key
base_urlstrhttps://api.outcallerai.comAPI origin
timeoutfloat30.0Request timeout in seconds
max_retriesint2Maximum retry attempts for safe operations
max_retry_elapsedfloat15.0Maximum total time spent retrying
max_backofffloat5.0Maximum delay between retries
max_connectionsint4Connection pool size
allow_insecure_httpboolFalseAllow HTTP for local development
response_hookcallableNoneCallback for response metadata
from outcallerai import OutCallerAI

client = OutCallerAI(
    api_key=os.environ["OUTCALLERAI_API_KEY"],
    base_url="https://api.outcallerai.com",
    timeout=60.0,
    max_retries=3,
    response_hook=lambda meta: print(
        f"{meta.method} {meta.path} -> {meta.status} ({meta.duration:.0f}s)"
    ),
)

Resources

ResourceMethods
workspaceget_workspace, update_workspace
usecaseslist_usecases, get_usecase, create_usecase, update_usecase, delete_usecase
agentslist_agents, get_agent, create_agent, update_agent, delete_agent
leadslist_leads, get_lead, create_lead, update_lead, delete_lead
callslist_calls, get_call, create_call
jobscreate_call_export_job, get_job, cancel_job

Complete usage guide

Workspace

# Get workspace
workspace = client.workspace.get_workspace()
print(workspace.id, workspace.name)

# Update workspace name
updated = client.workspace.update_workspace(
    workspace_update_request={"name": "Acme Corp"}
)

Usecases

# List usecases
usecases = client.usecases.list_usecases()

# Get usecase by ID
usecase = client.usecases.get_usecase(use_case_id="uc_abc123")

# Create usecase
created = client.usecases.create_usecase(
    use_case_write_request={"name": "Q4 Outreach", "description": "Quarterly sales push"}
)

# Update usecase
updated = client.usecases.update_usecase(
    use_case_id="uc_abc123",
    use_case_write_request={"name": "Updated Usecase"}
)

# Delete usecase
client.usecases.delete_usecase(use_case_id="uc_abc123")

Agents

# List agents
agents = client.agents.list_agents()

# Get agent by ID
agent = client.agents.get_agent(agent_id="ag_abc123")

# Create agent
created = client.agents.create_agent(
    agent_create_request={"name": "Sales Agent", "gender": "female"}
)

# Update agent
updated = client.agents.update_agent(
    agent_id="ag_abc123",
    agent_update_request={"name": "Updated Name", "gender": "male"}
)

# Delete agent
client.agents.delete_agent(agent_id="ag_abc123")

Leads

# List leads for an agent
leads = client.leads.list_leads(agent_id="ag_abc123", limit=50)

# Get lead by ID
lead = client.leads.get_lead(agent_id="ag_abc123", lead_id="ld_xyz789")

# Create lead (single or bulk)
from outcallerai.generated.models.lead_create_request import LeadCreateRequest
from outcallerai.generated.models.body import Body
new_leads = client.leads.create_lead(
    agent_id="ag_abc123",
    body=Body(actual_instance=[
        LeadCreateRequest(
            name="Jane Doe",
            email="jane@example.com",
            phone="+911234567890",
            description="Interested in pricing",
        )
    ])
)

# Update lead
updated_lead = client.leads.update_lead(
    agent_id="ag_abc123",
    lead_id="ld_xyz789",
    lead_update_request={"name": "Jane Smith"}
)

# Delete lead
client.leads.delete_lead(agent_id="ag_abc123", lead_id="ld_xyz789")

Calls

# List calls for an agent
calls = client.calls.list_calls(agent_id="ag_abc123", limit=50)

# Get call by ID
call = client.calls.get_call(agent_id="ag_abc123", call_id="cl_xyz789")

# Create call (initiate outbound call to a lead)
from outcallerai.generated.models.call_create_request import CallCreateRequest
new_calls = client.calls.create_call(
    agent_id="ag_abc123",
    call_create_request=CallCreateRequest(lead_id="ld_xyz789")
)
print(new_calls[0].id, new_calls[0].status)

# Bulk call creation (initiate calls to multiple leads at once)
bulk_calls = client.calls.create_call(
    agent_id="ag_abc123",
    call_create_request=CallCreateRequest(lead_ids=["ld_xyz789", "ld_abc456", "ld_def012"])
)
print(f"Created {len(bulk_calls)} calls")
for call in bulk_calls:
    print(call.id, call.status)

Note: create_call accepts either lead_id (single) or lead_ids (bulk list). Provide one of the two — not both. Bulk creation deduplicates the lead_ids list and returns a list of call objects.

Jobs

import uuid

# Create call export job
job = client.jobs.create_call_export_job(
    call_export_job_request={"agent_id": "ag_abc123", "limit": 100},
    idempotency_key=str(uuid.uuid4()),
)

# Get job status
job_status = client.jobs.get_job(job_handle=job.handle)

# Cancel job
client.jobs.cancel_job(job_handle=job.handle)

Pagination

from outcallerai import Page, paginate


def fetch_page(cursor=None):
    response = client.leads.list_leads(
        agent_id="ag_abc123",
        cursor=cursor,
        limit=50,
    )
    return Page(
        items=response.items,
        next_cursor=response.next_cursor,
    )


for lead in paginate(fetch_page, max_pages=1_000):
    print(lead.id, lead.name)

Idempotency

import uuid

from outcallerai.generated.models.lead_create_request import LeadCreateRequest
from outcallerai.generated.models.body import Body

lead = client.leads.create_lead(
    agent_id="ag_abc123",
    body=Body(actual_instance=[
        LeadCreateRequest(
            name="Jane",
            email="jane@example.com",
            phone="+911234567890",
            description="Interested in pricing",
        )
    ]),
    idempotency_key=str(uuid.uuid4()),
)

Error handling

from outcallerai import AuthenticationError, OutCallerAIError, RateLimitError

try:
    client.agents.create_agent(...)
except AuthenticationError:
    # The API key is invalid or has been revoked
    raise
except RateLimitError:
    # Back off - the SDK already retried when safe
    raise
except OutCallerAIError as error:
    print(error.category, error.code, error.request_id)
    raise
Error typeHTTP statusRetryable
AuthenticationError401No
PermissionError403No
NotFoundError404No
RequestValidationError400/422No
ConflictError409No
RateLimitError429Yes
TimeoutError408/0Yes
ServerError5xxYes
NetworkError0Yes

Response metadata

from outcallerai import ResponseMetadata


def observe(meta: ResponseMetadata):
    print(
        meta.method,
        meta.path,
        meta.status,
        meta.request_id,
        meta.rate_limit_remaining,
    )


client = OutCallerAI(
    os.environ["OUTCALLERAI_API_KEY"],
    response_hook=observe,
)

How is this guide?