{
  "schemaVersion": "1.0",
  "title": "Cal.diy slots and reservations",
  "description": "Use these capabilities to query availability and to create, inspect, update, or release a short-lived slot reservation. The reviewed connector exposes five fixed operations, all pinned to Cal.diy API version 2024-09-04.",
  "canonical": "https://getaip.org/docs/connectors/cal-diy/capabilities/slots-and-reservations",
  "route": "/docs/connectors/cal-diy/capabilities/slots-and-reservations",
  "source": "docs/connectors/cal-diy/capabilities/slots-and-reservations.md",
  "protocol": "Agent Interoperability Protocol",
  "protocolVersion": "1.0",
  "section": "Connectors",
  "documentType": "Connector",
  "language": "en",
  "downloads": {
    "md": "/docs/download/connectors/cal-diy/capabilities/slots-and-reservations.md",
    "txt": "/docs/download/connectors/cal-diy/capabilities/slots-and-reservations.txt",
    "json": "/docs/download/connectors/cal-diy/capabilities/slots-and-reservations.json",
    "pdf": "/docs/download/connectors/cal-diy/capabilities/slots-and-reservations.pdf"
  },
  "content": {
    "format": "text/markdown",
    "markdown": "---\ntitle: Cal.diy slots and reservations\ndescription: Query one valid availability selector and manage the reservation lifecycle safely\nkind: capability-reference\naudience: application-developer\nappliesTo: \"1.x\"\nwritingStandard: \"aip-docs/1.0\"\nlastReviewedRevision: \"97be86e9efedf07ecf1783b03800f683f107fb04\"\nconnector: cal-diy\ncapabilityIds:\n  - cap:cal_diy:slot.list\n  - cap:cal_diy:slot.reservation.create\n  - cap:cal_diy:slot.reservation.get\n  - cap:cal_diy:slot.reservation.update\n  - cap:cal_diy:slot.reservation.delete\n---\n\n# Cal.diy slots and reservations\n\nUse these capabilities to query availability and to create, inspect, update, or\nrelease a short-lived slot reservation. The reviewed connector exposes five\nfixed operations, all pinned to Cal.diy API version `2024-09-04`.\n\nA slot result is a time-bounded observation. It does not reserve capacity and\ndoes not guarantee that a later booking will commit. Use a reservation when the\nworkflow needs a provider-owned hold, and preserve its opaque uid.\n\n## Operations\n\n| Capability | Provider request | Risk | Approval |\n|---|---|---|---|\n| `cap:cal_diy:slot.list` | `GET /v2/slots` | Low | No |\n| `cap:cal_diy:slot.reservation.create` | `POST /v2/slots/reservations` | Medium | Required |\n| `cap:cal_diy:slot.reservation.get` | `GET /v2/slots/reservations/{reservation_uid}` | Low | No |\n| `cap:cal_diy:slot.reservation.update` | `PATCH /v2/slots/reservations/{reservation_uid}` | Medium | Required |\n| `cap:cal_diy:slot.reservation.delete` | `DELETE /v2/slots/reservations/{reservation_uid}` | High | Required |\n\nApplications invoke the AIP capability and pass one input object. The connector\nencodes the slot query, percent-encodes the reservation path, and removes path\nfields from provider request bodies.\n\n## Query available slots\n\n`cap:cal_diy:slot.list` requires `start`, `end`, and exactly one selector\nbranch. Both boundaries accept an ISO date or date-time.\n\n### Select by event-type id\n\n```json\n{\n  \"start\": \"2030-01-01\",\n  \"end\": \"2030-01-08\",\n  \"eventTypeId\": 42,\n  \"timeZone\": \"Europe/London\",\n  \"format\": \"time\"\n}\n```\n\n`eventTypeId` is an integer.\n\n### Select by user and event slug\n\n```json\n{\n  \"start\": \"2030-01-01T00:00:00Z\",\n  \"end\": \"2030-01-08T00:00:00Z\",\n  \"eventTypeSlug\": \"product-consultation\",\n  \"username\": \"avery\"\n}\n```\n\n`eventTypeSlug` and `username` must be non-empty. `organizationSlug` is\noptional in this branch.\n\n### Select by team and event slug\n\n```json\n{\n  \"start\": \"2030-01-01\",\n  \"end\": \"2030-01-08\",\n  \"eventTypeSlug\": \"team-consultation\",\n  \"teamSlug\": \"solutions\"\n}\n```\n\n`eventTypeSlug` and `teamSlug` must be non-empty. `organizationSlug` is\noptional in this branch.\n\n### Select a dynamic group\n\n```json\n{\n  \"start\": \"2030-01-01\",\n  \"end\": \"2030-01-08\",\n  \"usernames\": [\"avery\", \"jordan\"],\n  \"organizationSlug\": \"example-org\"\n}\n```\n\nThis branch requires at least two unique, non-empty usernames and a non-empty\norganization slug.\n\nThe four branches reject each other's selector fields. For example, do not add\n`teamSlug` to an `eventTypeId` query or combine `username` with `usernames`.\nAdditional properties are rejected.\n\n### Shared query fields\n\n| Field | Constraint | Purpose |\n|---|---|---|\n| `start` | ISO date or date-time; required | Beginning of the query interval |\n| `end` | ISO date or date-time; required | End of the query interval |\n| `timeZone` | Non-empty string | Requested time-zone interpretation |\n| `duration` | Integer at least `1` | Requested slot duration |\n| `bookingUidToReschedule` | Non-empty string | Exclude or evaluate an existing booking during reschedule |\n| `format` | `time` or `range` | Provider response representation |\n\nThe published schema validates field shapes, not chronological ordering or\ntime-zone identifiers. Cal.diy can reject a schema-valid interval or selector\nunder provider-side policy.\n\n## Interpret slot results\n\nSlot discovery is a public-data read in the capability contract. It contains no\ndeclared PII and does not require redaction. Deployment policy may still limit\nwhich account, event type, team, or date range a caller may query.\n\nThe operation is synchronous, retry-safe, and eligible for connector retry. It\nuses optional action-scoped idempotency with input-hash revalidation. Retry only\nwithin the caller deadline and current policy; a later response may legitimately\nshow different availability.\n\nThe connector returns the provider JSON body after checking the common output\nschema. A non-empty string `status` is required. The `data`, `pagination`, and\nany additional provider fields are provider-owned and optional in the published\nconnector schema.\n\n## Create a reservation\n\n`cap:cal_diy:slot.reservation.create` requires an event-type id and a slot start:\n\n```json\n{\n  \"eventTypeId\": 42,\n  \"slotStart\": \"2030-01-03T10:00:00Z\",\n  \"slotDuration\": 30,\n  \"reservationDuration\": 5\n}\n```\n\n| Field | Constraint |\n|---|---|\n| `eventTypeId` | Integer; required |\n| `slotStart` | Date-time string; required |\n| `slotDuration` | Integer at least `1` |\n| `reservationDuration` | Integer at least `1` |\n\nAdditional properties are rejected before provider dispatch.\n\nThe published JSON Schema does not encode a unit for the two duration fields.\nThe source-owned ignored live exercise names its slot-duration input in minutes\nand uses `5` for `reservationDuration`. Treat that as test-source context, not\nas evidence that a live run passed or that a future provider version preserves\nthe same interpretation.\n\nCreate is a medium-risk mutation. It requires approval and an\nexternal-account-scoped idempotency key, but it does not perform a separate\nslot-list preflight. A schema-valid request can still lose an availability race\nor be rejected by Cal.diy.\n\n## Capture and read the reservation\n\nThe source-owned ignored live exercise expects a successful create response to\ncontain a non-empty string at `/data/reservationUid`, then uses that value for\nrelease. The connector's common output schema does not require that field.\n\nValidate the returned uid before storing or using it. If it is absent, stop and\ntreat the response as provider-contract drift; do not guess an identifier from\nthe action id or idempotency key.\n\n`cap:cal_diy:slot.reservation.get` accepts only:\n\n```json\n{\n  \"reservation_uid\": \"reservation-provider-uid\"\n}\n```\n\n`reservation_uid` must be a non-empty string. It is a sensitive provider handle\neven though the capability's data contract does not classify reservation\noperations as containing PII. Do not place it in application logs, user-visible\nURLs, or metric labels. The connector necessarily places its percent-encoded\nvalue in the provider request path.\n\nReservation get is a low-risk, retry-safe read. It does not extend or recreate\nthe reservation.\n\n## Update the reservation\n\nUpdate requires the existing uid, event-type id, and new slot start:\n\n```json\n{\n  \"reservation_uid\": \"reservation-provider-uid\",\n  \"eventTypeId\": 42,\n  \"slotStart\": \"2030-01-03T10:30:00Z\",\n  \"slotDuration\": 30,\n  \"reservationDuration\": 5\n}\n```\n\n`slotDuration` and `reservationDuration` remain optional positive integers.\nAll other properties are rejected.\n\nBefore update dispatch, the connector reads the current reservation by uid.\nThat preflight checks current provider visibility; it does not reserve the new\ntime, guarantee the update, or make the mutation retry-safe.\n\n## Release the reservation\n\nRelease uses the delete capability with the same one-field input as get:\n\n```json\n{\n  \"reservation_uid\": \"reservation-provider-uid\"\n}\n```\n\nThis is a high-risk destructive mutation. The connector reads the current\nreservation before dispatch, then sends `DELETE` to its fixed provider route.\nAfter a completed release, do not assume that the uid can be reused.\n\nRelease declares no rollback or compensation. Creating a later reservation is\nnew provider state and may fail because availability has changed.\n\n## Mutation safety and compensation\n\nCreate, update, and release share these contract requirements:\n\n| Contract field | Value |\n|---|---|\n| Human approval | Required |\n| Approval selector | Tenant policy |\n| Approval validity window | 900,000 ms |\n| Approval evidence | Reason, input snapshot, policy decision |\n| Idempotency | Required; external-account scope |\n| Collision behavior | Revalidate input hash |\n| Connector retry | Not supported |\n| Retry safety | Unsafe |\n| Execution | Synchronous only |\n| Transaction modes | `dry_run`, `plan`, `commit`, `reconcile` |\n| Plan before commit | Not required |\n| Dry-run fidelity | Policy and schema only |\n\nCreate and update use the `customer_visible_change` approval reason class.\nRelease uses `destructive_state_change`.\n\nReservation create names `slot.reservation.delete` as a best-effort,\napproval-required compensation with a 24-hour contract window. Compensation is\na new governed release action; it is not automatic and cannot guarantee that\ndownstream workflow effects disappear.\n\nUpdate and release declare rollback unsupported. If a mutation outcome is\nuncertain, reconcile the durable provider-operation evidence instead of sending\nthe action again under a new key.\n\nReservation operations are confidential but declare no PII and set the\ncontract's `redaction_required` marker to false. The connector still applies\nits generic secret-name redactor to every provider body. Neither fact makes the\nreservation uid public.\n\n## Failures and recovery\n\n| Failure | Relevant cause | Safe response |\n|---|---|---|\n| `connector.cal_diy.invalid_action` | Wrong selector branch, missing required field, invalid date shape, empty uid, or unknown property | Correct input before another call |\n| `connector.cal_diy.policy` | Mutation omitted its idempotency key | Preserve the approved input and supply the required key |\n| `connector.cal_diy.idempotency_collision` | The key already owns different input | Stop and inspect the original action |\n| `connector.cal_diy.in_flight` | The matching reservation mutation is still running | Read durable action state and wait |\n| `connector.cal_diy.outcome_unknown` | A prior provider dispatch cannot be proved | Reconcile; do not create a replacement key |\n| `connector.cal_diy.authentication` | Provider returned `401` or `403` | Verify account binding and credential revision |\n| `connector.cal_diy.state_conflict` | Provider returned `409` or `412` | Read current reservation or slots and review the intended change |\n| `connector.cal_diy.rate_limited` | Provider returned `429` | Retry slot or reservation reads within policy; reconcile mutations |\n| `connector.cal_diy.remote_temporary` | Provider returned a server error | Retry reads within policy; reconcile mutations |\n| `connector.cal_diy.transport` | Provider exchange failed | Retry reads only; treat dispatched mutations as uncertain |\n| `connector.cal_diy.invalid_provider_output` | Successful response lacked a valid `status` | Preserve evidence and reconcile a mutation |\n\nPermanent provider rejection, invalid credentials, oversized responses, and\ndurable settlement failures use the common Cal.diy error family. Gateway and\nlifecycle errors are described in the [global error reference](../../../reference/errors.md).\n\n## Verify the lifecycle\n\nFor slot discovery, verify the selected branch, account route, query interval,\nresponse status, and observation time. Do not cache the result beyond the\nworkflow's availability policy.\n\nFor a reservation lifecycle, verify that:\n\n- discovery returns the exact reservation capability before each action;\n- approval binds the exact mutation input;\n- each mutation retains its external-account idempotency key;\n- create returns a validated non-empty reservation uid before later calls;\n- update or release reaches a completed durable state;\n- a read confirms the expected reservation state when the provider supports it;\n- uncertain dispatch is reconciled instead of repeated.\n\nThe ignored live exercise in source describes a reversible round trip, but its\npresence is not retained execution evidence. These checks do not claim live\nprovider qualification or production readiness.\n\n## Related documentation\n\n- [Cal.diy capability index](README.md)\n- [Authentication and tenant routing](../getting-started/authentication-and-tenant-routing.md)\n- [Approvals and policy](../../../concepts/approvals-and-policy.md)\n- [Transactions and compensation](../../../concepts/transactions-and-compensation.md)\n- [Error reference](../../../reference/errors.md)\n",
    "text": "Cal.diy slots and reservations\n\nUse these capabilities to query availability and to create, inspect, update, or\nrelease a short-lived slot reservation. The reviewed connector exposes five\nfixed operations, all pinned to Cal.diy API version 2024-09-04.\n\nA slot result is a time-bounded observation. It does not reserve capacity and\ndoes not guarantee that a later booking will commit. Use a reservation when the\nworkflow needs a provider-owned hold, and preserve its opaque uid.\n\nOperations\n\n| Capability | Provider request | Risk | Approval |\n\n| cap:caldiy:slot.list | GET /v2/slots | Low | No |\n| cap:caldiy:slot.reservation.create | POST /v2/slots/reservations | Medium | Required |\n| cap:caldiy:slot.reservation.get | GET /v2/slots/reservations/{reservationuid} | Low | No |\n| cap:caldiy:slot.reservation.update | PATCH /v2/slots/reservations/{reservationuid} | Medium | Required |\n| cap:caldiy:slot.reservation.delete | DELETE /v2/slots/reservations/{reservationuid} | High | Required |\n\nApplications invoke the AIP capability and pass one input object. The connector\nencodes the slot query, percent-encodes the reservation path, and removes path\nfields from provider request bodies.\n\nQuery available slots\n\ncap:caldiy:slot.list requires start, end, and exactly one selector\nbranch. Both boundaries accept an ISO date or date-time.\n\nSelect by event-type id\n\n{\n  \"start\": \"2030-01-01\",\n  \"end\": \"2030-01-08\",\n  \"eventTypeId\": 42,\n  \"timeZone\": \"Europe/London\",\n  \"format\": \"time\"\n}\n\neventTypeId is an integer.\n\nSelect by user and event slug\n\n{\n  \"start\": \"2030-01-01T00:00:00Z\",\n  \"end\": \"2030-01-08T00:00:00Z\",\n  \"eventTypeSlug\": \"product-consultation\",\n  \"username\": \"avery\"\n}\n\neventTypeSlug and username must be non-empty. organizationSlug is\noptional in this branch.\n\nSelect by team and event slug\n\n{\n  \"start\": \"2030-01-01\",\n  \"end\": \"2030-01-08\",\n  \"eventTypeSlug\": \"team-consultation\",\n  \"teamSlug\": \"solutions\"\n}\n\neventTypeSlug and teamSlug must be non-empty. organizationSlug is\noptional in this branch.\n\nSelect a dynamic group\n\n{\n  \"start\": \"2030-01-01\",\n  \"end\": \"2030-01-08\",\n  \"usernames\": [\"avery\", \"jordan\"],\n  \"organizationSlug\": \"example-org\"\n}\n\nThis branch requires at least two unique, non-empty usernames and a non-empty\norganization slug.\n\nThe four branches reject each other's selector fields. For example, do not add\nteamSlug to an eventTypeId query or combine username with usernames.\nAdditional properties are rejected.\n\nShared query fields\n\n| Field | Constraint | Purpose |\n\n| start | ISO date or date-time; required | Beginning of the query interval |\n| end | ISO date or date-time; required | End of the query interval |\n| timeZone | Non-empty string | Requested time-zone interpretation |\n| duration | Integer at least 1 | Requested slot duration |\n| bookingUidToReschedule | Non-empty string | Exclude or evaluate an existing booking during reschedule |\n| format | time or range | Provider response representation |\n\nThe published schema validates field shapes, not chronological ordering or\ntime-zone identifiers. Cal.diy can reject a schema-valid interval or selector\nunder provider-side policy.\n\nInterpret slot results\n\nSlot discovery is a public-data read in the capability contract. It contains no\ndeclared PII and does not require redaction. Deployment policy may still limit\nwhich account, event type, team, or date range a caller may query.\n\nThe operation is synchronous, retry-safe, and eligible for connector retry. It\nuses optional action-scoped idempotency with input-hash revalidation. Retry only\nwithin the caller deadline and current policy; a later response may legitimately\nshow different availability.\n\nThe connector returns the provider JSON body after checking the common output\nschema. A non-empty string status is required. The data, pagination, and\nany additional provider fields are provider-owned and optional in the published\nconnector schema.\n\nCreate a reservation\n\ncap:caldiy:slot.reservation.create requires an event-type id and a slot start:\n\n{\n  \"eventTypeId\": 42,\n  \"slotStart\": \"2030-01-03T10:00:00Z\",\n  \"slotDuration\": 30,\n  \"reservationDuration\": 5\n}\n\n| Field | Constraint |\n\n| eventTypeId | Integer; required |\n| slotStart | Date-time string; required |\n| slotDuration | Integer at least 1 |\n| reservationDuration | Integer at least 1 |\n\nAdditional properties are rejected before provider dispatch.\n\nThe published JSON Schema does not encode a unit for the two duration fields.\nThe source-owned ignored live exercise names its slot-duration input in minutes\nand uses 5 for reservationDuration. Treat that as test-source context, not\nas evidence that a live run passed or that a future provider version preserves\nthe same interpretation.\n\nCreate is a medium-risk mutation. It requires approval and an\nexternal-account-scoped idempotency key, but it does not perform a separate\nslot-list preflight. A schema-valid request can still lose an availability race\nor be rejected by Cal.diy.\n\nCapture and read the reservation\n\nThe source-owned ignored live exercise expects a successful create response to\ncontain a non-empty string at /data/reservationUid, then uses that value for\nrelease. The connector's common output schema does not require that field.\n\nValidate the returned uid before storing or using it. If it is absent, stop and\ntreat the response as provider-contract drift; do not guess an identifier from\nthe action id or idempotency key.\n\ncap:caldiy:slot.reservation.get accepts only:\n\n{\n  \"reservationuid\": \"reservation-provider-uid\"\n}\n\nreservationuid must be a non-empty string. It is a sensitive provider handle\neven though the capability's data contract does not classify reservation\noperations as containing PII. Do not place it in application logs, user-visible\nURLs, or metric labels. The connector necessarily places its percent-encoded\nvalue in the provider request path.\n\nReservation get is a low-risk, retry-safe read. It does not extend or recreate\nthe reservation.\n\nUpdate the reservation\n\nUpdate requires the existing uid, event-type id, and new slot start:\n\n{\n  \"reservationuid\": \"reservation-provider-uid\",\n  \"eventTypeId\": 42,\n  \"slotStart\": \"2030-01-03T10:30:00Z\",\n  \"slotDuration\": 30,\n  \"reservationDuration\": 5\n}\n\nslotDuration and reservationDuration remain optional positive integers.\nAll other properties are rejected.\n\nBefore update dispatch, the connector reads the current reservation by uid.\nThat preflight checks current provider visibility; it does not reserve the new\ntime, guarantee the update, or make the mutation retry-safe.\n\nRelease the reservation\n\nRelease uses the delete capability with the same one-field input as get:\n\n{\n  \"reservationuid\": \"reservation-provider-uid\"\n}\n\nThis is a high-risk destructive mutation. The connector reads the current\nreservation before dispatch, then sends DELETE to its fixed provider route.\nAfter a completed release, do not assume that the uid can be reused.\n\nRelease declares no rollback or compensation. Creating a later reservation is\nnew provider state and may fail because availability has changed.\n\nMutation safety and compensation\n\nCreate, update, and release share these contract requirements:\n\n| Contract field | Value |\n\n| Human approval | Required |\n| Approval selector | Tenant policy |\n| Approval validity window | 900,000 ms |\n| Approval evidence | Reason, input snapshot, policy decision |\n| Idempotency | Required; external-account scope |\n| Collision behavior | Revalidate input hash |\n| Connector retry | Not supported |\n| Retry safety | Unsafe |\n| Execution | Synchronous only |\n| Transaction modes | dryrun, plan, commit, reconcile |\n| Plan before commit | Not required |\n| Dry-run fidelity | Policy and schema only |\n\nCreate and update use the customervisiblechange approval reason class.\nRelease uses destructivestatechange.\n\nReservation create names slot.reservation.delete as a best-effort,\napproval-required compensation with a 24-hour contract window. Compensation is\na new governed release action; it is not automatic and cannot guarantee that\ndownstream workflow effects disappear.\n\nUpdate and release declare rollback unsupported. If a mutation outcome is\nuncertain, reconcile the durable provider-operation evidence instead of sending\nthe action again under a new key.\n\nReservation operations are confidential but declare no PII and set the\ncontract's redactionrequired marker to false. The connector still applies\nits generic secret-name redactor to every provider body. Neither fact makes the\nreservation uid public.\n\nFailures and recovery\n\n| Failure | Relevant cause | Safe response |\n\n| connector.caldiy.invalidaction | Wrong selector branch, missing required field, invalid date shape, empty uid, or unknown property | Correct input before another call |\n| connector.caldiy.policy | Mutation omitted its idempotency key | Preserve the approved input and supply the required key |\n| connector.caldiy.idempotencycollision | The key already owns different input | Stop and inspect the original action |\n| connector.caldiy.inflight | The matching reservation mutation is still running | Read durable action state and wait |\n| connector.caldiy.outcomeunknown | A prior provider dispatch cannot be proved | Reconcile; do not create a replacement key |\n| connector.caldiy.authentication | Provider returned 401 or 403 | Verify account binding and credential revision |\n| connector.caldiy.stateconflict | Provider returned 409 or 412 | Read current reservation or slots and review the intended change |\n| connector.caldiy.ratelimited | Provider returned 429 | Retry slot or reservation reads within policy; reconcile mutations |\n| connector.caldiy.remotetemporary | Provider returned a server error | Retry reads within policy; reconcile mutations |\n| connector.caldiy.transport | Provider exchange failed | Retry reads only; treat dispatched mutations as uncertain |\n| connector.caldiy.invalidprovideroutput | Successful response lacked a valid status | Preserve evidence and reconcile a mutation |\n\nPermanent provider rejection, invalid credentials, oversized responses, and\ndurable settlement failures use the common Cal.diy error family. Gateway and\nlifecycle errors are described in the global error reference (../../../reference/errors.md).\n\nVerify the lifecycle\n\nFor slot discovery, verify the selected branch, account route, query interval,\nresponse status, and observation time. Do not cache the result beyond the\nworkflow's availability policy.\n\nFor a reservation lifecycle, verify that:\n• discovery returns the exact reservation capability before each action;\n• approval binds the exact mutation input;\n• each mutation retains its external-account idempotency key;\n• create returns a validated non-empty reservation uid before later calls;\n• update or release reaches a completed durable state;\n• a read confirms the expected reservation state when the provider supports it;\n• uncertain dispatch is reconciled instead of repeated.\n\nThe ignored live exercise in source describes a reversible round trip, but its\npresence is not retained execution evidence. These checks do not claim live\nprovider qualification or production readiness.\n\nRelated documentation\n• Cal.diy capability index (README.md)\n• Authentication and tenant routing (../getting-started/authentication-and-tenant-routing.md)\n• Approvals and policy (../../../concepts/approvals-and-policy.md)\n• Transactions and compensation (../../../concepts/transactions-and-compensation.md)\n• Error reference (../../../reference/errors.md)\n"
  },
  "integrity": {
    "algorithm": "sha256",
    "sourceDigest": "ed99fca252b359a1dc68f2da2c70f78ce9d2baf1d27d7cf13adecbca4bb7c022"
  }
}
