# Application Calendars

Not every scheduling use case is based on access to people's calendars. As we've worked with customers across a range of industries we've discovered a number of situations where these customers want to leverage the power of Cronofy's scheduling API without linking it to a "real" calendar.

Examples we've seen include:

- Interview scheduling for retail store managers

- Booking meetings at expos

- Scheduling in-store consultations

- Tracking assignment of workshop equipment

These, and many other use cases are why we've built Application Calendars.

Application Calendars are really a specialized type of Cronofy `Account` that automatically gets created with one `Profile` and one `Calendar`.

```json
{
  "token_type": "bearer",
  "access_token": {RANDOM_TOKEN},
  "expires_in": 3600,
  "refresh_token": {RANDOM_TOKEN},
  "scope": "read_write",
  "application_calendar_id": "my-unique-string",
  "sub": "apc_64b17fbb8090ea21640c9152",
  "linking_profile": {
    "provider_name": "cronofy",
    "profile_id": "pro_n23kjnwrw2",
    "profile_name": "n23kjnwrw2"
  }
}
```

You'll see that it has an `access_token` and `refresh_token` to allow interaction with the Application Calendar through any API endpoints that are authorized with User credentials.

The `sub` value allows you to use this calendar in `Availability` queries.

## Creating an Application Calendar
As is common with the Cronofy API, you specify the `application_calendar_id` so it operates as an upsert operation. You can lazily create the calendar as you need it.



```bash
curl -v --header "Content-Type: application/json" \
    --data "{\"client_id\": \"{CLIENT_ID}\",\"client_secret\": \"{CLIENT_SECRET}}\",\"application_calendar_id\": \"{APPLICATION_CALENDAR_ID}}\"}" \
    https://api.cronofy.com/v1/application_calendars
```


```ruby
cronofy = Cronofy::Client.new(client_id: '{CLIENT_ID}', client_secret: '{CLIENT_SECRET}')

application_calendar = cronofy.application_calendar("{APPLICATION_CALENDAR_ID}")
sub = application_calendar.sub;
```


```csharp
var cronofy = new CronofyOAuthClient("{CLIENT_ID}", "{CLIENT_SECRET}");

var applicationCalendar = cronofy.ApplicationCalendar("{APPLICATION_CALENDAR_ID}");
var sub = applicationCalendar.Sub;
```


```javascript
var cronofy = new Cronofy({
  client_id: '{CLIENT_ID}',
  client_secret: '{CLIENT_SECRET}'
});

var options = {
  application_calendar_id: "{APPLICATION_CALENDAR_ID}"
};

cronofy.applicationCalendar(options)
    .then(function (applicationCalendar) {
        var sub = applicationCalendar.sub;
    });
```


```php
$cronofy = new Cronofy(array("client_id" => "{CLIENT_ID}", "client_secret" => "{CLIENT_SECRET}"));

$application_calendar = $cronofy->application_calendar("{APPLICATION_CALENDAR_ID}");
$sub = $application_calendar['sub'];
```



```python
cronofy = pycronofy.Client(client_id='{CLIENT_ID}', client_secret='{CLIENT_SECRET}')

application_calendar = cronofy.application_calendar('{APPLICATION_CALENDAR_ID}')
sub = application_calendar['sub']
```



See [Application Calendar docs](/developers/api/calendars/application-calendars/index.md) for more info.

## Adding Events to Application Calendars
The data hierarchy for Application Calendars is the same as for User accounts.

```
Application Calendar > Profiles > Calendars```
In order to create an Event in an Application Calendar you need to obtain the `calendar_id` for the Calendar. Application Calendars only have one Profile and one Calendar.

The [List Calendars endpoint](/developers/api/calendars/list-calendars/index.md) allows you to get access to this.

`ACCESS_TOKEN` is the access_token value for the Application Calendar you've created.



```bash
curl -v --header "Authorization: Bearer {ACCESS_TOKEN}" \
    https://api.cronofy.com/v1/calendars
```


```ruby
cronofy = Cronofy::Client.new(access_token: '{ACCESS_TOKEN}')

calendars = cronofy.list_calendars
calendar_id = calendars.first.calendar_id
```


```csharp
var cronofy = new CronofyAccountClient("{ACCESS_TOKEN}");

var calendars = cronofy.GetCalendars();
var calendar_id = calendars.First().CalendarId;
```


```javascript
var cronofy = new Cronofy({
  access_token: '{ACCESS_TOKEN}'
});

cronofy.listCalendars()
    .then(function (response) {
        var calendar_id = response.calendars[0].calendar_id;
    });
```


```php
$cronofy = new Cronofy('', '', '{ACCESS_TOKEN}', '');

$calendars = $cronofy->list_calendars();
$calendar_id = reset($calendars)[0]['calendar_id'];
```


```python
cronofy = pycronofy.Client(access_token="{ACCESS_TOKEN}")

calendars = cronofy.list_calendars()
calendar_id = calendars[0]['calendar_id']
```



This will give you a response similar to this.

```json
{
  "calendars": [
    {
      "provider_name": "cronofy",
      "profile_id": "pro_n23kjnwrw2",
      "profile_name": "n23kjnwrw2",
      "calendar_id": "cal_n23kjnwrw2_jsdfjksn000",
      "calendar_readonly": false,
      "calendar_deleted": false
    }
  ]
}
```

You can then create an Event by using the `ACCESS_TOKEN` value for the Application Calendar and the `calendar_id` for the Calendar.



