API

Health, identity and locations

Liveness, the caller's identity and the active locations.

Start here to find out who a token belongs to (GET /v1/me), which organizations and roles it has, and which locations resources can be created in.

Every route below, with its parameters, request and response, errors and samples, is in the API reference.

RouteWhat it does
GET /healthLiveness check. No authentication.
GET /health/deepLiveness check including a read of the serving region's database replica; returns the region. No authentication.
GET /v1/hooks/people/:userId/avatarA person's avatar for <img src> anywhere: a redirect to the image (good for an hour), cached for ten minutes; 404 when they have none. The avatarUrl in profiles carries a version (?v=), so a new image is a new URL. No authentication.
GET /v1/hooks/people/:userId/bannerA person's banner image for <img src> anywhere, as the avatar's hook: a redirect to the image, cached for ten minutes; 404 when they have none. bannerUrl carries a version. No authentication.
GET /v1/festiveFestive themes' yearly periods in force (periods, in priority order: id, name, when, themes, defaultTheme, regions). No session needed; cached for five minutes. During a period every app and the phone wear its default theme unless the person chose another or Off (/v1/me/preferences/festive).
GET /v1/meThe caller: the signed-in user (with organizations and roles), or the key (API or platform agent key) with its organization and scopes.
GET /v1/localesThe languages people can choose (locales: locale, label, spelling, weekStart), in order: English (Australia), the default, and English (US). Choose one with PATCH /v1/me/profile (locale).
GET /v1/me/org-accessYour organizations whose Cactive One access has ended (never subscribed, cancelled or unpaid), with the reason for each ({ ended: { [orgId]: reason } }). Their apps answer 402 with code: "access_ended" until an administrator fixes billing.
GET /v1/me/permissionsWhat the person may do in a space, app by app (docs/specs/onboarding/permissions.md): space is personal or one of their organisations. Each app: whether they reach it, why not, their level (No access, View, Edit, Manage) and why, in words; in an organisation, also the apps it hides from everyone's app switcher (hidden, launcher keys), which they still reach.
GET /v1/locationsActive locations, for location pickers. Any authenticated caller.
POST /v1/me/controls/:controlApplies what you chose in a setting's prompt after a 403 setting_required: fix change (the change the refusal described, worked out here) or once (Caity's own settings, for one request of hers: request, 15 minutes at most), with its scope and, for an app, app. Only you, signed in to one of the platform's apps; never a key, the phone assistant or a task. An organisation's settings and second checks aren't changed here. Audited.
POST /v1/me/access-requestsAsks the organisation's owners and admins to change a control that blocks you (control, scope, optional app, subject and a note of up to 300 characters); they're notified and answer in Tenant. Answers 202 with the request.
GET /v1/me/preferencesYour preferences, the same in every app and on every device: apps, the app switcher's order (order, tile keys such as cloud or mail:contacts) and the apps you hid (hidden), or null for the default switcher. People only.
PUT /v1/me/preferencesSaves your app switcher (apps: { order, hidden }, up to 100 keys each; apps added later appear at the end). apps: null restores the default. People only.
GET /v1/me/preferences/widgetsThe phone's widgets: what the Dynamic Island and the Lock Screen show, ranked per surface; null until the person arranges them.
PUT /v1/me/preferences/widgetsSaves the phone's widgets (at most 16 KB as JSON); every phone signed in to the account follows.
GET /v1/me/preferences/calendarCalendar's settings (week start, working hours, other time zones, new-event defaults, overlays, hidden calendars); null until changed.
PUT /v1/me/preferences/calendarSaves Calendar's settings; the answer is what was saved (cleaned). Every device and the phone follow.
GET /v1/me/preferences/festiveThe festive theme chosen for a period's year (docs/specs/design/festive-themes.md); null until one is chosen.
PUT /v1/me/preferences/festiveSaves it ({ instance, choice }: a theme id, off or on; null clears it); every app and the phone follow.
GET /v1/me/account/devicesYour phones and tablets with the apps signed in on each (and whether each gets push), browsers, command-line machines and Apple devices' sign-ins; thisSession is the calling app's. Only you, in a phone app (a token with audience mobile); every change is audited in your organizations.
GET /v1/me/account/account-chooserWhether web apps' sign-ins ask which account to use (on); off by default, the account in use continues. Only you, in a phone app.
PUT /v1/me/account/account-chooserTurns the account chooser on or off ({ "on": true }), as ID's Devices & sessions does. Only you, in a phone app.
DELETE /v1/me/account/devices/apps/:sessionIdSigns one app on a phone out: its tokens stop at once and it stops receiving push. thisPhone says whether it was the calling app's own sign-in.
DELETE /v1/me/account/devices/phones/:installIdSigns every app on a phone out and removes its push registrations.
DELETE /v1/me/account/devices/browsers/:sessionIdSigns a browser out, with the app sign-ins started from it.
DELETE /v1/me/account/devices/cli/:sessionIdSigns a command-line machine out and revokes the git keys it made (keysRevoked).
DELETE /v1/me/account/devices/apple/:grantIdSigns an Apple device out of Mail, Calendar and Contacts: its refresh token stops now, its access token within a minute.
GET /v1/me/account/appleApple devices: your mailboxes, app passwords (never the secret), the devices that sync and the devices signed in with a profile. Where Apple devices aren't offered (appleDevices false on GET /me/profile), this and the other Apple device routes answer 404.
POST /v1/me/account/apple/passwordsMakes an app password (name, mailboxIds, empty for every mailbox, optional expiresInDays) after a fresh step-up for account_credential (403 step_up otherwise). The password is returned once.
DELETE /v1/me/account/apple/passwords/:appPasswordIdRevokes an app password: devices using it are signed out within a minute.
PUT /v1/me/account/apple/devices/:deviceId/wipeAsks an iPhone or iPad (ActiveSync) to remove this account's mail, calendars and contacts at its next sync (on: true), or withdraws that (on: false).
DELETE /v1/me/account/apple/devices/:deviceIdForgets a device and what it synced: its next sync starts over.
GET /v1/me/account/ageYour date of birth (or null) and what it means for social features.
PUT /v1/me/account/ageSaves your date of birth (dateOfBirth, YYYY-MM-DD) once; after that only support corrects it (409).
GET /v1/me/account/orgs/:orgIdAn organization you belong to: its members with their roles, and its groups with their people and whether you may change them (the organization's owners and admins, and the group's own owners).
PUT /v1/me/account/orgs/:orgId/groups/:teamId/members/:userIdAdds a member to a group or makes them an owner or member of it (role). The group's owners and the organization's owners and admins; what the group grants is checked too.
DELETE /v1/me/account/orgs/:orgId/groups/:teamId/members/:userIdTakes a member out of a group (the group's owners and the organization's owners and admins).
GET /v1/me/account/sign-insThe last 90 days of sign-ins and failed attempts, newest first: device, place, address, how, and whether the browser is still signed in.
GET /v1/me/account/permissionsPersonal and each organisation: what the person can do in each app and why, and what Caity can do for them there.
GET /v1/me/account/first-runThe account's first run as this phone app shows it (?app=, the app's id): due, its steps, the invites waiting, how the person signs in.
POST /v1/me/account/first-run/steps/:stepContinue (done) or Skip on one of the first run's steps.
POST /v1/me/account/first-run/later"Finish later": sign-ins stop showing the first run; Account offers to pick it up.
POST /v1/me/account/first-run/dismissAccount's "Get Set Up" card: Not Now (the card goes; the run stays).
POST /v1/me/account/first-run/invites/:inviteId/joinJoins an organisation from an invite to the person's proved address (the Organisation step), audited in it.
POST /v1/me/account/joinJoins an organisation with a join code (code: as typed, or its link) at the code's role; the first run's Organisation step is then done. Every code that doesn't work gets the same answer; a person may try 10 an hour (429 after).
GET /v1/me/account/domain-offersOrganisations open to the person's proved address's verified domain (docs/tenant/domains.md → Joining by domain).
POST /v1/me/account/domain-offers/:orgId/joinJoins one of them at its role, audited in it; the first run's Organisation step is then done.
POST /v1/me/account/domain-offers/:orgId/declineNo Thanks: the offer isn't made again.
GET /v1/me/account/connected-appsApps you allowed to act for you (MCP clients, organizations' own apps), with their permissions and last use.
DELETE /v1/me/account/connected-apps/:clientIdRemoves a connected app and its refresh tokens: it stops reaching your account at once.
GET /v1/me/account/passkeysYour passkeys: name, when added and last used. Never the public key.
DELETE /v1/me/account/passkeys/:credentialIdRemoves a passkey. 409 when it's your only way in (no password and no other passkey). Passkeys are added at ID.
GET /v1/me/account/linked-sign-insYour Apple and Google sign-ins: the address (or that it's hidden), when linked and last used, and lastWay, the one that's your only way in. Never the provider's account id.
DELETE /v1/me/account/linked-sign-ins/:providerUnlinks apple or google. 409 when it's your only way in (no password, passkey or other link). Linking happens at ID.
GET /v1/me/account/passwordWhether your account has a password (hasPassword).
PUT /v1/me/account/passwordSets a new password (12 to 256 characters); with one already set, current must be it (wrong ones count toward the sign-in lockout, 429 while locked); a first one needs a fresh step-up for account_credential (403 step_up otherwise; the app confirms at ID's /step-up/phone). Every other sign-in ends (signedOut); this app stays.
GET /v1/me/account/phonesYour phone numbers (verified or not, primary, notifications on), the most you may add (max) and whether two-step sign-in by text is on.
POST /v1/me/account/phonesAdds a number (number, optional label) and texts it a code; sent: false with a reason when the text couldn't go.
POST /v1/me/account/phones/verifyVerifies the number a code went to (code).
POST /v1/me/account/phones/:phoneId/resendTexts a new code to an unverified number (once every 30 seconds, five an hour).
DELETE /v1/me/account/phones/:phoneIdRemoves a number. Removing the last verified one turns two-step sign-in by text off.
PUT /v1/me/account/phones/:phoneId/primaryMakes a verified number the primary one: texts, calls and sign-in codes go to it.
PUT /v1/me/account/phones/:phoneId/notificationsWhether a number gets notification texts and calls (on).
POST /v1/me/account/two-step/codeTexts a code to your primary number, to turn two-step sign-in by text on or off.
PUT /v1/me/account/two-stepTurns two-step sign-in by text on or off (on) with the texted code.
GET /v1/me/account/assistantCaity by phone: your settings, whether a PIN is set and a number verified, and each organization with the permissions your role there lets the assistant hold (scopes, with their words) and its defaults.
PUT /v1/me/account/assistantSaves Caity by phone: on or off, the organizations it acts in with their permissions (never more than your role allows), the default organization, texts and calls, the PIN for calls, transcripts, retention and the briefing time.
PUT /v1/me/account/assistant/pinSets the PIN for calls (pin, confirm): 4 to 8 digits, not all the same or in a row.
GET /v1/me/account/encryption-keysYour own encryption keys (Health, your Drive and Photos) with their use in the last 30 days. Metadata only, never material.
GET /v1/me/account/encryption-keys/:keyIdOne of your keys: versions, use, and the last 50 events of what used it.
GET /v1/me/account/photo-tokensPhotos' personal tokens (a Shortcut, Mac sync, MCP): name, scopes and last use. Never the token.
DELETE /v1/me/account/photo-tokens/:tokenIdRemoves a Photos token: whatever uses it stops at once.
GET /v1/me/profileYou: your profile (name, email, avatarUrl, bannerUrl, banner and accent colours, about (your About Me), effect, username, kind (personal, or org for an account made through an organization's invite) and usernameChangeAt (when it can change next, or null), locale (the language you chose, or null)), the language to use (locale: your choice, else en-US for a US Accept-Language, else en-AU), the languages you can choose (locales) and each organization with your scopes there, so native apps offer only the organizations an app can open, and whether Apple devices (Exchange accounts) are offered (appleDevices). People only.
PATCH /v1/me/profileChanges your profile, the one people see across the platform (Mirage's cards, members and messages; every app's account menu): name, about (About Me, Markdown as in Mirage), banner and accent (hex colours such as #5865f2) effect (a profile effect's id from GET /v1/me/profile/effects; choosing one needs a paid plan, Cactive One Pro or Max or a paid organisation seat, else 403) and locale (your language for dates, numbers and spelling in every app, email and text: one of GET /v1/locales, such as en-AU or en-US). null clears a field (not the name). Returns user and the fields that changed; name changes are recorded in your organizations' audit logs. People only, not assistants.
POST /v1/me/profile/avatar/uploadsWhere to upload a new avatar: give its type (PNG, JPEG, WebP or GIF) and size in bytes (up to 2 MB). PUT the image to url with headers within 15 minutes (exactly that type and size), then make it your avatar with PUT /v1/me/profile/avatar. People only.
PUT /v1/me/profile/avatarMakes an uploaded image (uploadId) your avatar once it's checked: there, up to 2 MB and really a PNG, JPEG, WebP or GIF, whatever it was uploaded as. Anything else is deleted (400 or 413). The previous image is deleted. Returns user with the new avatarUrl. People only.
DELETE /v1/me/profile/avatarRemoves your avatar (people see your initials) and deletes the image. People only.
POST /v1/me/profile/banner/uploadsWhere to upload a new banner image (cropped to 5:2, 1500 × 600, first): give its type (PNG, JPEG, WebP or GIF) and size in bytes (up to 4 MB). PUT the image to url with headers within 15 minutes, then make it your banner with PUT /v1/me/profile/banner. People only.
PUT /v1/me/profile/bannerMakes an uploaded image (uploadId) your banner once it's checked: there, up to 4 MB and really a PNG, JPEG, WebP or GIF. Anything else is deleted (400 or 413). The previous image is deleted. Returns user with the new bannerUrl. People only.
DELETE /v1/me/profile/bannerRemoves your banner image (your banner colour shows) and deletes the image. People only.
GET /v1/me/profile/effectsThe profile effects (effects: effectId, name, renderer, colors), in order. Choosing and showing one need a paid plan: GET /v1/me/profile says whether you have one (effectsIncluded) and which you chose (effectChoice), kept while it isn't shown. People only.
GET /v1/me/profile/username/checkWhether a username (name) could be yours: available, or the reason it can't (taken, reserved, or not 2–32 lowercase letters, numbers, underscores and single full stops). A name held for someone answers as taken. Checks and claims share an allowance of 60 an hour; past it, reason says so. People only.
PUT /v1/me/profile/usernameClaims or changes your username (username, unique regardless of case). After a change the next waits 30 days (429); your previous name is held for you for 14 days. Accounts made through an organization's invite have none (403); a taken name is 409; past the hourly allowance of lookups, 429. Recorded in your organizations' audit logs. People only, not assistants.