{
  "schemaVersion": "1.0",
  "title": "Cal.diy profile capabilities",
  "description": "Use these capabilities to read or update the Cal.diy profile owned by the credential configured for the selected external account. Both operations use the provider route /v2/me, but they have different authorization, approval, idempotency, ",
  "canonical": "https://getaip.org/docs/connectors/cal-diy/capabilities/profile",
  "route": "/docs/connectors/cal-diy/capabilities/profile",
  "source": "docs/connectors/cal-diy/capabilities/profile.md",
  "protocol": "Agent Interoperability Protocol",
  "protocolVersion": "1.0",
  "section": "Connectors",
  "documentType": "Connector",
  "language": "en",
  "downloads": {
    "md": "/docs/download/connectors/cal-diy/capabilities/profile.md",
    "txt": "/docs/download/connectors/cal-diy/capabilities/profile.txt",
    "json": "/docs/download/connectors/cal-diy/capabilities/profile.json",
    "pdf": "/docs/download/connectors/cal-diy/capabilities/profile.pdf"
  },
  "content": {
    "format": "text/markdown",
    "markdown": "---\ntitle: Cal.diy profile capabilities\ndescription: Read or update the authenticated Cal.diy profile through its exact AIP contracts\nkind: capability-reference\naudience: application-developer\nappliesTo: \"1.x\"\nwritingStandard: \"aip-docs/1.0\"\nlastReviewedRevision: \"97be86e9efedf07ecf1783b03800f683f107fb04\"\nconnector: cal-diy\ncapabilityIds:\n  - cap:cal_diy:profile.get\n  - cap:cal_diy:profile.update\n---\n\n# Cal.diy profile capabilities\n\nUse these capabilities to read or update the Cal.diy profile owned by the\ncredential configured for the selected external account. Both operations use\nthe provider route `/v2/me`, but they have different authorization, approval,\nidempotency, and retry requirements.\n\nThe connector exposes exactly two profile operations at the reviewed source\nrevision. It does not expose an arbitrary pass-through profile endpoint.\n\n## Operations\n\n| Capability | Provider request | Risk | Approval | Retry |\n|---|---|---|---|---|\n| `cap:cal_diy:profile.get` | `GET /v2/me` | Low | No | Safe |\n| `cap:cal_diy:profile.update` | `PATCH /v2/me` | Medium | Required | Unsafe |\n\nBoth requests set `cal-api-version: 2024-08-13`. The connector also sends the\nconfigured provider credential and trusted AIP request metadata. Applications\ninvoke the AIP capability; they do not construct this provider request directly.\n\n## Read the profile\n\n`cap:cal_diy:profile.get` reads the profile associated with the selected\ncredential. Its input is an object with no properties:\n\n```json\n{}\n```\n\nAdditional properties are rejected by the published input schema. The\noperation is a synchronous, low-risk read with these contract markers:\n\n| Contract field | Value |\n|---|---|\n| Side effects | `read`, `external_network` |\n| Human approval | Not required by the capability |\n| Idempotency | Optional; action scope; revalidate input hash on collision |\n| Connector retry support | Yes |\n| Retry safety | Safe |\n| Data sensitivity | Restricted; contains PII; redaction required |\n| Credential scope | `cal_diy:profile.get` |\n| Expected latency hint | 2,000 ms |\n| Provider timeout | 30,000 ms |\n\n“No human approval” is not “no authorization.” The gateway and connector host\nstill enforce the authenticated actor, tenant, admitted route, credential\nrevision, and policy for the request.\n\n## Update the profile\n\n`cap:cal_diy:profile.update` changes fields on the same authenticated profile.\nPass only the fields that should change:\n\n```json\n{\n  \"name\": \"Avery Patel\",\n  \"timeFormat\": 24,\n  \"weekStart\": \"Monday\",\n  \"timeZone\": \"Europe/London\",\n  \"locale\": \"en\",\n  \"bio\": \"Scheduling product consultations\"\n}\n```\n\nThe input schema technically accepts an empty object because every field is\noptional. Do not send an empty update as a probe. Use `profile.get` for a read,\nand include at least one intentional field in an update.\n\n### Update fields\n\n| Field | Type and constraint | Meaning |\n|---|---|---|\n| `email` | String with email format | Profile email |\n| `name` | String | Display name |\n| `timeFormat` | Integer: `12` or `24` | Clock format |\n| `defaultScheduleId` | Integer | Default Cal.diy schedule identifier |\n| `weekStart` | Weekday enum | First day of the displayed week |\n| `timeZone` | Non-empty string | Profile time-zone identifier |\n| `locale` | Supported locale enum | Profile interface locale |\n| `avatarUrl` | String with URI format | Profile avatar URL |\n| `bio` | String | Profile biography |\n| `metadata` | Object with bounded scalar values | Provider profile metadata |\n\nAdditional top-level properties are rejected. The schema does not add business\nrules beyond the constraints shown here; provider-side account policy can still\nreject a schema-valid value.\n\n`weekStart` accepts exactly:\n\n```text\nMonday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday\n```\n\n`locale` accepts exactly:\n\n```text\nar | ca | de | es | eu | he | id | ja | lv | pl | ro | sr | th | vi | az\ncs | el | es-419 | fi | hr | it | km | nl | pt | ru | sv | tr | zh-CN\nbg | da | en | et | fr | hu | iw | ko | no | pt-BR | sk | ta | uk | zh-TW\nbn\n```\n\nThe `metadata` object accepts at most 50 properties. Each property name has at\nmost 40 characters. Each value must be a string, Boolean, or number; a string\nvalue has at most 500 characters. Nested objects, arrays, and null values are\nnot accepted.\n\n### Update safety contract\n\n| Contract field | Value |\n|---|---|\n| Side effects | `write`, `external_network`, `identity` |\n| Human approval | Required |\n| Approval reason class | `customer_visible_change` |\n| Idempotency | Required; external-account scope |\n| Collision behavior | Revalidate input hash |\n| Connector retry support | No |\n| Retry safety | Unsafe |\n| Data sensitivity | Restricted; contains PII; redaction required |\n| Credential scope | `cal_diy:profile.update` |\n| Expected latency hint | 5,000 ms |\n| Provider timeout | 30,000 ms |\n\nThe approval policy uses the tenant-policy selector and a 900,000 ms validity\nwindow. Approval evidence must include a reason, an input snapshot, and the\npolicy decision. Bind the approval to the exact actor, tenant, capability, and\ninput being executed. A changed field or value requires a new decision.\n\nThe identity side-effect marker is additive: it tells policy that this write\nchanges account identity or presentation data. It does not replace provider\nauthorization or grant permission to change an email address.\n\n## Idempotency and settlement\n\nEvery profile update requires an idempotency key. Scope it to the selected\nexternal account and preserve the same key only for the same canonical input.\nReusing a key with different update content is an idempotency collision.\n\nBefore provider dispatch, the connector records a durable claim. A repeated\nmatching request can observe one of three relevant states:\n\n| Durable state | Meaning | Application action |\n|---|---|---|\n| Completed | The original result was stored | Accept the stored result |\n| In progress | Another invocation owns the claim | Read durable action state; do not create a new key |\n| Uncertain | Dispatch may have crossed the provider boundary | Reconcile evidence; do not repeat the update |\n\n`profile.update` supports `dry_run`, `plan`, `commit`, and `reconcile` modes. A\nplan is not required before commit, and dry-run fidelity is limited to policy\nand schema checks. A successful dry run does not prove that Cal.diy will accept\nthe update.\n\nThe capability declares no rollback or compensating capability. If a completed\nupdate must be reversed, submit a new, separately approved update using values\nconfirmed from authoritative state. Do not treat that later write as an atomic\nrollback.\n\n## Result contract\n\nThe connector returns the validated Cal.diy JSON response as the AIP action\noutput. The common output schema requires a non-empty string `status` and may\ncontain `data`, `pagination`, or additional provider fields:\n\n```json\n{\n  \"status\": \"success\",\n  \"data\": {}\n}\n```\n\nThis example demonstrates only the connector envelope. The connector does not\npublish an exhaustive provider profile schema for `data`. Consumers must\ntolerate additional fields and must not assume a particular `data` shape.\n\nBefore returning output, the connector recursively replaces values whose\nnormalized field names are `secret`, `apiKey`, `hashedKey`, `token`,\n`accessToken`, `refreshToken`, or `clientSecret` with `[REDACTED]`. Profile data\nremains classified as restricted even after this targeted redaction.\n\nAn empty successful provider body is normalized to:\n\n```json\n{\n  \"status\": \"success\"\n}\n```\n\n## Failures and recovery\n\n| Failure | Typical cause | Safe response |\n|---|---|---|\n| `connector.cal_diy.invalid_action` | Input does not match the published operation schema | Correct the input; do not resend unchanged data |\n| `connector.cal_diy.policy` | A mutation lacks its required idempotency key | Supply the missing key while preserving the original governed input |\n| `connector.cal_diy.idempotency_collision` | The key already owns different input | Stop and inspect the original action; never force reuse |\n| `connector.cal_diy.in_flight` | A matching mutation is still executing | Read durable state and wait for settlement |\n| `connector.cal_diy.outcome_unknown` | The provider outcome cannot be proved | Reconcile using durable and provider evidence; do not retry |\n| `connector.cal_diy.authentication` | Cal.diy returned `401` or `403` | Verify account binding and credential revision before another call |\n| `connector.cal_diy.state_conflict` | Cal.diy returned `409` or `412` | Refresh authoritative profile state and review the intended change |\n| `connector.cal_diy.rate_limited` | Cal.diy returned `429` | Honor the retry delay only when the action contract permits retry |\n| `connector.cal_diy.remote_temporary` | Cal.diy returned a server error | Retry reads within policy; reconcile mutations |\n| `connector.cal_diy.remote_rejected` | Cal.diy rejected another client request | Correct the request or account state before retrying |\n| `connector.cal_diy.transport` | The provider exchange failed | Retry a read within policy; treat a dispatched mutation as uncertain |\n| `connector.cal_diy.response_too_large` | The response exceeded the configured bound | Do not bypass the bound casually; inspect provider output and configuration |\n| `connector.cal_diy.invalid_provider_output` | A successful response lacked a valid non-empty `status` | Preserve request evidence; reconcile an update before investigating provider drift |\n\nErrors can also include a validated provider request ID and remote status. Keep\nthose values with the AIP action ID and external-account identity during\ndiagnosis. Error details do not contain raw provider response bodies.\n\nFor global lifecycle and gateway errors, use the [error reference](../../../reference/errors.md).\n\n## Verify an integration\n\nFor a profile read, verify that:\n\n- discovery returns `cap:cal_diy:profile.get` for the intended account route;\n- the completed result belongs to the submitted action ID;\n- the output has a non-empty `status`;\n- returned PII is handled under the tenant's restricted-data policy.\n\nFor a profile update, additionally verify that:\n\n- the approval evidence binds the exact update input;\n- the external-account idempotency key is retained with the action record;\n- the durable result is completed before relying on the new profile value;\n- a follow-up read confirms the intended fields without exposing unrelated PII;\n- an uncertain result is reconciled instead of repeated.\n\nThese checks validate application handling. They do not establish live-provider\nqualification or production readiness for a particular deployment.\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 profile capabilities\n\nUse these capabilities to read or update the Cal.diy profile owned by the\ncredential configured for the selected external account. Both operations use\nthe provider route /v2/me, but they have different authorization, approval,\nidempotency, and retry requirements.\n\nThe connector exposes exactly two profile operations at the reviewed source\nrevision. It does not expose an arbitrary pass-through profile endpoint.\n\nOperations\n\n| Capability | Provider request | Risk | Approval | Retry |\n\n| cap:caldiy:profile.get | GET /v2/me | Low | No | Safe |\n| cap:caldiy:profile.update | PATCH /v2/me | Medium | Required | Unsafe |\n\nBoth requests set cal-api-version: 2024-08-13. The connector also sends the\nconfigured provider credential and trusted AIP request metadata. Applications\ninvoke the AIP capability; they do not construct this provider request directly.\n\nRead the profile\n\ncap:caldiy:profile.get reads the profile associated with the selected\ncredential. Its input is an object with no properties:\n\n{}\n\nAdditional properties are rejected by the published input schema. The\noperation is a synchronous, low-risk read with these contract markers:\n\n| Contract field | Value |\n\n| Side effects | read, externalnetwork |\n| Human approval | Not required by the capability |\n| Idempotency | Optional; action scope; revalidate input hash on collision |\n| Connector retry support | Yes |\n| Retry safety | Safe |\n| Data sensitivity | Restricted; contains PII; redaction required |\n| Credential scope | caldiy:profile.get |\n| Expected latency hint | 2,000 ms |\n| Provider timeout | 30,000 ms |\n\n“No human approval” is not “no authorization.” The gateway and connector host\nstill enforce the authenticated actor, tenant, admitted route, credential\nrevision, and policy for the request.\n\nUpdate the profile\n\ncap:caldiy:profile.update changes fields on the same authenticated profile.\nPass only the fields that should change:\n\n{\n  \"name\": \"Avery Patel\",\n  \"timeFormat\": 24,\n  \"weekStart\": \"Monday\",\n  \"timeZone\": \"Europe/London\",\n  \"locale\": \"en\",\n  \"bio\": \"Scheduling product consultations\"\n}\n\nThe input schema technically accepts an empty object because every field is\noptional. Do not send an empty update as a probe. Use profile.get for a read,\nand include at least one intentional field in an update.\n\nUpdate fields\n\n| Field | Type and constraint | Meaning |\n\n| email | String with email format | Profile email |\n| name | String | Display name |\n| timeFormat | Integer: 12 or 24 | Clock format |\n| defaultScheduleId | Integer | Default Cal.diy schedule identifier |\n| weekStart | Weekday enum | First day of the displayed week |\n| timeZone | Non-empty string | Profile time-zone identifier |\n| locale | Supported locale enum | Profile interface locale |\n| avatarUrl | String with URI format | Profile avatar URL |\n| bio | String | Profile biography |\n| metadata | Object with bounded scalar values | Provider profile metadata |\n\nAdditional top-level properties are rejected. The schema does not add business\nrules beyond the constraints shown here; provider-side account policy can still\nreject a schema-valid value.\n\nweekStart accepts exactly:\n\nMonday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday\n\nlocale accepts exactly:\n\nar | ca | de | es | eu | he | id | ja | lv | pl | ro | sr | th | vi | az\ncs | el | es-419 | fi | hr | it | km | nl | pt | ru | sv | tr | zh-CN\nbg | da | en | et | fr | hu | iw | ko | no | pt-BR | sk | ta | uk | zh-TW\nbn\n\nThe metadata object accepts at most 50 properties. Each property name has at\nmost 40 characters. Each value must be a string, Boolean, or number; a string\nvalue has at most 500 characters. Nested objects, arrays, and null values are\nnot accepted.\n\nUpdate safety contract\n\n| Contract field | Value |\n\n| Side effects | write, externalnetwork, identity |\n| Human approval | Required |\n| Approval reason class | customervisiblechange |\n| Idempotency | Required; external-account scope |\n| Collision behavior | Revalidate input hash |\n| Connector retry support | No |\n| Retry safety | Unsafe |\n| Data sensitivity | Restricted; contains PII; redaction required |\n| Credential scope | caldiy:profile.update |\n| Expected latency hint | 5,000 ms |\n| Provider timeout | 30,000 ms |\n\nThe approval policy uses the tenant-policy selector and a 900,000 ms validity\nwindow. Approval evidence must include a reason, an input snapshot, and the\npolicy decision. Bind the approval to the exact actor, tenant, capability, and\ninput being executed. A changed field or value requires a new decision.\n\nThe identity side-effect marker is additive: it tells policy that this write\nchanges account identity or presentation data. It does not replace provider\nauthorization or grant permission to change an email address.\n\nIdempotency and settlement\n\nEvery profile update requires an idempotency key. Scope it to the selected\nexternal account and preserve the same key only for the same canonical input.\nReusing a key with different update content is an idempotency collision.\n\nBefore provider dispatch, the connector records a durable claim. A repeated\nmatching request can observe one of three relevant states:\n\n| Durable state | Meaning | Application action |\n\n| Completed | The original result was stored | Accept the stored result |\n| In progress | Another invocation owns the claim | Read durable action state; do not create a new key |\n| Uncertain | Dispatch may have crossed the provider boundary | Reconcile evidence; do not repeat the update |\n\nprofile.update supports dryrun, plan, commit, and reconcile modes. A\nplan is not required before commit, and dry-run fidelity is limited to policy\nand schema checks. A successful dry run does not prove that Cal.diy will accept\nthe update.\n\nThe capability declares no rollback or compensating capability. If a completed\nupdate must be reversed, submit a new, separately approved update using values\nconfirmed from authoritative state. Do not treat that later write as an atomic\nrollback.\n\nResult contract\n\nThe connector returns the validated Cal.diy JSON response as the AIP action\noutput. The common output schema requires a non-empty string status and may\ncontain data, pagination, or additional provider fields:\n\n{\n  \"status\": \"success\",\n  \"data\": {}\n}\n\nThis example demonstrates only the connector envelope. The connector does not\npublish an exhaustive provider profile schema for data. Consumers must\ntolerate additional fields and must not assume a particular data shape.\n\nBefore returning output, the connector recursively replaces values whose\nnormalized field names are secret, apiKey, hashedKey, token,\naccessToken, refreshToken, or clientSecret with [REDACTED]. Profile data\nremains classified as restricted even after this targeted redaction.\n\nAn empty successful provider body is normalized to:\n\n{\n  \"status\": \"success\"\n}\n\nFailures and recovery\n\n| Failure | Typical cause | Safe response |\n\n| connector.caldiy.invalidaction | Input does not match the published operation schema | Correct the input; do not resend unchanged data |\n| connector.caldiy.policy | A mutation lacks its required idempotency key | Supply the missing key while preserving the original governed input |\n| connector.caldiy.idempotencycollision | The key already owns different input | Stop and inspect the original action; never force reuse |\n| connector.caldiy.inflight | A matching mutation is still executing | Read durable state and wait for settlement |\n| connector.caldiy.outcomeunknown | The provider outcome cannot be proved | Reconcile using durable and provider evidence; do not retry |\n| connector.caldiy.authentication | Cal.diy returned 401 or 403 | Verify account binding and credential revision before another call |\n| connector.caldiy.stateconflict | Cal.diy returned 409 or 412 | Refresh authoritative profile state and review the intended change |\n| connector.caldiy.ratelimited | Cal.diy returned 429 | Honor the retry delay only when the action contract permits retry |\n| connector.caldiy.remotetemporary | Cal.diy returned a server error | Retry reads within policy; reconcile mutations |\n| connector.caldiy.remoterejected | Cal.diy rejected another client request | Correct the request or account state before retrying |\n| connector.caldiy.transport | The provider exchange failed | Retry a read within policy; treat a dispatched mutation as uncertain |\n| connector.caldiy.responsetoolarge | The response exceeded the configured bound | Do not bypass the bound casually; inspect provider output and configuration |\n| connector.caldiy.invalidprovideroutput | A successful response lacked a valid non-empty status | Preserve request evidence; reconcile an update before investigating provider drift |\n\nErrors can also include a validated provider request ID and remote status. Keep\nthose values with the AIP action ID and external-account identity during\ndiagnosis. Error details do not contain raw provider response bodies.\n\nFor global lifecycle and gateway errors, use the error reference (../../../reference/errors.md).\n\nVerify an integration\n\nFor a profile read, verify that:\n• discovery returns cap:caldiy:profile.get for the intended account route;\n• the completed result belongs to the submitted action ID;\n• the output has a non-empty status;\n• returned PII is handled under the tenant's restricted-data policy.\n\nFor a profile update, additionally verify that:\n• the approval evidence binds the exact update input;\n• the external-account idempotency key is retained with the action record;\n• the durable result is completed before relying on the new profile value;\n• a follow-up read confirms the intended fields without exposing unrelated PII;\n• an uncertain result is reconciled instead of repeated.\n\nThese checks validate application handling. They do not establish live-provider\nqualification or production readiness for a particular deployment.\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": "4085a0cade4067780b985462599db9d6d802390f56d1a028f5e1f21233f79312"
  }
}
