Availability Query
Required plan: EmergingDescription #
Inspects calendars to determine the common availability for people within the specified periods of time.
URL format #
{data_center_url}/v1/availability
Example Request #
POST /v1/availability HTTP/1.1
Host: {data_center_url}
Authorization: Bearer {API_KEY}
Content-Type: application/json; charset=utf-8
{
"participants": [
{
"members": [
{
"sub": "acc_5ba21743f408617d1269ea1e",
"managed_availability": true
},
{
"sub": "acc_64b17d868090ea21640c914c",
"managed_availability": true
}
],
"required": "all"
},
{
"members": [
{ "sub": "res_5ba21743f408617d12693521" },
{ "sub": "res_5ba21743f4000563a26934ea" },
{ "sub": "res_64b17d868090ea21640ad6e0" }
],
"required": 1
}
],
"required_duration": { "minutes": 60 },
"query_periods": [
{
"start": "2024-11-22T09:00:00Z",
"end": "2024-11-22T18:00:00Z"
},
{
"start": "2024-11-23T09:00:00Z",
"end": "2024-11-23T18:00:00Z"
}
],
"buffer": {
"before": { "minutes": 30 },
"after": { "minutes": 15 }
},
"response_format": "slots"
}
Example Response #
Slots #
When a response_format
of slots
or overlapping_slots
is specified, the response looks like this.
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"available_slots": [
{
"start": "2024-11-22T09:00:00Z",
"end": "2024-11-22T10:00:00Z",
"participants": [
{ "sub": "acc_5ba21743f408617d1269ea1e" },
{ "sub": "acc_64b17d868090ea21640c914c" },
{ "sub": "res_5ba21743f408617d12693521" },
{ "sub": "res_5ba21743f4000563a26934ea" }
]
},
{
"start": "2024-11-23T10:00:00Z",
"end": "2024-11-23T11:00:00Z",
"participants": [
{ "sub": "acc_5ba21743f408617d1269ea1e" },
{ "sub": "acc_64b17d868090ea21640c914c" },
{ "sub": "res_64b17d868090ea21640ad6e0" }
]
},
{
"start": "2024-11-23T11:00:00Z",
"end": "2024-11-23T12:00:00Z",
"participants": [
{ "sub": "acc_5ba21743f408617d1269ea1e" },
{ "sub": "acc_64b17d868090ea21640c914c" },
{ "sub": "res_64b17d868090ea21640ad6e0" }
]
}
]
}
Periods #
The default response_format
of periods
looks like this.
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"available_periods": [
{
"start": "2024-11-22T09:00:00Z",
"end": "2024-11-22T11:00:00Z",
"participants": [
{ "sub": "acc_5ba21743f408617d1269ea1e" },
{ "sub": "acc_64b17d868090ea21640c914c" },
{ "sub": "res_5ba21743f4000563a26934ea" }
]
},
{
"start": "2024-11-23T11:00:00Z",
"end": "2024-11-23T17:00:00Z",
"participants": [
{ "sub": "acc_5ba21743f408617d1269ea1e" },
{ "sub": "acc_64b17d868090ea21640c914c" },
{ "sub": "res_64b17d868090ea21640ad6e0" }
]
}
]
}
Request parameters #
data_center_url required
The URL for the data center you want to communicate with. Possible choices are:
api-au.cronofy.com
- π¦πΊ Australiaapi-ca.cronofy.com
- π¨π¦ Canadaapi-de.cronofy.com
- π©πͺ Germanyapi-sg.cronofy.com
- πΈπ¬ Singaporeapi-uk.cronofy.com
- π¬π§ United Kingdomapi.cronofy.com
- πΊπΈ United States
Find out more about Cronofy's data centers.
API_KEY required #
The client_secret
of the client.
response_format optional #
This can be one of the following values:
periods
slots
overlapping_slots
When not specified, and providing query_periods
, the default response format is periods
. In this case, response_format
works in conjunction with start_interval
to control the distribution of the periods/slots.
periods
will generate contiguous available periods that are a minimum length of the required_duration
.
slots
will generate non-overlapping slots with length equal to the required_duration
.
overlapping_slots
will generate slots starting every start_interval
irrespective of whether they overlap with length equal to the required_duration
.
When using query_slots
instead of query_periods
, we’ll always consider all provided slots, effectively behaving like overlapping_slots
. periods
is an invalid value in this case.
query_periods example
POST /v1/availability HTTP/1.1
Host: {data_center_url}
Authorization: Bearer {API_KEY}
Content-Type: application/json; charset=utf-8
{
...
"response_format": "overlapping_slots",
"required_duration": { "minutes": 60 },
"query_periods": [
{
"start": "2024-11-22T09:00:00Z",
"end": "2024-11-22T18:00:00Z"
}
],
"start_interval": { "minutes": 30 }
}
This query will consider 1-hour slot times starting every 30 minutes, with the first slot being at 9AM UTC, then 9:30AM UTC, and so on - with the last slot being at 5PM UTC. Any of those slots would be returned, if available.
query_slots example
POST /v1/availability HTTP/1.1
Host: {data_center_url}
Authorization: Bearer {API_KEY}
Content-Type: application/json; charset=utf-8
{
...
"required_duration": { "minutes": 60 },
"query_slots": [
{ "start": "2024-11-22T09:00:00Z" },
{ "start": "2024-11-22T10:00:00Z" },
{ "start": "2024-11-22T13:30:00Z" },
{ "start": "2024-11-22T14:30:00Z" }
]
}
This will return, at most, four 1-hour slots starting at the specified times, avoiding the need to use a complex combination of query_periods
and start_interval
, or post-processing of the response, to achieve the same result. No other slot times would be considered or returned.
participants required #
An array of the groups of participants whose availability should be taken into account.
At least one group must be specified, a maximum of 10 accounts may be specified over a combination of groups.
participants.members required #
An array of participants that should have their availability taken into account as part of this group.
At least one participant must be specified and you must have been granted the read_free_busy
scope for each participant involved in the availability request.
Note that the read_events
scope implicitly includes this scope as it allows access to a higher level of information than free-busy so you do not have to have both.
participants.members.sub required #
The internal Cronofy ID for the account, as an ASCII-only String
.
This can be retrieved by calling the UserInfo endpoint with a valid access_token
participants.members.available_periods optional #
An array of 1 to 50 available periods within which the member is available. If omitted it is assumed the member is available whenever they do not have a “busy” event in their calendar.
participants.members.available_periods.start #
Thestart
of an available period as a Time
.
It must represent a future point in time.
participants.members.available_periods.end #
Theend
of an available period as a Time
.
Must be at least 1 minute after the corresponding start
and within 35 days of the earliest start
.
participants.members.calendar_ids optional #
Restricts the events contributing towards the members availability to those within the set of specified calendar_id
s.
Calendars are chosen for each member in this order of precedence:
- if this property is present, then only the calendars specified are used. If an empty array is specified then no calendars are chosen and all events in the participants calendars are ignored.
- else, if
managed_availability
istrue
for the member, the calendars from the relevant Availability Rule(s) are used - else, all calendars for the member are considered
participants.members.buffer optional #
Buffer values specific to this member. If specified are used instead of any top-level buffer
when considering the member’s availability.
participants.members.buffer.before optional #
A Duration
specifying the minimum number of minutes that must be free for this member before an available period starts.
participants.members.buffer.after optional #
A Duration
specifying the minimum number of minutes that must be free for this member after the available period ends.
participants.members.availability_constraints optional #
An Array
of constraints that must be satisfied for each slot or period.
participants.members.availability_constraints.period required #
A String
value specifying the time period over which the constraint is to be applied.
You can specify one of the following values:
day
will apply the constraint each day. You must also pass thetzid
parameter to indicate which timezone you want to use to determine when a day starts and ends.week
will apply the constraint over the period of a week. A week is considered to be Monday to Sunday in the UTC time zone, following the ISO standard.
participants.members.availability_constraints.tzid optional #
A String
value specifying the time zone to use when the period
is set to day
. Must be a known time zone identifier from the IANA Time Zone Database. See the time zones page for more information.
Currently specifying a time zone is only supported with the day
constraint period.
participants.members.availability_constraints.limit required #
An Integer
value specifying the maximum number of events allowable per period. If tags
are provided then limit will only consider events with all of the given tags.
participants.members.availability_constraints.tags optional #
An Object
describing zero or more contextual Tag
values to search for against each event when searching for availability. If more than one tag is provided the events must have all of the specified tags to be considered.
Tags may be treated as an empty set by omitting the tags
field, setting it to null
, the empty object {}
, or leaving the context as an empty array { "private": [] }
.
The context of “private”, as seen in the example below, is the only context currently supported.
POST /v1/availability HTTP/1.1
Host: {data_center_url}
Authorization: Bearer {API_KEY}
Content-Type: application/json; charset=utf-8
{
"participants":[{
"members":[
{
"sub": "acc_5ba21743f408617d1269ea1e",
"availability_constraints":[{
"tags": {
"private": [
{ "value": "Interview" }
]
},
"limit": 3,
"period": "week"
}]
},
],
"required": 1
}],
"required_duration": { "minutes": 30 },
"query_periods": [
{
"start": "2024-11-22T09:00:00Z",
"end": "2024-11-22T18:00:00Z"
},
{
"start": "2024-11-23T09:00:00Z",
"end": "2024-11-23T18:00:00Z"
}
]
}
Tags on events are managed via the create or update event endpoint.
participants.members.managed_availability optional #
A Boolean
specifying whether managed availability should be taken into account for this member.
participants.members.only_managed_events optional #
A Boolean
specifying whether to to only consider events that you are managing when determining busy times for this member. Defaults to false
.
participants.members.ignore_tentative optional #
A Boolean
specifying whether events where the user is marked as tentatively attending will be considered as free periods or not. By default these events are considered as busy periods.
participants.members.availability_rule_ids optional #
An Array
of availability_rule_id
values referencing Availability Rules
stored against the Account
.
If not specified or set to null
, all availability rules stored against the Account
will be used.
If an empty Array
is specified, ie []
then all availability rules stored against the Account
will be ignored.
participants.required required #
Either a String
of all
to specify that all members
of the group need to be available for a period to be viable, or an Integer
to specify the minimum number of the group that must be available.
required_duration required #
A Duration
describing the minimum period that the participant groups must be satisfied for a period to be deemed as available.
Must be greater than zero minutes in length.
query_periods optional #
An array of 1 to 50 query periods, across up to 35 days of the period of synchronized events, within which suitable matches may be found.
query_periods.start required #
The start
of a query period as a Time
.
It must represent a future point in time.
query_periods.end required #
The end
of a query period as a Time
.
Must be at least 1 minute after the corresponding start
and within 35 days of the earliest start
.
query_slots optional #
An array of 1 to 50 slot times, across up to 35 days of the period of synchronized events, within which suitable matches may be found.
This is an alternative to specifying query_periods
, giving you more control over the exact slot times considered.
query_slots.start required #
The start
of a query slot as a Time
.
It must represent a future point in time. The end
is unspecified, as it is implicit based on the value of the required_duration
parameter.
available_periods alias #
This is an alias for query_periods to maintain backwards compatibility. available_periods
is the original name for query_periods
and both represent the same concept, but query_periods
makes the intent clearer.
We will not remove support for using available_periods
but it is recommended to use query_periods
.
buffer.before optional #
A Duration
specifying the minimum number of minutes that must be free before the available period starts.
buffer.after optional #
A Duration
specifying the minimum number of minutes that must be free after the available period ends.
start_interval optional #
A Duration
describing the frequency that a sequence can start on.
For example, “every hour” or “every 15 minutes”.
Must be one of 5
, 10
, 15
, 20
, 30
, or 60
minutes.
This value is only relevant when using query_periods
, and is ignored when query_slots
are passed instead.
max_results optional #
An Integer
describing the maximum number of available periods or slots to return from the query.
Must be between 1
and 512
inclusive. If not provided up to 20
results will be returned.
include_member_statuses optional #
A Boolean
specifying if you want members’ synchronization status to be returned in the response.
Sync statuses are returned in an additional member_statuses
top level key on the response and include all of the members participating in the Availability Query.
This is useful to ensure the returned availability is based on the most up-to-date calendar data for the member.
See the description of the possible values below.
excluded_events optional #
An array of objects describing events that should not be considered during the Availability calculation.
{
...
"excluded_events": [
{ "event_id": "interview_123" },
{ "event_uid": "evt_external_64f758b2707e9e455c32e9e" },
]
}
Each item must specify either event_id
for a Managed Event or the event_uid
of an External Event (you can learn more about the difference between these here).
If the specified events appear in any of the calendars queried, they will not block time from being considered as Available.
This is useful for operations such as querying to reschedule a meeting, where omitting the current event representing the meeting may make some additional slots available. It can also be used to customize your query based on context, such as allowing a query for an important customer meeting to ignore several reschedulable internal meetings.
Response parameters #
available_periods #
An array of available periods that match the criteria specified in the request.
Up to 20
, or the value specified for max_results
, periods will be returned with preference being towards the soonest matches.
available_periods.start #
Thestart
of an available period as a Time
.
available_periods.end #
Theend
of an available period as a Time
.
available_periods.participants #
An array of participants that are available for the given period.
available_periods.participants.sub #
The internal Cronofy ID for the account, as an ASCII-only String
.
member_statuses #
An array of each of the participants in the query, and their synchronization status. Only returned when passing true
in the include_member_statuses
request parameter.
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
...
"member_statuses": [
{
"sub": "acc_64b17d868090ea21640c914c",
"sync_status": "active"
},
{
"sub": "acc_61815038636bd5c5ce4edd14",
"sync_status": "pending"
},
{
"sub": "acc_64b186438090ea21640c9160",
"sync_status": "disconnected"
}
]
}
member_statuses.sync_status #
The current synchronization status as a String
.
If a member has multiple calendar profiles authorized on their account and are participating in the query, this value represents the worst (least connected) profile.
The possible values are:
active
- their calendar is syncing and the query has used an up-to-date view of their availability.pending
- the initial sync of their calendar has not completed yet, so the query cannot consider a their full availability yet. The query has run based on the data available.disconnected
- their calendar profile is disconnected (usually due to expired credentials, awaiting relinking), so the query has run on the most recent data held and cannot guarantee a complete picture of their availability.hibernated
- your authorization to their Account is currently in a hibernated state. Including this Account in the query will trigger all Profiles for this Account to be fully synced. You can then reattempt the Availability query to get up to date calendar information.
Error responses #
401 Unauthorized #
The request was refused as the provided authentication credentials were not recognized.
Note that whilst many accounts can be part of the availability request that authentication is performed via theaccess_token
for only one of them.
When an OAuthrefresh_token
is available then it should be used to request a replacement auth_token
before the request is retried.
402 Payment Required #
The request was refused as your plan does not include the required feature.
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 required_duration
parameter, you would receive a response like:
{
"errors": {
"required_duration": [
{
"key": "errors.required",
"description": "required"
}
]
}
}
The key
field is intended for programmatic use and the description
field is a human-readable equivalent.
Common validation errors
- invalid_time_format - not a recognized time format.
available_periods.start
andavailable_periods.end
must be ISO 8601 compliant Time strings. - invalid_time_pair -
end
must be afterstart
. - max_date_exceeded - date is too far in the future.
available_periods
must be less than or equal to 201 days in the future. - min_date_exceeded - date is too far in the past.
available_periods
must be in the future. - max_period_exceeded -
available_periods.end
andquery_periods.end
must be within 35 days of the earliest start.