```bash
curl -v --header "Authorization: Bearer {ACCESS_TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{\"event_id\": \"qTtZdczOccgaPncGJaCiLg\",\"summary\": \"Board meeting\",\"description\": \"Discuss plans for the next quarter.\",\"start\": \"2026-04-23T15:30:00Z\",\"end\": \"2026-04-23T17:00:00Z\",\"location\": {\"description\": \"Board room\"}}" \
    https://api.cronofy.com/v1/calendars/{CALENDAR_ID}/events
```


```ruby
cronofy = Cronofy::Client.new(access_token: '{ACCESS_TOKEN}')
new_event = {
  event_id: "qTtZdczOccgaPncGJaCiLg",
  summary: "Board meeting",
  description: "Discuss plans for the next quarter.",
  start: Time.parse("2026-04-23T15:30:00Z"),
  end: Time.parse("2026-04-23T17:00:00Z"),
  location: {
    description: "Board room"
  }
}

cronofy.upsert_event(calendar_id, new_event)
```


```csharp
var cronofy = new CronofyAccountClient("{ACCESS_TOKEN}");
var eventBuilder = new UpsertEventRequestBuilder()
                        .EventId("uniq-id")
                        .Summary("Event summary")
                        .Description("Event description")
                        .Start(2026, 4, 23, 17, 00)
                        .End(2026, 4, 23, 17, 30)
                        .Location("Meeting room");

cronofy.UpsertEvent(calendarId, eventBuilder);
```


```javascript
var options = {
    access_token: '{ACCESS_TOKEN}',
    event_id: "qTtZdczOccgaPncGJaCiLg",
    summary: "Board meeting",
    description: "Discuss plans for the next quarter.",
    start: "2026-04-23T15:30:00Z",
    end: "2026-04-23T17:00:00Z",
    location: {
        description: "Board room"
    }
};

cronofy.createEvent(options)
    .then(function () {
        // Success
    });
```


```php
$cronofy = new Cronofy('', '', '{ACCESS_TOKEN}', '');

$params = array(
    'calendar_id' => $calendarId,
    'event_id' => 'qTtZdczOccgaPncGJaCiLg',
    'summary' => 'Board meeting',
    'description' => 'Discuss plans for the next quarter.',
    'start' => '2026-04-23T15:30:00Z',
    'end' => '2026-04-23T17:00:00Z'
);

$cronofy->upsert_event($params);
```


```python
import pycronofy

cronofy = pycronofy.Client(access_token="{ACCESS_TOKEN}")
event = {
    'event_id': "qTtZdczOccgaPncGJaCiLg",
    'summary': "Board meeting",
    'description': "Discuss plans for the next quarter.",
    'start': "2026-04-23T15:30:00Z",
    'end': "2026-04-23T17:00:00Z",
    'location': {
        'description': "Board room"
    }
}
cronofy.upsert_event(calendar_id=calendar_id, event=event)
```



Also see docs for the [Upsert Events endpoint](/developers/api/events/upsert-event/index.md)

## Using Application Calendars with scheduling functions
As Application Calendars are a specialized version of a standard Cronofy Account, they can be used in exactly the same way as Cronofy Accounts in Availability queries.

You can treat them as `members` in Availability queries alongside User and Resource accounts.

```json
{
  "participants": [
    {
      "members": [
        { "sub": "apc_64b17fbb8090ea21640c9152" },
        { "sub": "acc_5ba21743f408617d1269ea1e" }
      ],
      "required": "all"
    }
  ],
  "required_duration": { "minutes": 60 },
  "available_periods": [
    {
      "start": "2026-04-23T09:00:00Z",
      "end": "2026-04-23T18:00:00Z"
    },
    {
      "start": "2026-04-24T09:00:00Z",
      "end": "2026-04-24T18:00:00Z"
    }
  ]
}
```

You can assign [Availability Rules](/developers/api/scheduling/availability-rules/index.md) and [Available Periods](/developers/api/scheduling/available-periods/index.md) using the `access_token` for the Application Calendar.

You can use the Availability Query to drive [Real-Time Schedulng links](/developers/scheduling/real-time-scheduling/index.md).

## UI Elements
They are also fully supported by UI Elements. You generate an `element_token` in exactly the same way. Passing the `sub` value for the Application Calendar.

```http
POST /v1/element_tokens HTTP/1.1

Authorization: Bearer {API_KEY}
Content-Type: application/json

{
  "version": "1",
  "permissions": ["agenda"],
  "subs": ["apc_64b17fbb8090ea21640c9152"],
  "origin": "http://localhost"
}
```

## Revoking Application Calendars
Application Calendars can be revoked by calling to the [Revoking Authorization](/developers/api/authorization/revoke/index.md) endpoint and passing the Application Calendar's `access_token` or the `sub` value.

## Summary
Application Calendars allow you to leverage all of the power of Cronofy's rich scheduling features and UI elements without needing a "real" calendar to act as the data store.

They are designed to be used as drop in replacements for, or to work alongside User and Resource Accounts. Greatly extending the scheduling use cases you can support.

To understand how Application Calendars work in relation to Accounts and Billing please review the [Application Calendar FAQ](/developers/faqs/application-calendars/index.md).

For any questions or to let us know what you're building with Application Calendars, just email [support@cronofy.com](mailto:support@cronofy.com).


---
[Read in HTML](/developers/calendars-events/application-calendars/)
