# Subscription calendars for developers Maintain subscription calendars with the REST API and learn about new subscriptions through webhooks. Source: https://docs.getridian.com/subscription-calendars/developers/ Language: en Reviewed: 2026-11-01 A developer project maintains subscription calendars with its app token at `https://api.getridian.com/v1/public-calendars`. Turn access on under **Developer > API projects**, **Access** tab; **API** at the top of a subscription calendar page shows the status and links there. The switch applies to the whole project: it can then read and change all subscription calendars of the workspace. Events from the API show the source "API" in the console and can still be edited there. ## REST API | Method and path | Scope | Purpose | | --- | --- | --- | | `GET /public-calendars` | `public_calendars:read` | Calendars of the workspace | | `POST /public-calendars` | `public_calendars:write` | Create a calendar; `mode` is `test` (default) or `live` | | `GET`, `PATCH`, `DELETE /public-calendars/{id}` | read or write | Read, change or delete a calendar | | `GET /public-calendars/{id}/events` | `public_calendars:read` | Events, paginated | | `GET`, `PUT`, `DELETE /public-calendars/{id}/events/{external_id}` | read or write | Read, create or replace, delete an event by your own ID | | `POST /public-calendars/{id}/events/batch` | `public_calendars:write` | Many events in one call (`operations`) | | `POST /public-calendars/{id}/syncs` and `…/syncs/{sync_id}/complete` | `public_calendars:write` | Full sync: whatever the sync did not include is deleted | | `PUT`, `DELETE /public-calendars/{id}/images/logo` or `/banner` | `public_calendars:write` | Logo and banner | | `GET /public-calendars/{id}/stats` | `public_calendars:read` | Active and new subscriptions | Address events by your own `external_id`; a `PUT` with the same ID replaces the event instead of creating a second one. Send an `Idempotency-Key` when creating a calendar so a retry returns the same calendar. Errors are Problem Details (RFC 9457) with a `code`. **Full sync:** Start a sync, write all current events with `sync_id` through `events/batch` and finish with `complete`. Events missing from the sync are deleted. If that would delete a large number of events, `complete` asks for `confirm_large_delete: true`. ```sh curl -X PUT https://api.getridian.com/v1/public-calendars/$CALENDAR/events/class-2027-01-12 \ -H "Authorization: Bearer $RIDIAN_APP_TOKEN" \ -H "Content-Type: application/json" \ -d '{"title":"Evening yoga","start":"2027-01-12T18:00:00+01:00","end":"2027-01-12T19:30:00+01:00","timezone":"Europe/Berlin"}' ``` ## Webhooks Under **Developer > Webhooks** you add up to five webhooks per developer project, to a public `https` address. Events: - `subscriber.created`: a new subscription fetched the calendar for the first time. - `calendar.updated`: events or settings changed. Several changes in quick succession arrive as one message with the current state. Every delivery carries `x-ridian-event`, `x-ridian-delivery`, `x-ridian-timestamp` and `x-ridian-signature: v1=` over `.` using the webhook's secret. You only see the secret when you create the webhook. If your server does not answer with 2xx, we retry after 1 minute, 5 minutes, 30 minutes, 2 hours and 12 hours. **Developer > Webhooks** lists all webhooks of the workspace with a delivery log: event, time, HTTP status or error reason and next attempt. We delete deliveries 30 days after delivery or after the last attempt. ## Assistants With the scopes `public_calendars:read` and `public_calendars:write`, MCP clients can read and maintain subscription calendars in conversation as well. There too, only admins and owners can make changes.