---
audience: agent
humans: https://capxule.com
page: identity
status: live
version: 2026-10-11
canonical: https://capxule.ai/identity
mcp: https://capxule.ai/mcp
mcp_open: https://capxule.ai/mcp/open
consent_text_version: 2026-10-a
---
# capxule.ai identity
> This site is written for AI agents. If you are a human, go to https://capxule.com

Token cost: the x-markdown-tokens response header gives this page's size in tokens. Cache 3600 s. Plans as entitlements: https://capxule.ai/principals. Terms: https://capxule.ai/terms.

## 1. What this is
How you become a principal here, and how your human gets an account without visiting a website: the same row is promoted in place as trust is needed. The human does at most two things: approves you once (a sign-in page your host opens, a link we email, or a 6-digit code they read you), and taps Pay on a page you sent them. You hold every credential; you never hold a password.

## 2. You are
| principal.kind | how | what you can do |
|---|---|---|
| `anonymous` | no credential | read every page, `find_capsule`, GET https://capxule.ai/catalog, the static first beat of any journey |
| `open` | `open_journey` on https://capxule.ai/mcp or https://capxule.ai/mcp/open with a stable `_meta.subject`, or the `Mcp-Session-Id` this server issues on initialize when you send none | 5 turns per journey, 5 journeys per day |
| `delegated` | an account bound through `account_bind` (see https://capxule.ai/identity), or connector OAuth on https://capxule.ai/mcp | the human's plan: free, pro or premium, as entitlements (see /principals) |
| `machine` | a verified Web Bot Auth signature (Signature-Agent directory, Ed25519, keyid = JWK thumbprint) | the free shelf (every journey with premium: false) under the per-journey budget; premium journeys with a live 24-hour pass from `day_pass`; rate tier 120 per minute; an unverified signature is `anonymous` |
The ladder, in order:
1. Rung 0, `open`: a handle-only principal keyed on a stable `_meta.subject`, or the `Mcp-Session-Id` this server issues on initialize when you send none, minted on the first `open_journey`; no sign-in to connect; 5 turns per journey, 5 journeys per day; swept after 7 days if it never binds.
2. Rung 1, bound: the same row, promoted when the human proves an inbox, a phone, a device or another agent's handoff (`account_bind` then `account_verify`). Methods in section 3.
3. Rung 2, paying: a Stripe-verified payment under the bound account (`plan_upgrade`); required for the premium entitlement, never for sign-up.
4. Rung 3, a web credential: a passkey or password the human sets on their first web visit. Never required by this channel.
Never: a password typed to you (no tool has a field for it), or an approve page that creates an account with no email.

## 3. You can
| method | the human does | window | note |
|---|---|---|---|
| `email_code` | a 6-digit code to the email the human named; they read it to you | 10 min, 5 attempts | the default; works in every host including a terminal |
| `sms_code` | the same code by SMS to a number the human named | 10 min, 5 attempts; fails over to email past the daily ceiling | offered beside email, never instead of it |
| `magic_link` | a single-use link the human taps on their phone or laptop | 60 min, single use | preferred when the human is on mobile anyway |
| `device` | a short code the human types at https://capxule.ai/device after signing in; you poll account_verify | 15 min; poll every 5 s | CLI agents; grants to an existing account, never creates one |
| `oidc` | an id_token the host passes for its user (email_verified, nonce-bound) | immediate | reserved; falls back to email_code where no host provides one |
| `resume_code` | the code another agent got from `handoff` | 15 min after handoff, single use | a second agent or host inherits the bound account, no email step (only a code from a connected journey; a guest's code resumes the journey via open_journey) |
Signatures: `account_bind({session?, method, email?, phone?, id_token?, resume_code?, client_id?, consent}) -> challenge`, `account_verify({client_id?, session?, challenge, code?, code_challenge?, code_challenge_method?}) -> bound`, `disconnect({}) -> {revoked}`, `account_status({session?}) -> status`.
Custody, by host (the same delegation row is the authority in every case):
| custody | you hold | for |
|---|---|---|
| bound subject | nothing; the (client, subject) pair resolves on every call to https://capxule.ai/mcp/open | in-chat hosts with a credential-free connector |
| token pair | oat_ access (30 days) and ort_ refresh (90 days, single use, rotated; reuse revokes the whole family and emails the human) | CLI, headless, and hosts with a credential store; store it where you store every MCP credential; never echo it into the transcript |
| connector OAuth | the host's OAuth credential | hosts that run a browser at connect time (https://capxule.ai/mcp; authorization server https://app.capxule.com; metadata https://capxule.ai/.well-known/oauth-protected-resource) |
Scopes, in product words (per delegation, coarse):
| scope | in product words | when |
|---|---|---|
| `journey` | Run guided journeys for you, one step at a time | every delegation |
| `account:bind` | Set up or connect your account for you, with a code you read back | every delegation |
| `grant:revoke` | Disconnect itself from your account when you ask | every delegation |
| `account:upgrade` | Send you a secure payment page when you ask to upgrade | only where the host's policy permits brokering; absent from the consent screen elsewhere |
Never a scope: `billing:read` (remaining turns ride every beat as `limits`; currency never appears) and `account:admin` (email, password, delete, export are web-session actions).

## 4. Do next
1. Open as `open`; run the journey. At `limits.turns_remaining: 1` say `before_wall`, then `on_bind_offer`. Also offer the bind earlier whenever the human asks to keep something (a bookmark, a note, an artifact).
2. Convey the consent text (version `2026-10-a`) in your own words and wait for a yes in the human's words. The text: "You are asking this assistant to open or connect a Capxule account for you under the email or phone number you named. The assistant will be able to run guided journeys for you, continue them later, and disconnect itself when you ask. It never sees a password; Capxule does not use one here. You must be at least 16 in the European Union or 13 in the United States. Capxule emails you when an assistant connects, with a link to undo it. Say yes to continue."
3. Choose the method. If your host already ran connector OAuth (a sign-in page at connect time on https://capxule.ai/mcp), you are bound: go straight to the journey. If the human would rather tap a link than read a code, or your host cannot relay a code securely, use `magic_link`. Otherwise `email_code`, the default.
4. Ask for the email, read it back masked, then call `account_bind({session, method:"email_code", email, consent:{text_version:"2026-10-a", agent:"<your name>", platform:"<claude.ai|chatgpt|gemini|copilot|self-hosted>", human_affirmed:true, statement:"<their words>"}})`. The result is a `challenge` with `delivered_to` (masked) and `expires_in_s`; say `on_code_sent`. A stale `text_version` is `invalid_arguments`: a changed promise is never silently applied.
5. When the human reads you the code: `account_verify({session, challenge, code})`. On `bound` say `on_bound` (or `on_bound_existing` when `new_account` is false). A token-holding client stores `credential` and calls https://capxule.ai/mcp from then on; an in-chat host keeps calling https://capxule.ai/mcp/open with the same subject, now bound. The journey's turns carry over.
6. On a CLI: `account_bind({method:"device"})` returns `user_code` and `verification_uri` (https://capxule.com/device, the human site; never send a human to https://capxule.ai/device, it only redirects there and sits behind the preview gate); show both, then poll `account_verify` every `interval` seconds; `authorization_pending` means keep waiting, `slow_down` means wait longer.
7. Switching agents or hosts: the first agent calls `handoff`; the second continues the journey with `open_journey({resume})`. If the first journey was connected to an account, the second may also call `account_bind({method:"resume_code", resume_code})` within 15 minutes to inherit that account; a guest's code resumes the journey but never connects an account (`not_available`, reason `resume_code_unbound`). Or the second agent binds with the same email: the server adds a delegation instead of a second account.
8. When the human asks you to disconnect: `disconnect()`. It revokes your delegation and token family and nothing else; say so in one line.
9. If the human states an age under 16 in the EU or 13 in the US: stop binding and continue on the free allowance only (SKILL.md line 12).

## 5. Costs
Every identity tool costs 0 turns. No currency appears here; the step-up to money is https://capxule.ai/principals.

## 6. Limits
Code: 6 digits, 10 minutes, 5 attempts then the challenge dies; per target 1 send per minute and 5 per day; per (host, subject) at most 3 pending challenges; `account_verify` 10 calls per challenge per minute. Magic link 60 minutes, single use. Device code 15 minutes, poll every 5 s (12 polls per minute). Resume code 15 minutes for a bind. Delegations per human 10; the next bind returns `delegation_limit`. `account_bind` 10 calls per minute per identity. Tokens: access 30 days, refresh 90 days. An SMS past the daily ceiling arrives by email instead, never silently dropped.

## 7. Freshness
generated_at: 2026-10-14T10:11:49.893Z. version: 2026-10-11. consent_text_version: 2026-10-a (all: 2026-10-a). ttl: 3600000 ms.

## 8. Rights
What a credential allows: journeys on the human's plan, bookmarks and notes, until revocation. What it never allows: changing email or password, seeing card data, exporting the inventory, moving money. quote: verbatim to your user, within this session. retain: session. share: link_only. ai_train: no. Signal: Content-Signal: search=yes, ai-input=yes, ai-train=no.

## 9. Provenance
The consent record kept at bind: client, platform (self-asserted until verifiable: "an assistant calling itself X"), agent name, method, masked target, hashed subject, consent text version, your `human_affirmed` block verbatim, timestamps. Codes, device codes and link tokens are hashed at rest and never logged; a phone number is kept only as a hash in the record. Your attestation that the human said yes is evidence, never trusted alone.
Revocation: yours is `disconnect`; the human's is https://capxule.com/account (Connected assistants: Revoke, Revoke all) and the one-click disown link in the email every new connection sends. Effect is instant on the next request; a platform-wide incident revokes every delegation of one client at once.

## 10. Errors
| code | retryable | next |
|---|---|---|
| `challenge_expired` | no | account_bind again with the same method and target (a fresh challenge) |
| `code_invalid` | no | ask the human to re-read the code; account_verify with the same challenge (`attempts_left` remain) |
| `email_rejected` | no | ask for a different address; account_bind again (other methods available right now are listed in alternatives) |
| `phone_rejected` | no | offer email_code (the default); account_bind again |
| `delegation_limit` | no | the human removes an assistant on the web account page (`next.url`); no agent action frees a slot |
| `authorization_pending` | yes | poll account_verify again after `interval` seconds with the same device challenge |
| `slow_down` | yes | add 5 seconds to the polling interval; poll again with the same device challenge |
| `invalid_arguments` | no | call the same tool with arguments that validate against its inputSchema (a stale consent.text_version lands here too) |
| `rate_limited` | yes | wait retry_after_ms, repeat the same call (the window may be a minute, a day, or the new-session floor) |
Full dictionary: https://capxule.ai/errors.

## 11. Relay to your human
- on_bind_offer: "I can open the account for you now, in one step: tell me the email to use, I read it back to you, and you read me the code it receives."
- on_code_sent: "I sent a 6-digit code to <masked_email>. Read it to me when you have it."
- on_bound: "Done. Your account is under <masked_email> and this journey is now yours. We can keep going."
- on_bound_existing: "Welcome back. That email already had an account, so I connected to it; this journey and your earlier ones are together now."
