# Integration Operations

### Description
Integration operations are the actions your application can take on a
[Scheduling Request](https://docs.cronofy.com/api-reference/managed-scheduling/scheduling-requests/index.md)
over the API, such as listing its available times with
[Available Slots](https://docs.cronofy.com/api-reference/managed-scheduling/scheduling-requests/available-slots/index.md) and booking one with
[Select Slot](https://docs.cronofy.com/api-reference/managed-scheduling/scheduling-requests/select-slot/index.md). Together these let your
application book a request that only needs a time, without sending a person to
the booking page.

Every integration operation follows the same structure: you discover it from
the request, call the URL Cronofy gives you, and get back a typed result
alongside the current state of the request. This page describes that
structure; each operation's page covers what it does and the results it can
return.

### Discovering the operations
You never build the operation URLs yourself. They are handed to you when they
are available via an `integration_operations` object, mirroring the
`recipient_operations` object aimed at the person the request is intended for.
`integration_operations` are the set of actions available to your application
at that point in the request's life.

```json
{
  "integration_operations": {
    "simple_available_slots_url": "{SIMPLE_AVAILABLE_SLOTS_URL}"
  }
}
```

`integration_operations` appears on the Scheduling Request everywhere it is
serialized, including the [Create](https://docs.cronofy.com/api-reference/managed-scheduling/scheduling-requests/create/index.md)
and [Query](https://docs.cronofy.com/api-reference/managed-scheduling/scheduling-requests/query/index.md) responses,
and on the result of every operation. Some operations are only advertised once
an earlier one has been called, so following the URLs as they are returned
means there is nothing for your application to construct or store between
steps.

The operations currently available are:

<table>
	<thead>
			<tr>
					<th>Key</th>
					<th>Operation</th>
					<th>Advertised by</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>`simple_available_slots_url`</td>
					<td>[Available Slots](https://docs.cronofy.com/api-reference/managed-scheduling/scheduling-requests/available-slots/index.md)</td>
					<td>The Scheduling Request</td>
			</tr>
			<tr>
					<td>`simple_select_slot_url`</td>
					<td>[Select Slot](https://docs.cronofy.com/api-reference/managed-scheduling/scheduling-requests/select-slot/index.md)</td>
					<td>Available Slots</td>
			</tr>
	</tbody>
</table>
> **INFO:** We are actively working on this area of the platform. If there are operations
you want to be made available via the API, please email
[support@cronofy.com](mailto:support@cronofy.com) with your use case.

When no operation is available, `integration_operations` is an empty object
`{}`. Where a person can still act, send them to
[`recipient_operations.view_url`](https://docs.cronofy.com/api-reference/managed-scheduling/scheduling-requests/query/index.md).

### Operation URLs are opaque
Treat every operation URL as **opaque**. Use it exactly as Cronofy provides it.
Do not parse it or store assumptions about its shape. As these operations are
enhanced and expanded, the URLs may change and so will an integration that
relies on a specific pattern.

Its host, path, and any identifier within it are not part of the contract and
may change. The only guarantee is that the string Cronofy hands you in
`integration_operations` will work for a suitable period for the related
workflow (minutes or hours, rather than days or weeks).

Unlike examples elsewhere in our documentation, these URLs are shown as
placeholders such as `{SIMPLE_AVAILABLE_SLOTS_URL}`, precisely because their
structure is not part of the contract.

### The response envelope
The successes and the business-state failures of every operation share one
response shape: a typed `integration_operation_result` object beside the full
`scheduling_request`. Returning the request on every such response lets you
inspect and render the current state, and see what is possible.

```json
{
  "integration_operation_result": {
    "type": "available_slots",
    "result": "success",
    "integration_operations": { ... },
    ...
  },
  "scheduling_request": { ... }
}
```

`integration_operation_result` always carries:

- `type`: the operation invoked, for example `available_slots` or `select_slot`.

- `result`: the outcome, from the [result vocabulary](#result-vocabulary) below.

- `integration_operations`: the same "what's next" map the request carries,
so new actions can appear without changing the shape.

Any context-specific data sits alongside these, such as the `available_slots`
for a listing or the `selected_slot` for a selection.

### Result vocabulary
<table>
	<thead>
			<tr>
					<th>HTTP</th>
					<th>`result`</th>
					<th>Meaning</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>`200`</td>
					<td>`success`</td>
					<td>The operation completed; the response holds what was asked for.</td>
			</tr>
			<tr>
					<td>`202`</td>
					<td>`accepted`</td>
					<td>The operation was accepted; it will be processed asynchronously.</td>
			</tr>
			<tr>
					<td>`409`</td>
					<td>`conflict`</td>
					<td>Transient state meant the operation could not be actioned; retry the same payload shortly.</td>
			</tr>
			<tr>
					<td>`409`</td>
					<td>`not_possible`</td>
					<td>The request's current state means this cannot be done; see `result_detail`.</td>
			</tr>
			<tr>
					<td>`422`</td>
					<td>`invalid`</td>
					<td>The input was wrong, such as a missing or malformed value; see the top-level `errors`.</td>
			</tr>
	</tbody>
</table>
Each operation's page lists the results it can return.

### result_detail
The `result` guides the general handling of all operation results, the
`result_detail` allows you to specialize based on more operation-specific
variations of a `not_possible` `result`.

The values below are common to every operation. An operation may also return
special cases of its own, which are documented on its page.

#### superseded
The token was replaced, or the request is paused and will re-open under a new
token. Re-read the accompanying `scheduling_request` and follow whatever it now
advertises.

#### no_longer_possible
The request is booked, cancelled, expired, or otherwise terminal. Stop; fall back
to `recipient_operations.view_url` if a person can still act.

#### requires_more_input
The request needs more input than the operation can provide. Send the person to
the booking page (`recipient_operations.view_url`). Each operation's page
describes what it can and can't complete.

#### configuration_error
Some configuration of the request or its participants prevents it from being
completed. The underlying configuration will need to be resolved for this
request to be scheduled.

### Error responses
Failures fall into two shapes.

**Failures with useful request state** (the successes, the business-state
`409`s, and the validation `422`) use the [response envelope](#the-response-envelope)
so the `scheduling_request` travels alongside. A `not_possible` adds a
[`result_detail`](#result_detail); an `invalid` adds a top-level `errors` map, a
sibling of `integration_operation_result`, in the public API's
`{ &quot;<field>&quot;: [ { &quot;key&quot;, &quot;description&quot; } ] }` form:

```json
{
  "integration_operation_result": {
    "type": "select_slot",
    "result": "invalid",
    "integration_operations": {}
  },
  "errors": {
    "start": [
      { "key": "errors.required", "description": "required" }
    ]
  },
  "scheduling_request": { ... }
}
```

**Failures that are only about the caller or their credentials** carry no useful
request state, so they mirror the public API's
[errors shape](https://docs.cronofy.com/api-reference/fundamentals/error-codes/index.md) with no
envelope:

```json
{
  "errors": {
    "authentication": [
      { "key": "errors.unauthorized", "description": "unauthorized" }
    ]
  }
}
```

This shape covers:

- `401` / `403`: authentication and authorization failures, which also
carry a `WWW-Authenticate` header;

- `404`: an unknown or deleted token;

- `429`: rate limited, returned with an empty body.

The `description` in an errors body is a human-readable fallback; treat the `key`
as the stable identifier. The specific errors each operation can return are
listed on its page.

### Authentication
The token in the URL identifies the request; the caller additionally
authenticates so the calls can be audited and rate limited. Two credentials are
accepted, the same two the [Scheduling Requests](https://docs.cronofy.com/api-reference/managed-scheduling/scheduling-requests/index.md)
endpoints accept:

- an access token for the Organizational Unit, created by authorizing an
application for an [Organizational Unit scope](https://docs.cronofy.com/developers/authorization/organization-connect/index.md);

- the `client_secret` of an [Internal Application](https://docs.cronofy.com/developers/application-management/internal-applications/index.md)
linked to the Organizational Unit.

The resolved application or Organizational Unit must own the request. Both are
passed as a `Bearer` credential in the `Authorization` header.

**Scopes.** Access-token callers need the `organizational_unit_scheduling` scope.
An access token missing it receives a `403` with a `WWW-Authenticate` header
naming the scope needed. `client_secret` callers are granted the scheduler scope
implicitly.

**Rate limiting.** These endpoints draw from the same rate-limit buckets as the
rest of the public API, so they grant no additional allowance. A breach returns
`429`; see the [rate limits FAQ](https://docs.cronofy.com/developers/faqs/application-management/rate-limits/index.md).

### Times
Every time in a request or response is in UTC, formatted with a trailing `Z`
(for example `2026-10-24T09:00:00Z`).



---
[Read in HTML](https://docs.cronofy.com/api-reference/managed-scheduling/scheduling-requests/integration-operations/)