Skip to content

Python SDK Quickstart

Get the Chronary Python SDK installed and talking to the API in under 5 minutes.

Terminal window
pip install chronary

Requires Python 3.9+.

  1. Grab your API key from console.chronary.ai.

  2. Set it as an environment variable:

    Terminal window
    export CHRONARY_API_KEY="chr_sk_your_key_here"
  3. Or pass it directly to the client:

    from chronary import Chronary
    client = Chronary(api_key="chr_sk_your_key_here")
from chronary import Chronary
client = Chronary()
agent = client.agents.create(
name="Sales Agent - Acme Corp",
type="ai",
description="Handles meeting scheduling for the sales team",
)
print(agent.id) # "agt_a1b2c3d4"
calendar = client.agents.calendars.create(
agent.id,
name="Sales Meetings",
timezone="America/New_York",
)
print(calendar.ical_url) # Subscribe to this in Google Calendar!
event = client.events.create(
calendar_id=calendar.id,
title="Strategy sync with Acme Corp",
start_time="2026-04-07T14:00:00Z",
end_time="2026-04-07T14:30:00Z",
description="Quarterly strategy alignment",
)
print(event.id) # "evt_m1n2o3"
availability = client.availability.get(
agent_id=agent.id,
start="2026-04-07T09:00:00Z",
end="2026-04-07T17:00:00Z",
slot_duration="30m",
)
print(f"{len(availability.slots)} available slots found")

Every method has an async equivalent via AsyncChronary:

import asyncio
from chronary import AsyncChronary
async def main():
client = AsyncChronary()
agent = await client.agents.create(
name="Sales Agent - Acme Corp",
type="ai",
)
calendar = await client.agents.calendars.create(
agent.id,
name="Sales Meetings",
timezone="America/New_York",
)
event = await client.events.create(
calendar_id=calendar.id,
title="Strategy sync with Acme Corp",
start_time="2026-04-07T14:00:00Z",
end_time="2026-04-07T14:30:00Z",
)
await client.close()
asyncio.run(main())

Use async with for automatic cleanup:

async with AsyncChronary() as client:
agents = client.agents.list()
async for agent in agents:
print(agent.name)

List methods return auto-paging iterators that handle pagination automatically:

# Iterate through all agents (auto-fetches pages)
for agent in client.agents.list():
print(agent.name)
# Async iteration
async for agent in client.agents.list():
print(agent.name)

For manual control, access the underlying ListResponse:

page = client.agents.list(limit=10)
print(page.data) # list of Agent objects
print(page.total) # total count
print(page.has_more) # whether more pages exist
# Fetch next page manually
next_page = client.agents.list(limit=10, offset=10)

Access calendars, events, and availability scoped to a specific agent:

# Create a calendar for an agent
calendar = client.agents.calendars.create(
"agt_a1b2c3d4",
name="Client Meetings",
timezone="America/New_York",
)
# List an agent's calendars
for cal in client.agents.calendars.list("agt_a1b2c3d4"):
print(cal.name)
# List events across all of an agent's calendars
for event in client.agents.events.list("agt_a1b2c3d4"):
print(f"{event.title}: {event.start_time}")
# Check an agent's availability
availability = client.agents.availability.get(
"agt_a1b2c3d4",
start="2026-04-07T09:00:00Z",
end="2026-04-07T17:00:00Z",
)

Customize the client behavior with constructor options:

import httpx
from chronary import Chronary
client = Chronary(
api_key="chr_sk_...", # API key (or set CHRONARY_API_KEY env var)
base_url="https://api.chronary.ai", # Override for testing/staging
timeout=60.0, # Request timeout in seconds (default: 60)
max_retries=2, # Automatic retries on failure (default: 2)
httpx_client=httpx.Client( # Custom httpx client for proxy/transport
proxy="http://localhost:8080",
),
)

The SDK automatically retries on network errors and 429/5xx responses with exponential backoff. The Retry-After header is respected when present.

The SDK raises typed exceptions you can catch specifically:

from chronary import Chronary, NotFoundError, RateLimitError, AuthenticationError
client = Chronary()
try:
agent = client.agents.get("agt_nonexistent")
except NotFoundError as e:
print(f"Not found: {e.message}")
print(f"Request ID: {e.request_id}")
except RateLimitError as e:
print(f"Rate limited: {e.message}")
except AuthenticationError as e:
print(f"Bad API key: {e.message}")

See the Error Codes page for the full exception hierarchy.