Availability
The availability engine finds open time slots by examining events across one or more calendars. It supports single-agent, single-calendar, and cross-agent queries.
Three availability endpoints
Section titled “Three availability endpoints”| Endpoint | Scope | Use case |
|---|---|---|
GET /v1/agents/:id/availability | All calendars for one agent | ”When is this agent free?” |
GET /v1/calendars/:id/availability | Single calendar | ”When is this calendar free?” |
GET /v1/availability | Multiple agents | ”When are all these agents free?” |
Single-agent availability
Section titled “Single-agent availability”Returns available time slots across all of an agent’s calendars:
curl "https://api.chronary.ai/v1/agents/agt_a1b2c3d4/availability?start=2026-04-07T09:00:00Z&end=2026-04-07T17:00:00Z&slot_duration=30m" \ -H "Authorization: Bearer chr_sk_test_your_key_here"const params = new URLSearchParams({ start: '2026-04-07T09:00:00Z', end: '2026-04-07T17:00:00Z', slot_duration: '30m',});const response = await fetch( `https://api.chronary.ai/v1/agents/${agentId}/availability?${params}`, { headers: { 'Authorization': 'Bearer chr_sk_test_your_key_here' } });const { slots } = await response.json();response = requests.get( f'https://api.chronary.ai/v1/agents/{agent_id}/availability', headers={'Authorization': 'Bearer chr_sk_test_your_key_here'}, params={ 'start': '2026-04-07T09:00:00Z', 'end': '2026-04-07T17:00:00Z', 'slot_duration': '30m', },)data = response.json()print(f"{len(data['slots'])} available slots")Response:
{ "slots": [ { "start": "2026-04-07T09:00:00Z", "end": "2026-04-07T09:30:00Z" }, { "start": "2026-04-07T09:30:00Z", "end": "2026-04-07T10:00:00Z" }, { "start": "2026-04-07T10:00:00Z", "end": "2026-04-07T10:30:00Z" }, { "start": "2026-04-07T15:00:00Z", "end": "2026-04-07T15:30:00Z" } ]}Query parameters
Section titled “Query parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
start | datetime | Yes | Start of the time range (ISO 8601) |
end | datetime | Yes | End of the time range (must be after start) |
slot_duration | string | No | 15m, 30m (default), 45m, 1h, or 2h |
include_busy | boolean | No | Include busy slots in response (default false) |
Single-calendar availability
Section titled “Single-calendar availability”Same parameters, scoped to one calendar:
curl "https://api.chronary.ai/v1/calendars/cal_x1y2z3/availability?start=2026-04-07T09:00:00Z&end=2026-04-07T17:00:00Z&slot_duration=1h" \ -H "Authorization: Bearer chr_sk_test_your_key_here"Cross-agent availability
Section titled “Cross-agent availability”Find time slots where multiple agents are all free:
curl "https://api.chronary.ai/v1/availability?agents=agt_a1b2c3d4,agt_e5f6g7h8&start=2026-04-07T09:00:00Z&end=2026-04-07T17:00:00Z&slot_duration=30m" \ -H "Authorization: Bearer chr_sk_test_your_key_here"const params = new URLSearchParams({ agents: 'agt_a1b2c3d4,agt_e5f6g7h8', start: '2026-04-07T09:00:00Z', end: '2026-04-07T17:00:00Z', slot_duration: '30m',});const response = await fetch( `https://api.chronary.ai/v1/availability?${params}`, { headers: { 'Authorization': 'Bearer chr_sk_test_your_key_here' } });const { slots } = await response.json();response = requests.get( 'https://api.chronary.ai/v1/availability', headers={'Authorization': 'Bearer chr_sk_test_your_key_here'}, params={ 'agents': 'agt_a1b2c3d4,agt_e5f6g7h8', 'start': '2026-04-07T09:00:00Z', 'end': '2026-04-07T17:00:00Z', 'slot_duration': '30m', },)data = response.json()Additional parameters for cross-agent queries
Section titled “Additional parameters for cross-agent queries”| Parameter | Type | Description |
|---|---|---|
agents | string | Required. Comma-separated agent IDs |
calendars | string | Optional. Comma-separated calendar IDs to narrow scope |
Plan limits
Section titled “Plan limits”Cross-agent availability has plan-based limits:
| Plan | Max agents per query | Max date range |
|---|---|---|
| Free | 5 | 30 days |
| Pro | 20 | 90 days |
| Scale | 50 | 365 days |
Exceeding these limits returns 400 Bad Request.
How availability is calculated
Section titled “How availability is calculated”- The engine collects all events from the relevant calendars in the requested time range
- Events with status
confirmedortentativeblock time slots - Events with status
cancelleddo not block time - Events imported via iCal subscriptions are also included
- The time range is divided into slots of the requested duration
- Slots that overlap with any blocking event are excluded (or marked busy if
include_busy=true)