# Create a calendar event

`POST /calendar.event.create`

## Description

Create a calendar event on the host's connected calendar. A Roam meeting link
is automatically attached and email notifications are sent to attendees.

The event is written to the first active, writable calendar associated with the
host. The host must have a connected calendar provider (e.g. Google, Microsoft).

**Recurring events:** Provide `rrule` to create a recurring series. A
`timeZone` is required for recurring events.

**All-day events:** Set `allDay: true`; `start` and `end` are interpreted as
dates and normalized to UTC midnight.

**Access:** Organization and Personal. For Organization tokens, the `host` email
is required and identifies the calendar owner. For Personal tokens, `host`
defaults to the authenticated user; if provided it must match the
authenticated user's email.

**Required scope:** `calendar:write`

---

**OpenAPI Spec:** [chat-v1.json](https://developer.ro.am/chat-v1.json)

## Authentication

```
Authorization: Bearer YOUR_API_KEY
```

## Request Body

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `title` | string | Yes | Event title. |
| `description` | string | No | (Optional) Event description. |
| `start` | string | Yes | Event start time (RFC3339). For all-day events, the date portion is used. |
| `end` | string | Yes | Event end time (RFC3339). For all-day events, the date portion is used. |
| `allDay` | boolean | No | Whether this is an all-day event. Defaults to false. |
| `rrule` | string | No | (Optional) iCalendar RFC 5545 recurrence rule, e.g. `FREQ=WEEKLY;COUNT=10`. When provided, `timeZone` is required.  |
| `timeZone` | string | No | IANA timezone name, e.g. `America/New_York`. Required for recurring events; recommended for all events. Defaults to `UTC` when omitted.  |
| `attendees` | string[] | No | Attendee email addresses. Each entry may be a plain email (`user@example.com`) or an address string (`Name <user@example.com>`).  |
| `host` | string | No | Calendar host email. Required for Organization tokens. For Personal tokens, defaults to the authenticated user and, if provided, must match the authenticated user's email.  |

### Example Request

```json
{
  "title": "Q1 Planning",
  "description": "Plan Q1 roadmap",
  "start": "2026-02-15T14:00:00Z",
  "end": "2026-02-15T15:00:00Z",
  "timeZone": "America/Los_Angeles",
  "attendees": [
    "sam@example.com",
    "Alex Doe <alex@example.com>"
  ],
  "host": "host@example.com"
}
```

## Responses

### 200 - Calendar event created successfully.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `id` | string | Yes | Calendar event ID (provider-specific). |
| `title` | string | Yes |  |
| `description` | string | No |  |
| `start` | string | Yes |  |
| `end` | string | Yes |  |
| `allDay` | boolean | No |  |
| `attendees` | object[] | Yes | Attendees as stored on the calendar event. |
| `meetingLink` | object | No | The Roam meeting link attached to the event. |

**attendees** (array item):

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `name` | string | No |  |
| `email` | string | No |  |
| `status` | string | No | RSVP status, if provided by the calendar provider. |

**meetingLink**:

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `id` | string | No |  |
| `url` | string | No |  |


#### Example Response

```json
{
  "id": "evt_01HX3YABCDEF",
  "title": "Q1 Planning",
  "description": "Plan Q1 roadmap",
  "start": "2026-02-15T14:00:00Z",
  "end": "2026-02-15T15:00:00Z",
  "attendees": [
    {
      "name": "Sam Smith",
      "email": "sam@example.com",
      "status": "needsAction"
    }
  ],
  "meetingLink": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "url": "https://ro.am/r/#/d/abc123xyz/def456uvw"
  }
}
```

### 400 - Bad request. Common causes:
- Missing `title`, `start`, or `end`
- `start` or `end` is not valid RFC3339
- `rrule` provided without `timeZone`
- Invalid `timeZone` (must be an IANA zone name)
- No writable calendar found for the host
- Organization token missing `host` email
- Host email not found in the Roam


### 401 - Presented invalid authentication credentials.

### 403 - Forbidden. Personal tokens may only create events for the authenticated user.


### 405 - An unsupported method was requested.

### 500 - An internal error occurred.

---

*Machine-readable API documentation.*
*Full documentation: https://developer.ro.am/docs/api/calendar-event-create*
