# Create or Update Event

#### Description
Creates or updates an event within a user's calendar.

#### URL format
```
{data_center_url}/v1/calendars/{calendar_id}/events
```

#### Example Request
```http
POST /v1/calendars/cal_n23kjnwrw2_jsdfjksn234/events HTTP/1.1
Host: {data_center_url}
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json; charset=utf-8

{
  "event_id": "qTtZdczOccgaPncGJaCiLg",
  "summary": "Board meeting",
  "description": "Discuss plans for the next quarter.",
  "start": "2026-04-28T15:30:00Z",
  "end": "2026-04-28T17:00:00Z",
  "location": {
    "description": "Board room"
  }
}
```

#### Example Response
```http
HTTP/1.1 202 Accepted
```

#### Request parameters
##### `data_center_url` *(required)*

The URL for the data center you want to communicate with. Possible choices are:

- `api-au.cronofy.com` - Australia
- `api-ca.cronofy.com` - Canada
- `api-de.cronofy.com` - Germany
- `api-sg.cronofy.com` - Singapore
- `api-uk.cronofy.com` - United Kingdom
- `api.cronofy.com` - United States

Find out more about [Cronofy's data centers](/developers/data-centers/index.md).
##### `calendar_id` *(required)*

The `calendar_id` of the calendar you wish the event to be added to. This ID should have been discovered by making a [list calendars request](/developers/api/calendars/list-calendars/index.md) and **must not** have a `calendar_readonly` or `calendar_deleted` value that is `true`.

##### `event_id` *(required)*

The [`String`](/developers/api/data-types/index.md) that uniquely identifies the event. The first request made for a `calendar_id` and `event_id` combination will create an entry in the calendar and all subsequent requests will update the details of the event.

Usually this will be your own internal ID for the event, encoded as a [`String`](/developers/api/data-types/index.md).

##### `summary` *(required)*

The [`String`](/developers/api/data-types/index.md) of up to 1024 characters to use as the summary, sometimes referred to as the name, of the event.

##### `description` *(optional)*

The plain text [`String`](/developers/api/data-types/index.md) of up to 4096 characters to use as the description, sometimes referred to as the notes, of the event.
Please note that this should not contain HTML, as this is unlikely to be rendered by many Calendar services.
This field can contain [templates](/developers/api-alpha/templating/index.md) when the [locale parameter](#param-locale) is set.

> **WARNING:** We limit the description to 4096 characters for compatibility reasons, but it's possible for longer descriptions to exist on events if they are externally edited. To ensure you're still able to modify such events using the API, if the `description` field is omitted or `null` when Upserting, we'll leave any existing description untouched. To clear a description, set it to an empty string `&quot;&quot;`.

##### `tzid` *(optional)*

A [`String`](/developers/api/data-types/index.md) representing a known time zone identifier from the [IANA Time Zone Database](https://www.iana.org/time-zones).

Common examples are:

- `Etc/UTC`

- `Europe/Paris`

- `America/Chicago`

When provided, specifies the default `tzid` to use for the `start` and `end` times of the event if they do not specify their own.

If not provided, `Etc/UTC` is used by default. It is *strongly* recommended that you provide this parameter as many calendar clients highlight if this differs to the person's current time zone which can lead to confusion.

Most notably, Outlook will make it look like the event is occurring in Reykjavík as Iceland's time zone is UTC.

Please note the [caveats on time zone usage by provider](/developers/api/events/upsert-event/index.md).

##### `start` *(required)*

The `start` time can be provided as a simple [`Time`](/developers/api/data-types/index.md) or [`Date`](/developers/api/data-types/index.md) string or an object with two attributes, `time` and `tzid`:

```json
{
  "time": "2026-04-28T17:00:00Z",
  "tzid": "Europe/Paris"
}
```

The `time` attribute specifies the [`Time`](/developers/api/data-types/index.md) or [`Date`](/developers/api/data-types/index.md) to use as the start of the event. Regardless of the `tzid` used, this value is **always** provided in UTC time so as to not be ambiguous.

The `tzid` attribute specifies a [`String`](/developers/api/data-types/index.md) representing a known time zone identifier from the [IANA Time Zone Database](https://www.iana.org/time-zones).

Common examples are:

- `Etc/UTC`

- `Europe/Paris`

- `America/Chicago`

When provided, specifies the `tzid` to use for the `start` time of the event.

If not provided, the `tzid` attribute of the event is used if specified, otherwise `Etc/UTC` is used.

Please note the [caveats on time zone usage by provider](/developers/api/events/upsert-event/index.md).

When `start` is specified as a [`Time`](/developers/api/data-types/index.md), `end` must be specified as a [`Time`](/developers/api/data-types/index.md). Likewise, when `start` is specified as a [`Date`](/developers/api/data-types/index.md), `end` must be specified as a [`Date`](/developers/api/data-types/index.md).

The minimum date requirement for the `start` parameter is 5 years back from today.

##### `end` *(required)*

The `end` time can be provided as a simple [`Time`](/developers/api/data-types/index.md) or [`Date`](/developers/api/data-types/index.md) string or an object with two attributes, `time` and `tzid`:

```json
{
  "time": "2026-04-28T17:00:00Z",
  "tzid": "Europe/Paris"
}
```

The `time` attribute specifies the [`Time`](/developers/api/data-types/index.md) or [`Date`](/developers/api/data-types/index.md) to use as the end time of the event. Regardless of the `tzid` used, this value is **always** provided in UTC time so as to not be ambiguous. Also, it must be later in time than the `start` of the event.

The `tzid` attribute specifies a [`String`](/developers/api/data-types/index.md) representing a known time zone identifier from the [IANA Time Zone Database](https://www.iana.org/time-zones).

Common examples are:

- `Etc/UTC`

- `Europe/Paris`

- `America/Chicago`

When provided, specifies the `tzid` to use for the `end` time of the event.

If not provided, the `tzid` attribute of the event is used if specified, otherwise `Etc/UTC` is used.

Please note the [caveats on time zone usage by provider](/developers/api/events/upsert-event/index.md).

When `start` is specified as a [`Time`](/developers/api/data-types/index.md), `end` must be specified as a [`Time`](/developers/api/data-types/index.md). Likewise, when `start` is specified as a [`Date`](/developers/api/data-types/index.md), `end` must be specified as a [`Date`](/developers/api/data-types/index.md).

Also note that `end` is **exclusive**, for [`Time`](/developers/api/data-types/index.md)-based events this makes no noticeable difference, but for [`Date`](/developers/api/data-types/index.md)-based events this can be confusing. It may help to think of the `end` as the point in time by which the event will have ended. When based on time the event an event with an end of `11:30` is actually expected to end at `11:29.99999` so it would not overlap a following event starting at `11:30`. When working with dates the same logic applies so an all day event you wish to cover March 17th would start on March 17th but end **before** March 18th.

##### All-day event example
In the following example, the event will appear in the end-user's calendar as an all-day event on April 28, 2026.

```json
{
  ...
  "start": "2026-04-28",
  "end": "2026-04-29",
  "tzid": "Europe/Paris",
  ...
}
```

##### `location.description` *(optional)*

The plain text [`String`](/developers/api/data-types/index.md) of up to 1024 characters describing the event's location.

> **WARNING:** Support for geo-location is limited to Office 365, Outlook.com, Google and Apple. Please note that for Google and Apple geo-location will only be displayed on Apple devices or applications, and Google does not send this information to attendees, only the calendar owner.

##### `location.lat` *(optional)* **BETA**

The [`String`](/developers/api/data-types/index.md) to use as the latitude of the event's location.

Must be between **-85.05115** and **85.05115**.

##### `location.long` *(optional)* **BETA**

The [`String`](/developers/api/data-types/index.md) to use as the longitude of the event's location.

Must be between **-180** and **180**.

##### `url` *(optional)*

A [`String`](/developers/api/data-types/index.md) value which must be parseable as a URI as defined as defined in RFC 1738 and RFC 2111.

Omitting the value will leave the URL unchanged. Setting the value to `null` will remove the URL if supported by the provider.

Support for event URLs is currently limited to Apple and Google. In Google's case, the Calendar UI will not display the URL, but other apps like Apple Calendar on Mac will display it.

##### `transparency` *(optional)*

A [`String`](/developers/api/data-types/index.md) value representing the transparency of the event.

Either:

- `opaque`<br/>the account should appear as busy for the duration of the event

- `transparent`<br/>the account should **not** appear as busy for the duration of the event

If not provided, `transparent` is used for all-day events, and `opaque` for [`Time`](/developers/api/data-types/index.md)-based events.

##### `extended_transparency` *(optional)* **ALPHA**

A `String` allowing additional options on top of the standard `transparency` field.

If not provided, `transparent` is used for all-day events, and `opaque` for [`Time`](/developers/api/data-types/index.md)-based events.

Currently only Microsoft 365 and Exchange calendars can create events with the enhanced values. Other calendar providers will fall back to the equivalent `transparency` value.

This may be one of the standard `transparency` values as above:

- `opaque`<br/>the account should appear as busy for the duration of the event

- `transparent`<br/>the account should **not** appear as busy for the duration of the event

Or an extended value:

- `working_elsewhere`<br/>indicates the user is working away from their normal site

- `tentative`<br/>indicates an event being only tentatively attended

- `out_of_office`<br/>indicates the user is unavailable due to being out of the office, such as being on vacation

These values map to Microsoft Outlook's "Show as" UI and to standard `transparency` as follows:

<table>
  <thead>
      <tr>
          <th>Outlook Show as</th>
          <th>transparency</th>
          <th>extended_transparency</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Free</td>
          <td>transparent</td>
          <td>transparent</td>
      </tr>
      <tr>
          <td>Busy</td>
          <td>opaque</td>
          <td>opaque</td>
      </tr>
      <tr>
          <td>Working elsewhere</td>
          <td>opaque</td>
          <td>working_elsewhere</td>
      </tr>
      <tr>
          <td>Tentative</td>
          <td>opaque</td>
          <td>tentative</td>
      </tr>
      <tr>
          <td>Away</td>
          <td>opaque</td>
          <td>out_of_office</td>
      </tr>
  </tbody>
</table>
It is advised to provide only one of `extended_transparency` or `transparency` fields. If both are provided, they must be consistent with each other per the above table.

##### `color` *(optional)*

A hexadecimal color code [`String`](/developers/api/data-types/index.md) (eg. `#49BED8`) to use as the preferred color of the event.

Support by provider:

- **Apple** sets the <a href="https://www.rfc-editor.org/rfc/rfc7986#section-5.9">`COLOR` property from RFC 7986</a> in anticipation of future client support

- **Exchange** no support

- **Google** supports a limited palette, so the closest match to the provided `color` will be used

- **Office 365** no support

- **Outlook.com** no support

##### `reminders` *(optional)*

You can provide an array of up to 5 reminders for an event. They should be provided in order of priority for your application, **not** time order. This is because the providers support a varying number of reminders and we will set as many as they allow, in the order you provide them.

Number of reminders supported per provider:

- **Apple** 5 reminders, note that icloud.com will only display two

- **Exchange** 1 reminder

- **Google** 5 reminders

- **Office 365** 1 reminder

- **Outlook.com** 1 reminder

For example, if you provide 3 reminders and the provider only supports one, we will use the first one you specify, **not** the earliest or the latest one.

As a concrete example, whilst we advise erring on the side of setting less reminders rather than more, it is easy to imagine that 3 reminders may be useful for an appointment:

- 30 minutes before event start - get to the appointment

- 24 hours before event start - remember about the appointment

- At event start - the appointment should have started

In a request this would look like:

```http
POST /v1/calendars/cal_n23kjnwrw2_jsdfjksn234/events HTTP/1.1
Host: {data_center_url}
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json; charset=utf-8

{
  "event_id": "qTtZdczOccgaPncGJaCiLg",
  "summary": "Board meeting",
  "start": "2026-04-28T15:30:00Z",
  "end": "2026-04-28T17:00:00Z",
  "reminders": [
    { "minutes": 30 },
    { "minutes": 1440 },
    { "minutes": 0 }
  ]
}
```

If you want to build your own reminder-like behavior, you can use [Subscriptions](#param-subscriptions) to configure webhooks before or after the event.

If not provided, reminders will be added based upon the underlying calendar's defaults. If you want to prevent any reminders being set, you must provide an empty array:

```http
POST /v1/calendars/cal_n23kjnwrw2_jsdfjksn234/events HTTP/1.1
Host: {data_center_url}
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json; charset=utf-8

{
  "event_id": "qTtZdczOccgaPncGJaCiLg",
  "summary": "Board meeting",
  "start": "2026-04-28T15:30:00Z",
  "end": "2026-04-28T17:00:00Z",
  "reminders": []
}
```

##### `reminders.minutes` *(required)*

An [`Integer`](/developers/api/data-types/index.md) specifying the number of minutes before the start of the event that the reminder should occur.

Must be between 0 and 40,320, from the time the event starts to 4 weeks before the event starts, inclusive.

##### `reminders_create_only` *(optional)*

A [`Boolean`](/developers/api/data-types/index.md) specifying whether reminders should only be set when creating an event, or for updates as well.

When set to `true`, if the event already exists then its reminders will be left untouched. This allows you to create an event with default reminders but allow the user to alter them as they wish.

##### `attendees` *(optional)*

Attendees to an event can be invited and removed, if the attendees should not be changed then omitting the attribute will leave the attendees unchanged.

An concrete example of this is shown below where one attendee should be invited and another removed

```http
POST /v1/calendars/cal_n23kjnwrw2_jsdfjksn234/events HTTP/1.1
Host: {data_center_url}
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json; charset=utf-8

{
  "event_id": "qTtZdczOccgaPncGJaCiLg",
  "summary": "Board meeting",
  "description": "Discuss plans for the next quarter.",
  "start": "2026-04-28T15:30:00Z",
  "end": "2026-04-28T17:00:00Z",
  "location": {
    "description": "Board room"
  },
  "attendees": {
    "invite": [
      {
        "email": "invite@example.com",
        "display_name": "Example Invite"
      }
    ],
    "remove": [
      {
        "email": "remove@example.com",
        "display_name": "Example remove"
      }
    ]
  }
}
```

##### `attendees.invite` *(optional)*

An array of attendees to invite to the event.

##### `attendees.invite.email` *(required)*

The email address associated with the attendee as a `String`.

##### `attendees.invite.display_name` *(optional)*

A human-friendly name associated with the attendee as a `String`, may be `null`.

##### `attendees.remove` *(optional)*

An array of attendees to remove from the event.

##### `attendees.remove.email` *(required)*

The email address associated with the attendee as a `String`.

##### `attendees.remove.display_name` *(optional)*

A human-friendly name associated with the attendee as a `String`, may be `null`.

Please note, if too many invites are sent by Outlook.com users in a short period of time anti-spam measures may lock their account. They will then need to fully authenticate their account to remove the lock.

##### `event_private` *(optional)*

The [`Boolean`](/developers/api/data-types/index.md) value to determine if this event should be created as private or not.

The default value of this is `false`.

##### `conferencing` *(optional)*

Object describing the desired conferencing details. For more information on this feature, see [Conferencing Services documentation](/developers/api/conferencing-services/create/index.md).

##### `subscriptions` *(optional)* **ALPHA**

Object describing one or more [Event Triggers](/developers/api/event-triggers/index.md). These define webhooks to fire relative to the start or end of the event.

##### `locale` *(optional)* **ALPHA**

A key describing the locale to be used for fallback values in [templates](/developers/api-alpha/templating/index.md).

For a full description on the behavior and valid values, please see the [templating documentation](/developers/api-alpha/templating/index.md).

##### `include_userinfo` *(optional)*

A [`Boolean`](/developers/api/data-types/index.md) specifying whether the response should include an embedded [userinfo response](/developers/api/identity/userinfo/index.md).

##### `recurrence` *(optional)* **ALPHA**

Object describing the [recurrence pattern](/developers/api-alpha/recurring-events/index.md) for the event.

##### `tags` *(optional)*

Object describing one or more contextual tags to associate with the event.
The context of "private", as seen in the example below, is the only context currently supported.

Tags are used for the purposes of providing [availability constraints](/developers/api/scheduling/availability/index.md).

`tags` is an array of objects, each [`Tag`](/developers/api/data-types/index.md) has a `value`.
If a [`Tag`](/developers/api/data-types/index.md) matching the provided `value` does not already exist, it will be created.

Tags have the following restrictions:

- no more than 32 tags

- tag value character limit is 64

- restricted characters currently include `;`

```http
POST /v1/calendars/cal_n23kjnwrw2_jsdfjksn234/events HTTP/1.1
Host: {data_center_url}
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json; charset=utf-8

{
  "event_id": "qTtZdczOccgaPncGJaCiLg",
  "summary": "Board meeting",
  "start": "2026-04-28T15:30:00Z",
  "end": "2026-04-28T17:00:00Z",
  "tags": {
    "private": [
      { "value": "Internal planning" },
      { "value": "Marketing" }
    ]
  }
}
```

#### Caveats
##### `Time Zone Information`

Time zone information can be provided with your events so we can insert events with localized times into your users calendars when the underlying provider allows.

Current time zone support by provider:

- **Apple** separate time zones for start and end

- **Exchange** uses start time zone for both start and end

- **Google** separate time zones for start and end

- **Office 365** uses start time zone for both start and end

- **Outlook.com** uses start time zone for both start and end

Please note that even when we can push a separate time zone for start and end, some clients (for example OSX Calendar.app) will display them as if they are both for the start time zone.

Our API supports all of time zone identifiers specified in the [IANA database](https://www.iana.org/time-zones), which is periodically updated. When calendar providers support differs, we attempt to fall back to an appropriate time zone, or `Etc/UTC`.

#### Response parameters
This request has no response body unless `include_userinfo` was specified, in which case it will include an embedded [userinfo response](/developers/api/identity/userinfo/index.md) under a `userinfo` parameter.

#### Error responses
##### 401 Unauthorized

The request was refused as the provided [authentication credentials](/developers/api/authentication/index.md) were not recognized.

When an OAuth `refresh_token` is available then it should be used to [request a replacement `auth_token`](/developers/api/authorization/refresh-token/index.md) before the request is retried.

##### 403 Forbidden

The request was refused as the provided [authorization credentials](/developers/api/authorization/index.md) were recognized but does not grant the `create_event` scope which was required for the request.

You will need to make an additional [authorization request](/developers/api/authorization/request-authorization/index.md) including the `create_event` scope before retrying the request.

##### 404 Not Found

The `calendar_id` provided was not recognized, or the authorization used to make the request has not been granted access to the calendar.

If the calendar does exist, you will need to make an additional [authorization request](/developers/api/authorization/request-authorization/index.md) including the `create_event` scope, asking the user to authorize access to the calendar, before retrying the request.

##### 422 Unprocessable

The request was unable to be processed due to it containing invalid parameters.

The response will contain a JSON object containing one or more errors relating to the invalid parameters.

For example, if you omitted the required `tzid` parameter, you would receive a response like:

```json
{
  "errors": {
    "tzid": [
      {
        "key": "errors.required",
        "description": "required"
      }
    ]
  }
}
```

The `key` field is intended for programmatic use and the `description` field is a human-readable equivalent.



---
[Read in HTML](/developers/api/events/upsert-event/)