Event Triggers

Read as Markdown

Description #

Add subscriptions to events to receive notifications based on event transitions, such as a number of minutes before or after an event. Subscriptions are defined through the extra parameters passed to the Create or Update event call.

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": "2026-11-13T15:30:00Z",
  "end": "2026-11-13T17:00:00Z",
  "tzid": "America/Chicago",
  "subscriptions": [
    {
      "type": "webhook",
      "uri": "https://example.com/event_trigger/xxxx",
      "transitions": [
        { "before": "event_start", "offset": { "minutes": 5 } }
      ]
    }
  ]
}

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.

subscriptions Required  #

The array of subscriptions being defined.

subscriptions.type Required  #

The String describing what type of subscription is being added. At present, only the value webhook is supported and will call the given URI when triggered.

subscriptions.uri Required  #

The URI which will be POSTed to when the subscription is triggered. This can include query parameters if you want to communicate additional fields back to your application.

To be considered successfully delivered:

  • Your application must respond in the 2xx range of HTTP status codes.
  • Your application must respond within 7 seconds.

subscriptions.transitions Required  #

An array of objects defining the transition you want to be notified of.

subscriptions.transitions.before Optional  #

Describes a subscription where the notification is delivered before a point in time relative to the event.

Supported values are:

  • event_start
  • event_end

Either before or after must be given.

subscriptions.transitions.after Optional  #

Describes a subscription where the notification is delivered after a point in time relative to the event.

Supported values are:

  • event_start
  • event_end

Either before or after must be given.

subscriptions.transitions.offset Required  #

A duration describing how far the notification delivery window is offset from the point defined by the before or after parameter.

For example:

  • { "before": "event_start", "offset": { "hours": 1 } } will trigger 1 hour before the event starts
  • { "after": "event_end", "offset": { "minutes": 0 } } will trigger at the end of the event
  • { "after": "event_start", "offset": { "minutes": 5 } } will trigger 5 minutes after the event starts

Zero offsets are allowed, but must be explicitly stated, as in the above example. Please note that even with zero offsets, there is a difference between a before or after subscription. Given an event starting at 11:00, with a zero offset:

  • A before subscription’s notification would be delivered between 10:59-11:00
  • An after subscription’s notification would be delivered between 11:00-11:01

Read more about delivery windows in When is the notification delivered?.

Example Callback #

The callback will contain the event details, as well as some details of the transition that triggered the notification.

POST /event_trigger/xxxx HTTP/1.1
Host: example.com
Content-Type: application/json; charset=utf-8
Cronofy-Notification-ID: 60c210faf5aa93093b000022
Cronofy-Notification-Attempt: 1

{
    "notification": {
        "type": "event_subscription",
        "transitions": [
            {
                "type": "event_start"
            }
        ]
    },
    "event": {
        "calendar_id": "cal_n23kjnwrw2_jsdfjksn234",
        "event_id": "qTtZdczOccgaPncGJaCiLg",
        "event_uid": "evt_partner_60ba0f2968ed0f6e66e1ab68",
        "summary": "Board meeting",
        "description": "Discuss plans for the next quarter",
        "start": "2026-11-13T15:30:00Z",
        "end": "2026-11-13T17:00:00Z",
        "deleted": false,
        "created": "2026-11-13T11:31:53Z",
        "updated": "2026-11-13T11:31:53Z",
        "event_private": false,
        "participation_status": "accepted",
        "attendees": [],
        "organizer": null,
        "transparency": "opaque",
        "status": "confirmed",
        "categories": [],
        "recurring": false,
        "options": {
            "delete": true,
            "update": true,
            "change_participation_status": false
        }
    }
}

Callback headers #

Cronofy-HMAC-SHA256  #

Can optionally be used to verify that the notification was sent by Cronofy.

This HMAC uses the SHA256 algorithm, keyed with the application's client secret, to generate a Base64 encoded hash of the request body.

When an application has multiple active client secrets, a value is generated for each active secret, separated by commas. For example:

 Cronofy-HMAC-SHA256: {HMAC_FROM_SECRET_1},{HMAC_FROM_SECRET_2}
 

Examples are available in our cronofy/notification-hmac-examples Github repository, and our API libraries include methods to verify this header.

HMACs are generated in the same way for all callback events.

Cronofy-Notification-ID  #

An identifier for the notification instance, persistent across retries. Useful for deduplicating any multiple deliveries, which are possible due to our at least once delivery guarantee.

Cronofy-Notification-Attempt  #

The delivery attempt number for the notification, starting at 1. If our first delivery attempt is unsuccessful, we’ll retry multiple times with an incremented value present in this header.

Callback parameters #

notification  #

Details of the subscription that triggered this notification.

event  #

Details of the event for which the notification has been triggered. The fields present map to those documented for our Read Events API.

FAQs #

Do I need to reschedule subscriptions if events move or change duration? #

No. Cronofy’s sync engine tracks the movement of calendar events, whether via the API, or by the event being moved in the calendar itself by end-users. Your subscriptions are defined relative to event start or end times. Once the subscription is added to the event, its delivery time will be kept up-to-date with the state of the event.

When is the notification delivered? #

Notifications based on the event start/end times naturally lead to spikes in activity at particular times. Calendar events tend to be scheduled at the 15 minute offsets, and particularly at the top of the hour. It’s rare to see a calendar event starting at 11:07, for example. To ensure consistent performance and to smooth the impact upon your application, we deliver notifications within a 1 minute window relative to the target time.

This only applies to the first attempt at delivery - if your application is unreachable, slow to respond, or does not reply with a HTTP 2xx status, the notification will be retried several times but these may fall outside of the 1 minute window.

The 1 minute window is based on the transition time (event start or event end) and the offset you specify.

The window is set to the side of the transition time furthest from the event- before subscriptions will be triggered up to 1 minute before the target time, and after subscriptions will be triggered up to 1 minute after the target time.

For example, given an event occurring from 10:00 to 10:30:

Subscription definitionDelivery window
{ "before": "event_start", "offset": { "hours": 1 } }08:59 β€” 09:00
{ "after": "event_start", "offset": { "minutes": 5 } }10:05 β€” 10:06
{ "before": "event_end", "offset": { "minutes": 0 } }10:29 β€” 10:30
{ "after": "event_end", "offset": { "minutes": 0 } }10:30 β€” 10:31

How many messages will I receive for a single subscription? #

For a given notification, we guarantee at least once delivery to your application unless delivery fails for a prolonged period. While we do everything we can to limit this to a single message, the nature of distributed systems means that a single notification cannot be guaranteed. It is unlikely to be duplicated but you should account for this in your integration. Notification payloads contain a Cronofy-Notification-ID HTTP header, which can be used to deduplicate, if your operation is not idempotent.

If an event moves, a new notification will be scheduled, even if one was already sent for the same event.

What happens if I create an event or move it such that some subscriptions are now in the past? #

It is entirely possible to schedule triggers in the past. For example, we could create an event to start in 1 hour, and add a subscription to be notified 2 hours before the start of the event. In these cases, Cronofy will dispatch this notification immediately so that your workflow is still triggered.

For this reason, your workflow might need to consider the start_time of the event before processing the notification. For example, a reminder email for an interview event would still be useful, but it may be too late for a workflow integration which calls a catering company’s API to order sandwiches.

Overdue notifications can also happen because an event is moved. When event start or end times changed, any notifications for the event will be re-queued for the new times. This means that if an event starting in 2 hours with a trigger for 30 minutes before the start of the event is moved to start in 15 minutes from now, the before trigger will immediately send a notification. This is because the event start has changed and the notification is now “overdue”, so Cronofy will immediately dispatch it.