Create or Update Event

Required plan: Starter

Description #

Creates or updates an event within a user’s calendar.

URL format #

{data_center_url}/v1/calendars/{calendar_id}/events

Example Request #

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": "2024-07-28T15:30:00Z",
  "end": "2024-07-28T17:00:00Z",
  "location": {
    "description": "Board room"
  }
}

Example Response #

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.

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 and must not have a calendar_readonly or calendar_deleted value that is true.

event_id required  #

The String 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.

summary required  #

The String 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 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 when the locale parameter is set.

tzid optional  #

A String representing a known time zone identifier from the IANA Time Zone Database.

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.

start required  #

The start time can be provided as a simple Time or Date string or an object with two attributes, time and tzid:

{
  "time": "2024-07-28T17:00:00Z",
  "tzid": "Europe/Paris"
}

The time attribute specifies the Time or Date 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 representing a known time zone identifier from the IANA Time Zone Database.

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.

When start is specified as a Time, end must be specified as a Time. Likewise, when start is specified as a Date, end must be specified as a Date.

end required  #

The end time can be provided as a simple Time or Date string or an object with two attributes, time and tzid:

{
  "time": "2024-07-28T17:00:00Z",
  "tzid": "Europe/Paris"
}

The time attribute specifies the Time or Date 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 representing a known time zone identifier from the IANA Time Zone Database.

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.

When start is specified as a Time, end must be specified as a Time. Likewise, when start is specified as a Date, end must be specified as a Date.

Also note that end is exclusive, for Time-based events this makes no noticeable difference, but for Date-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 July 28, 2024.

{
  ...
  "start": "2024-07-28",
  "end": "2024-07-29",
  "tzid": "Europe/Paris",
  ...
}
location.description optional  #

The plain text String of up to 1024 characters describing the event’s location.

location.lat optional BETA  #

The String to use as the latitude of the event’s location.

Must be between -85.05115 and 85.05115.

location.long optional BETA  #

The String to use as the longitude of the event’s location.

Must be between -180 and 180.

url optional  #

A String 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.

transparency optional  #

A String value representing the transparency of the event.

Either:

  • opaque
    the account should appear as busy for the duration of the event
  • transparent
    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-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-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
    the account should appear as busy for the duration of the event
  • transparent
    the account should not appear as busy for the duration of the event

Or an extended value:

  • working_elsewhere
    indicates the user is working away from their normal site
  • tentative
    indicates an event being only tentatively attended
  • out_of_office
    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:

Outlook Show astransparencyextended_transparency
Freetransparenttransparent
Busyopaqueopaque
Working elsewhereopaqueworking_elsewhere
Tentativeopaquetentative
Awayopaqueout_of_office

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 (eg. #49BED8) to use as the preferred color of the event.

Support by provider:

  • Apple sets the COLOR property from RFC 7986 in anticipation of future client support
  • Exchange no support
  • Google support for a limited palette, 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:

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": "2024-07-28T15:30:00Z",
  "end": "2024-07-28T17:00:00Z",
  "location": {
    "description": "Board room"
  },
  "reminders": [
    { "minutes": 30 },
    { "minutes": 1440 },
    { "minutes": 0 }
  ]
}

If you want to build your own reminder-like behavior, you can use Subscriptions to configure webhooks before or after the event.

reminders.minutes required  #

An Integer 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 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

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": "2024-07-28T15:30:00Z",
  "end": "2024-07-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 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.

subscriptions optional ALPHA  #

Object describing one or more Event Triggers. 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.

For a full description on the behavior and valid values, please see the templating documentation.

include_userinfo optional  #

A Boolean specifying whether the response should include an embedded userinfo response.

recurrence optional ALPHA  #

Object describing the recurrence pattern 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.

tags is an array of objects, each Tag has a value. If a Tag 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 ;
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": "2024-07-28T15:30:00Z",
  "end": "2024-07-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 uses start time zone for both 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, 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 under a userinfo parameter.

Error responses #

401 Unauthorized #

The request was refused as the provided authentication credentials were not recognized.

When an OAuth refresh_token is available then it should be used to request a replacement auth_token before the request is retried.

403 Forbidden #

The request was refused as the provided authorization credentials 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 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 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:

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

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