> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.athenaintel.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.athenaintel.com/_mcp/server.

# List calendar events

GET https://api.athenaintel.com/api/v0/tools/calendar/events

List events on the calendar of the caller's connected account.

Reads the primary Google Calendar of a Gmail account or the default calendar
of an Outlook account. `start`/`end` select the events overlapping that
window; without them, Outlook returns recurring series as single entries, so
supply a window to expand them. `title`, `location` and `attendees` filter the
events that were read.

Reference: https://docs.athenaintel.com/api-reference/tools/calendar/list-events

## Authentication

- `X-API-KEY` header (required) — API Key authentication via header

## Request

### Query parameters

- `title` (string, optional, nullable) — Text filter. On Outlook this matches the event title only (`contains(subject, …)`); on Google Calendar it is Google's free-text event search (`q`), which also matches the description, location and attendee names.
- `start` (string, optional, nullable) — Window start. `start` and `end` select events that overlap the window: an event that begins before `start` but is still running at `start` is included. ISO 8601 with an explicit UTC offset or Z (e.g. `2026-10-01T00:00:00-04:00`); the instant is forwarded in RFC 3339 form. Recurring series are expanded into their instances inside the window. Given only one bound, Google leaves the other side open while Outlook derives it 60 days away.
- `end` (string, optional, nullable) — Window end (see `start`); must be later than `start` when both are given. ISO 8601 with an explicit UTC offset or Z.
- `location` (string, optional, nullable) — Only events whose location contains this text. Applied after up to `limit` events have been read from the provider, so narrow the window with `start`/`end` when looking for a specific event.
- `attendees` (string, optional, nullable) — Only events with at least one of these attendee emails (comma-separated). Applied after up to `limit` events have been read from the provider, so narrow the window with `start`/`end` when looking for a specific event.
- `limit` (integer, optional, default: 50) — Maximum number of events (1-200).
- `catalog_id` (string, optional, nullable) — Connected email account to use, as the catalog asset id returned by the Athena UI or the assets API. Defaults to the caller's default email account. An id that is not one of the caller's own connected accounts in the current workspace is a 404.

## Response

### 200

Successful Response

- `catalog_id` (string, required) — The connected account that was read.
- `count` (integer, required) — Number of events returned.
- `provider` (string, required) — Account provider as Athena reports it: `gmail` or `outlook` for accounts connected through the Integrations page; `google` or `microsoft365` for directly-connected accounts.
- `results` (list of CalendarEventOut, optional) — Matching events in ascending start order.

## Errors

### 400 Bad Request Error

The request cannot be carried out as written (`detail.code` = `EMAIL_REQUEST_REJECTED`): an invalid recipient address, or an account that is read-only in Athena (a Microsoft 365 shared mailbox).

- `any`

### 403 Forbidden Error

The caller has no workspace; the email toolkit is disabled in this environment (`detail.code` = `ENVIRONMENT_FEATURE_DISABLED`); the tool is disabled for the workspace in its Tool Registry (`TOOL_NOT_ENABLED`); or the connected account is denied by its provider (for example a Microsoft 365 or Google Workspace connection that has not been granted write permission) or its connector is not enabled for the workspace (`EMAIL_PROVIDER_ACCESS_DENIED`, `EMAIL_CONNECTOR_NOT_ENABLED`).

- `any`

### 404 Not Found Error

No Gmail or Outlook account is connected (`detail.code` = `EMAIL_ACCOUNT_NOT_CONNECTED`); the requested `catalog_id` is not an account the caller can use (`EMAIL_ACCOUNT_NOT_FOUND`); or the provider has no such message or event (`PROVIDER_RESOURCE_NOT_FOUND`).

- `any`

### 422 Unprocessable Entity Error

Validation Error

- `detail` (list of ValidationError, optional)

### 429 Too Many Requests Error

The connected account is temporarily rate-limited by its provider (`detail.code` = `EMAIL_PROVIDER_RATE_LIMITED`). `Retry-After` is set when the provider communicated a wait; retrying earlier extends the lockout.

- `any`

### 502 Bad Gateway Error

The email provider rejected or failed the request (`detail.code` = `EMAIL_PROVIDER_ERROR`); `detail.message` carries the provider's status and `detail.provider_status` its code.

- `any`

## Types

### CalendarEventOut

One calendar event.

- `id` (string, required) — Provider event id.
- `attendees` (list of CalendarAttendeeOut, optional) — Attendees and their responses.
- `conferencing_url` (string, optional, default: ) — Meet / Teams / other conferencing join link, if any.
- `description` (string, optional, default: ) — Description or body preview.
- `end` (string, optional, default: ) — End time, ISO 8601.
- `html_link` (string, optional, nullable) — Link to the event in Google Calendar. Gmail accounts only.
- `location` (string, optional, default: ) — Location, if set.
- `start` (string, optional, default: ) — Start time, ISO 8601.
- `status` (string, optional, nullable) — Event status. Gmail accounts only.
- `title` (string, optional, default: ) — Event title.
- `web_link` (string, optional, nullable) — Link to the event in Outlook. Outlook accounts only.

### ValidationError

- `loc` (list of ValidationErrorLocItems, required)
- `msg` (string, required)
- `type` (string, required)
- `ctx` (ValidationErrorCtx, optional)
- `input` (any, optional)

### CalendarAttendeeOut

One attendee of a calendar event.

- `email` (string, optional, default: ) — Attendee email address.
- `name` (string, optional, default: ) — Attendee display name, if known.
- `response_status` (string, optional, default: ) — Attendee response, in the provider's vocabulary.

### ValidationErrorLocItems

### ValidationErrorCtx

## Examples

**Response**

```json
{
  "catalog_id": "string",
  "count": 1,
  "provider": "string",
  "results": [
    {
      "id": "string",
      "attendees": [
        {
          "email": "",
          "name": "",
          "response_status": ""
        }
      ],
      "conferencing_url": "",
      "description": "",
      "end": "",
      "html_link": "string",
      "location": "",
      "start": "",
      "status": "string",
      "title": "",
      "web_link": "string"
    }
  ]
}
```

**SDK Code**

```python
import requests

url = "https://api.athenaintel.com/api/v0/tools/calendar/events"

headers = {"X-API-KEY": "<apiKey>"}

response = requests.get(url, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.athenaintel.com/api/v0/tools/calendar/events';
const options = {method: 'GET', headers: {'X-API-KEY': '<apiKey>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.athenaintel.com/api/v0/tools/calendar/events"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("X-API-KEY", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.athenaintel.com/api/v0/tools/calendar/events")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<apiKey>'

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.athenaintel.com/api/v0/tools/calendar/events")
  .header("X-API-KEY", "<apiKey>")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.athenaintel.com/api/v0/tools/calendar/events', [
  'headers' => [
    'X-API-KEY' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.athenaintel.com/api/v0/tools/calendar/events");
var request = new RestRequest(Method.GET);
request.AddHeader("X-API-KEY", "<apiKey>");
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["X-API-KEY": "<apiKey>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.athenaintel.com/api/v0/tools/calendar/events")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```