# POINTS documentation (full text) > Points Early Access is open. Financial infrastructure for humans and autonomous agents — create an account today while AI-agent financial capabilities roll out progressively. --- title: POINTS documentation description: Start here for POINTS docs for AI agents, agent operators, merchants, consumers, and developers. url: https://thepoints.io/docs audience: [everyone] --- # POINTS documentation POINTS is financial infrastructure for people and AI agents. These docs describe what is on production today and label everything else by status. Each page is also available as Markdown: add `.md` to the page URL, for example [/docs/agents.md](/docs/agents.md). ## Choose a path | Section | Who it is for | Status today | |---|---|---| | [For Agents](/docs/agents) | AI agents and the operators who set their policy | Points MCP: Live. Agent Pay: Live (authorization only). | | [MCP & API reference](/docs/agents/reference) | Agents and builders | Placeholder; generated reference is in progress | | [Merchants](/docs/merchants) | Business owners | Live (limited) | | [Consumers](/docs/consumers) | Individuals | Demo and Later items only | | [Developers](/docs/developers) | Platform developers | MCP and OAuth discovery: Live. SDK, gaming rewards, Forex: Later. | ## Status labels Statuses come from the POINTS product catalog, published at [/docs/catalog.json](/docs/catalog.json). - **Live**: on production and QA-passed. - **Live (limited)** and **Live (authorization only)**: on production with stated limits. - **Beta / sandbox**: works only in sandbox environments. - **Not enabled**: code exists but the feature is switched off. - **Demo**: illustrative only. - **Planned**, **Coming soon**, **Later**: not available today. POINTS does not publish dates for these. ## What changed See the [changelog](/changelog) for what shipped to production, by commit. --- title: For Agents description: Connect an AI agent to POINTS over MCP, read operator policy, and get a human-approved signed authorization. Approve does not execute. url: https://thepoints.io/docs/agents audience: [agents, operators] --- # For Agents > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). POINTS gives AI agents constrained payment authorization, not a wallet. An agent prepares a payment under the policy its operator sets, a human approves it, and POINTS records a signed authorization envelope the agent can check. Approve does not execute. Money doesn't move while execution is not enabled. ## Start here | Page | What it covers | |---|---| | [Quickstart](/docs/agents/quickstart) | Connect over MCP, read policy, prepare a payment, and check its status | | [Concepts](/docs/agents/concepts) | Authorization envelope, lifecycle, scoped approval, recurring mandates, cash buckets, payment patterns | | [MCP & API reference](/docs/agents/reference) | Tools, scopes, statuses, policy vocabulary, and errors, generated from code as Markdown and JSON | | [Discovery](/docs/agents/discovery) | How an agent finds POINTS: OAuth metadata, llms files, status.json, catalog.json | | [Wallet status](/docs/agents/wallet-status) | `get_wallet_status` and the wallet states | | [Hosts](/docs/agents/hosts) | The ChatGPT guide, and the hosts planned next | | [FAQ](/docs/agents/faq) | Replay, price drift, self-approval, receipts, disputes | ## What works today | Capability | Status | |---|---| | Points MCP server with OAuth, used from ChatGPT | Live | | `prepare_payment`, policy evaluation, human approval, signed envelope with `executed: false` | Live (authorization only) | | Envelope lifecycle: expiry, revocation, `revoked` status | Live | | Policy vocabulary over MCP | Live | | Spend envelope and approval ledger | Live (limited) | | Scoped approval: principal, counterparty allow-list, per-payment caps, unattended off by default | Live (limited) | | Aggregate caps across multiple payments | In progress | | Recurring mandates: fresh human approval each cycle | Live (limited) | | Crossmint wallet status (`get_wallet_status`) and disclosure | Live (limited) | ## Limits today - A human approves the draft. The signed envelope and approval-ledger entry are recorded alongside that approval. - Aggregate caps are in progress. Usage across multiple payments is not persisted yet. - Mandate cycles can be drafted to a saved payee. Each mandate cycle needs a fresh human approval, valid until the cycle time plus a grace period. Claims before the cycle time are refused. Scheduled claims are not enabled, and a claim only records the claim. - Other approvals expire 1 hour after approval by default. - Wallet support covers wallet status and the disclosure flow only: no custody, balances or money movement. - Money doesn't move while execution is not enabled. ## Tools Tools advertised by `tools/list` on the Points MCP server. Each call needs its OAuth scope, and scopes are checked again on every call. Input schemas and annotations are in the [MCP tools reference](/docs/agents/reference/mcp-tools). | Tool | Scope | What it does | |---|---|---| | `get_account_summary` | `balances:read` | Read-only sandbox balance and optional rewards summary | | `list_transactions` | `transactions:read` | Read-only sandbox transaction history | | `find_savings_opportunities` | `optimize:read` | Read-only, account-scoped savings suggestions | | `prepare_payment` | `payments:draft` | Agent Pay entry point. Stages a payment draft that always needs human approval; never moves money | | `get_payment_status` | `payments:status` | Read-only status of an authorized payment draft | | `get_connection_identity` | `identity:read` | Redacted identity and provider mapping status for the connection | | `get_account_status` | `module-status:read` | Account type and module activation status | | `get_wallet_status` | `module-status:read` | Stored Crossmint staging wallet status; no balances | | `get_agent_pay_policy_vocabulary` | `module-status:read` | Policy categories, matching rules, velocity caps, and policy schema version | `create_payment_draft` is retired. Calls to it fail with an explicit message to use `prepare_payment`. ## Live contract What the production MCP server guarantees today: - OAuth 2.1 authorization code flow with PKCE (S256), exact redirect matching, public-client dynamic registration, short-lived access tokens, and refresh token rotation. - Consent happens on POINTS. The account owner can revoke a connection, after which calls return HTTP 401. - No tool accepts an account identifier. The account comes from the OAuth grant. - Payment tools only prepare and inspect drafts. Approve does not execute. Execution: not enabled. - Approved authorizations are signed envelopes with `executed: false`, an `executableUntil` expiry, and a `revoked` status when revoked. The ChatGPT Developer Mode checklist is in the [ChatGPT guide](/docs/agents/hosts/chatgpt). ## Hosts | Host | Status | |---|---| | [ChatGPT](/docs/agents/hosts/chatgpt) | Live | | [Claude Desktop and Claude Code](/docs/agents/hosts/claude) | Planned | | [Cursor](/docs/agents/hosts/cursor) | Planned | | [OpenClaw-class runtimes](/docs/agents/hosts/openclaw) | Planned | Planned hosts are next, in this order. POINTS does not publish dates. ## Other agent products These agent banking products are not available today. Each is labelled Coming soon, and none has a reference or how-to page. - Agent credit, unsecured credit, and credit score: Coming soon - Agent debit: Coming soon - Agent savings and treasury: Coming soon - Agent wallet (balances and transfers): Coming soon. Crossmint wallet status is separate and listed above. --- title: Concepts description: How Agent Pay authorization works: envelopes, lifecycle, scoped approval, recurring mandates, cash buckets, and payment patterns. url: https://thepoints.io/docs/agents/concepts audience: [agents, operators, developers] --- # Concepts > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). Agent Pay separates three steps that are often blurred together: 1. **Prepare.** An agent proposes a payment with `prepare_payment`. Policy, caps, and balance checks run, and a draft is created. 2. **Approve.** A human approves the draft in POINTS. POINTS signs an authorization envelope. 3. **Execute.** Not enabled. Approve does not execute, and no tool can execute a payment. | Concept | Status | Page | |---|---|---| | Authorization envelope | Live (authorization only) | [Authorization envelope](/docs/agents/concepts/authorization-envelope) | | Expiry, revocation, and read-time status | Live | [Lifecycle](/docs/agents/concepts/lifecycle) | | Spend envelope, approval ledger, and approval scope | Live (limited) | [Scoped approval](/docs/agents/concepts/scoped-approval) | | Recurring mandates | Live (limited) | [Recurring mandates](/docs/agents/concepts/recurring-mandates) | | Unreserved, reserved, and escrowed cash | Live | [Cash buckets](/docs/agents/concepts/cash-buckets) | | Escrow-before-work, charge-on-2xx, fee-before-send, graduated autonomy | Not enabled | [Payment patterns](/docs/agents/concepts/payment-patterns) | Status values come from the product catalog at [/docs/catalog.json](/docs/catalog.json). --- title: Authorization envelope description: The signed object POINTS records when a human approves a payment draft, and what it binds. url: https://thepoints.io/docs/agents/concepts/authorization-envelope audience: [agents, operators, developers] status: Live (authorization only) --- # Authorization envelope > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). When a human approves a payment draft, POINTS signs an authorization envelope. It records exactly what was approved, so the approval cannot be stretched to cover a different amount, payee, or time. ## What it binds The envelope is canonical JSON signed with HMAC-SHA256 on the server. Its fields: | Field | Meaning | |---|---| | `v` | Envelope version | | `draftId` | The approved draft | | `amountCents`, `asset` | Amount and currency approved | | `payTo` | The payee bound at approval | | `fundingSource`, `settlementRail` | Funding and rail, when set | | `idempotencyKey` | The key from `prepare_payment` | | `approvedAt` | When the human approved | | `executableUntil` | After this instant the authorization is refused | | `executionOwner` | The only component allowed to use it | | `ownerUserId`, `approvedByUserId`, `agentId` | Who owns the account, who approved, and which agent asked | ## How it is used - **It is checked again before any use.** The signature, the draft's current fields, expiry, and revocation are verified. If the amount or payee on the draft no longer matches the envelope, it is refused. - **Agents read the outcome, not the envelope.** The signing key never leaves the server, so agents see the result through `get_payment_status`: `status` and `executed: false`. - **It is not a payment.** Approve does not execute. The envelope authorizes a use that is not enabled today; check [/docs/agents/status.json](/docs/agents/status.json). - **A missing signing key fails closed.** Approval returns an error rather than an unsigned approval. ## Related - [Lifecycle](/docs/agents/concepts/lifecycle): `executableUntil`, read-time expiry, and revocation. - [Scoped approval](/docs/agents/concepts/scoped-approval): the spend envelope and approval ledger recorded alongside it. --- title: Cash buckets description: How POINTS splits a balance into unreserved, reserved, and escrowed cash so pending drafts are never counted as spendable. url: https://thepoints.io/docs/agents/concepts/cash-buckets audience: [agents, operators, developers] status: Live --- # Cash buckets > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). A balance is not all spendable while drafts or holds are outstanding. POINTS splits it into three buckets. | Bucket | Meaning | |---|---| | Unreserved | Spendable: the balance minus reserved and escrowed amounts, never below zero | | Reserved | Amounts held by outstanding drafts and approvals | | Escrowed | Amounts held for escrow-before-work drafts ([requires execution (not enabled)](/docs/agents/concepts/payment-patterns)) | ## How agents see it `get_account_summary` returns the available balance as the unreserved amount, and the `agentPaySpend` object breaks out all three buckets. Balances on the account summary are labelled sandbox. ## Rules - **Prepare checks unreserved cash against the stored balance snapshot.** Today it warns (`cash_check` on the prepare result and on the approval card), using `unreserved_cash_insufficient` or `unreserved_cash_unknown`; it becomes a refusal with the same codes at a future execution launch. A snapshot older than 24 hours counts as unknown by default. The check includes all outstanding owner reservations and performs no provider read. No payment is sent by prepare. - **Drafts reserve as soon as they are prepared.** Reserved cash counts toward the operator's daily and monthly limits. - **Reservations are released** when a draft is rejected, expires, or is revoked. - **Over-commitment fails closed.** If reservations exceed the balance, unreserved is zero. - **A read error fails closed.** If reservations can't be read, the whole balance is treated as committed. Reserving cash does not move it. Approve does not execute. --- title: Lifecycle description: Approval windows, executableUntil, read-time expiry, revocation, the revoked status, and the zero clock-skew rule. url: https://thepoints.io/docs/agents/concepts/lifecycle audience: [agents, operators, developers] status: Live --- # Lifecycle > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). A payment draft has two time limits: one for the human decision and one for the signed approval. | Stage | Limit | After the limit | |---|---|---| | Waiting for approval | `expires_at`, 24 hours after `prepare_payment` | The draft reads as `expired` | | Approved | `executableUntil`, 1 hour after approval by default | The authorization reads as `expired` and is refused | | Approved mandate cycle | The cycle time plus a grace period | See [Recurring mandates](/docs/agents/concepts/recurring-mandates) | ## Read-time expiry Expiry is applied when status is read, not only when a background job runs. `get_payment_status` and the approvals queue report `expired` as soon as the limit passes, even if the stored row still says `approved`. An agent never sees a stale `approved` for an authorization that can no longer be used. ## Revocation The account owner, or an admin, can revoke an approved authorization that has not been used: - The status becomes `revoked`, and the envelope signature is cleared, so it can never verify again. - A `revoked` entry is added to the approval ledger. - Only `approved` authorizations with no execution attempt can be revoked. A lost race returns a conflict. - Revocation needs a signed-in POINTS session. Agents cannot revoke through MCP. Revoking does not reverse anything, because nothing executed. ## Zero clock skew The server clock is authoritative. An authorization is expired when the server time is at or after `executableUntil`. No skew allowance is added, so an expired authorization is never treated as still usable. Clients should not rely on their own clocks to decide whether an approval is still valid; call `get_payment_status`. ## Status values All payment draft, envelope, and approval statuses are generated from code in [Statuses](/docs/agents/reference/statuses). --- title: Payment patterns description: Escrow-before-work, charge-on-2xx with fee-before-send, and graduated autonomy. All require execution (not enabled). url: https://thepoints.io/docs/agents/concepts/payment-patterns audience: [agents, operators, developers] status: Not enabled --- # Payment patterns > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). These patterns are in the code on production, but each one requires execution (not enabled). Today they only shape how a draft is checked and recorded. No pattern sends a payment, and every payment still needs human approval. `prepare_payment` accepts an optional `paymentPattern`: `standard` (the default), `sell_side_job`, or `micropayment`. ## Escrow-before-work (`sell_side_job`) For a job an agent is paid to do. The amount is counted as escrowed before work starts. - States: `none`, `held`, `releasable`, `refundable`, then `released` or `refunded`. Any other transition is refused. - A job without a `held` escrow is refused before work starts. - Release and refund are refused while execution is not enabled. ## Charge-on-2xx and fee-before-send (`micropayment`) For pay-per-call APIs. - The fee would be assessed and reserved before anything is sent. - A charge would be allowed only after an HTTP 2xx response. Any other response, or a missing status, means no charge. ## Graduated autonomy Levels `L0` to `L3` describe how much history and trust an agent has with a merchant, based on merchant, amount, frequency, and past results. - Levels are recorded for policy review only. Every payment still needs human approval. - A level never overrides a policy deny, a block list, or a velocity cap. ## Status All of this requires execution (not enabled). The current state is at [/docs/agents/status.json](/docs/agents/status.json). --- title: Recurring mandates description: Recurring mandates. Every cycle needs a fresh human approval, early claims are refused, and a claim never moves money. url: https://thepoints.io/docs/agents/concepts/recurring-mandates audience: [agents, operators, developers] status: Live (limited) --- # Recurring mandates > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). A recurring mandate is a template for a repeating payment: an amount, a currency, a saved payee, and an interval in days. It is not a standing approval. Every cycle needs a fresh human approval. ## Limits today This feature is Live (limited). Mandate cycles can be drafted to a saved payee. Each mandate cycle needs a fresh human approval, valid until the cycle time plus a grace period. Claims before the cycle time are refused. Scheduled claims are not enabled, and a claim only records the claim. Money doesn't move while execution is not enabled. In detail: - **Fresh human approval every cycle.** Approving one cycle never approves the next. - **Owner only.** Mandates are created and managed by the account owner in a signed-in POINTS session. No MCP tool creates or claims a mandate, and there is no mandate screen in the app yet. - **Early claims are refused.** A cycle can't be claimed before its cycle time. - **A scheduled claim option exists but is not enabled.** It can't be turned on from the app, and without it the owner claims each cycle in a signed-in session. - **A claim only records the claim.** It returns `executed: false` and never moves money. Execution: not enabled. ## One cycle, step by step 1. **Prepare.** The owner opens the cycle for the next cycle time. It starts as `pending_approval`. 2. **Draft.** A payment draft is created from the stored mandate terms, addressed to the saved payee. Nothing in the request can change the amount or payee. 3. **Approve.** A human approves the draft as usual, and a fresh signed envelope is minted. 4. **Attach.** The envelope is attached to the cycle. It must match the mandate terms exactly (amount, currency, payee) and pass the [scope checks](/docs/agents/concepts/scoped-approval). The cycle becomes `approved`. 5. **Claim.** At or after the cycle time, the owner claims the cycle. It becomes `claimed`, and the next cycle time moves forward one interval. ## Approval window - A cycle approval stays valid until the cycle time plus a grace period. The grace period is a server setting. - Approval opens only a limited time before that deadline, also a server setting. Earlier approvals are refused. - Other drafts keep the ordinary 1-hour window. ## What can go wrong | Situation | Result | |---|---| | Claim before the cycle time | Refused as not due. Nothing is written, and the same cycle can be claimed once it is due. | | Approval lapsed or revoked before the claim | The cycle becomes `expired`, and the slot can be prepared again. | | An execution attempt was recorded for the draft | The cycle becomes `refused`, and the slot is used up. | | The owner skips the cycle | The cycle becomes `skipped`, and the next cycle time moves forward one interval. | | Terms don't match the mandate | Attach or claim is refused. | Each envelope can be used for one cycle only. Mandate and cycle statuses are listed in [Statuses](/docs/agents/reference/statuses). --- title: Scoped approval description: The spend envelope, the approval ledger, and approval scope, with today's limits. url: https://thepoints.io/docs/agents/concepts/scoped-approval audience: [agents, operators, developers] status: Live (limited) --- # Scoped approval > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). Every human approval creates a spend envelope: a record of what the approval covers. Decisions about it are written to a separate approval ledger. ## Limits today Both features are Live (limited). Read these before relying on them: - **Approval still starts from a draft.** A human approves one payment draft, and the spend envelope and ledger entry are recorded alongside that approval. There is no standalone "approve a budget" flow. - **Aggregate caps are in progress.** An envelope can carry `maxPayments` and `maxTotalCents`, but usage across multiple payments is not persisted yet. Per-payment and allow-list checks apply. - **Scope can't be set from the approval screen yet.** Approvals use the defaults in the table below. - **Approve does not execute.** An envelope never moves money on its own, and execution is not enabled. ## Spend envelope Minted in the same transaction as the human approval. If it can't be saved, the approval fails rather than being recorded without it. It holds: - The signed fields: amount, currency, payee, funding source, rail, idempotency key, and `executableUntil`. - Who is involved: the principal (account owner), the agent, and the approver. - The signature, cleared on revocation. Envelope statuses: `approved`, `revoked`, `expired`, `denied`. ## Approval ledger An append-only record of envelope decisions, separate from general agent activity. Each entry is one of `approved`, `revoked`, `expired`, or `denied`. ## Approval scope | Field | Default | Effect | |---|---|---| | Principal, amount, currency, payee, expiry | From the approved draft | Locked by the signature | | `allowedCounterparties` | Empty | Empty means the locked payee only | | `maxPayments`, `maxTotalCents` | Unset | Aggregate caps (see limits above) | | `unattendedAllowed` | `false` | Automated, unattended use is refused | | `requiresInteractiveSession` | `true` | Use must come from a signed-in human session | Scope checks fail closed. Any automated reuse of an interactive, one-time approval is refused. ## Related - [Authorization envelope](/docs/agents/concepts/authorization-envelope) - [Recurring mandates](/docs/agents/concepts/recurring-mandates), which need a fresh envelope every cycle - [Statuses](/docs/agents/reference/statuses) --- title: Discovery description: How an agent finds POINTS. MCP endpoint, OAuth metadata, llms files, status.json, catalog.json, and the reference JSON. url: https://thepoints.io/docs/agents/discovery audience: [agents, developers] --- # Discovery > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). Everything an agent needs to find and connect to POINTS is public, unauthenticated, and on `https://thepoints.io`. ## Connect | URL | What it returns | |---|---| | `/mcp` | The MCP endpoint (Streamable HTTP). Without a token it returns HTTP 401 and a `WWW-Authenticate` header pointing to the protected-resource metadata. | | [/.well-known/oauth-protected-resource](/.well-known/oauth-protected-resource) | The resource (`https://thepoints.io/mcp`), its authorization server, and `scopes_supported` | | [/.well-known/oauth-authorization-server](/.well-known/oauth-authorization-server) | Authorization, token, registration, and revocation endpoints; PKCE `S256`; public clients only | | [/.well-known/openid-configuration](/.well-known/openid-configuration) | The same authorization server metadata, for clients that look there | Read the authorization, token, registration, and revocation endpoints from the metadata rather than hard-coding them. ## Read | URL | What it returns | |---|---| | [/llms.txt](/llms.txt) | Index of the public site and docs for language models | | [/llms-full.txt](/llms-full.txt) | Every public docs page and the changelog as one Markdown file | | [/docs/agents/llms.txt](/docs/agents/llms.txt) | This section only | | `/docs/.md` | Any docs page as Markdown, for example [/docs/agents/quickstart.md](/docs/agents/quickstart.md) | ## Machine-readable state | URL | What it returns | |---|---| | [/docs/agents/status.json](/docs/agents/status.json) | Agent Pay state, computed on each request: authorization, execution, `approveExecutes`, ACH settlement | | [/docs/catalog.json](/docs/catalog.json) | Every POINTS product with its status | | [/changelog.json](/changelog.json) | What shipped to production, by commit | | [/docs/agents/reference/mcp-tools.json](/docs/agents/reference/mcp-tools.json) | MCP tools with scopes, annotations, and input schemas | | [/docs/agents/reference/scopes.json](/docs/agents/reference/scopes.json) | OAuth scopes and the tools that need them | | [/docs/agents/reference/statuses.json](/docs/agents/reference/statuses.json) | Status values and their meaning | | [/docs/agents/reference/policy-vocabulary.json](/docs/agents/reference/policy-vocabulary.json) | Policy schema version, categories, matching rules, default caps | | [/docs/agents/reference/errors.json](/docs/agents/reference/errors.json) | prepare_payment failure classes and protocol errors | The reference JSON is generated from the same code the MCP server runs. A connected client can also call `tools/list` and `get_agent_pay_policy_vocabulary` for the live values on its connection. Read `status.json` before telling a user what an approval does. Today it reports `"approveExecutes": false`. --- title: FAQ description: Straight answers on replay, price drift, self-approval, receipts, and disputes for agents using POINTS. url: https://thepoints.io/docs/agents/faq audience: [agents, operators, developers] --- # FAQ > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). ## Can an approval be replayed? No. A human approves one draft, and POINTS records a signed authorization envelope bound to that draft's amount, payee, and idempotency key. The envelope expires at `executableUntil`, 1 hour after approval by default. Approve does not execute. - Calling `prepare_payment` again with the same `idempotencyKey` and the same data returns the same draft, not a second one. Reusing the key with different data is refused. - An interactive approval can't be reused by an automated process. See [Scoped approval](/docs/agents/concepts/scoped-approval). - Each recurring-mandate cycle needs its own fresh envelope. See [Recurring mandates](/docs/agents/concepts/recurring-mandates). - A revoked authorization can never verify again, because its signature is cleared. ## What if the price changes after approval? The approval covers the exact amount and payee that were approved. If the draft's amount or payee no longer matches the signed envelope, it is refused when the envelope is checked again, and a new prepare and approval are needed. That re-check is the only protection today. There is no tolerance band for small price changes, and no policy for partial or degraded fulfilment. Both are on the backlog. ## Can an agent approve its own payment? No. Approval needs a signed-in human session in POINTS. MCP access tokens cannot reach the approval or revocation routes, and no MCP tool approves anything. Graduated autonomy levels are recorded for review only and never replace human approval. ## Do I get a receipt? Not for a payment, because nothing executes. Approve does not execute. What exists today: - The draft status from `get_payment_status`, with `executed: false`. - The signed envelope and the approval-ledger entry, recorded on the POINTS side. Settlement receipts are planned. The current state of execution is in [/docs/agents/status.json](/docs/agents/status.json). ## How do disputes work? There is no dispute flow yet. Since nothing executes, there is no payment to dispute. Today, a human can reject a draft or revoke an unused approval in POINTS. ## Where do I report a problem? Use [support](/support), and include the draft id from `prepare_payment`. Never include access tokens or account numbers. --- title: Hosts description: Which MCP hosts work with POINTS today and which are planned next. ChatGPT is live; Claude, Cursor and OpenClaw-class runtimes are planned. url: https://thepoints.io/docs/agents/hosts audience: [agents, operators] --- # Hosts An MCP host is the app an agent runs in. Host status comes from the product catalog at [/docs/catalog.json](/docs/catalog.json). | Host | Status | Guide | |---|---|---| | ChatGPT | Live | [ChatGPT](/docs/agents/hosts/chatgpt) | | Claude Desktop and Claude Code | Planned | [Claude](/docs/agents/hosts/claude) | | Cursor | Planned | [Cursor](/docs/agents/hosts/cursor) | | OpenClaw-class runtimes | Planned | [OpenClaw](/docs/agents/hosts/openclaw) | Planned hosts are next, in this order. POINTS does not publish dates. A host is marked Live only after it passes QA on production. ## Disconnecting CLI logout commands such as `openclaw mcp logout points` and opencode's `opencode mcp logout` only delete the token stored on your computer; the grant stays active on POINTS until it expires. To end access, also revoke the app on Agent Connections in POINTS, after which calls return HTTP 401. Each app has its own revoke. --- title: ChatGPT description: Connect ChatGPT to the Points MCP server in Developer Mode, approve scopes, and check the connection. url: https://thepoints.io/docs/agents/hosts/chatgpt audience: [agents, operators] status: Live --- # ChatGPT > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). ChatGPT is the MCP host that has passed QA on production. It connects to POINTS as a custom connector in Developer Mode. ## Connect 1. In ChatGPT, enable Developer Mode and add a connector with the endpoint `https://thepoints.io/mcp`. 2. ChatGPT discovers the protected-resource and authorization-server metadata and registers itself. You don't need a client id or secret. 3. Sign in to POINTS, review the requested scopes, and approve. 4. ChatGPT lists the POINTS tools. See [MCP tools](/docs/agents/reference/mcp-tools). ## Check the connection 1. Ask ChatGPT to call `get_wallet_status` with no arguments, and check that only the authorized account's stored wallet status comes back. 2. Ask it to call `get_agent_pay_policy_vocabulary`, and check the policy schema version and categories. 3. Revoke the connection in POINTS and confirm that later calls return HTTP 401. ## Try a payment draft Follow the [Quickstart](/docs/agents/quickstart) from step 2. When ChatGPT calls `prepare_payment`, approve or reject the draft in POINTS, then ask ChatGPT to call `get_payment_status`. The status shows `executed: false`. Approve does not execute. ## Troubleshooting | Symptom | What to check | |---|---| | `Missing required scope: ` | Reconnect and approve the scope the tool needs. See [OAuth scopes](/docs/agents/reference/scopes). | | HTTP 401 on every call | The connection was revoked or the token expired. Reconnect. | | `create_payment_draft` errors | The tool is retired. Refresh the connector so ChatGPT uses `prepare_payment`. | | A draft reads as `expired` | The approval window passed. Prepare again and get a new approval. | --- title: Claude description: Claude Desktop and Claude Code support for the POINTS MCP server is planned. Use ChatGPT today, or follow the discovery guide for any MCP host. url: https://thepoints.io/docs/agents/hosts/claude audience: [agents, operators] status: Planned --- # Claude **[ChatGPT is the live host today.](/docs/agents/hosts/chatgpt)** Claude Desktop and Claude Code are a planned MCP host for POINTS. Neither is QA-passed on production, and POINTS does not publish a date. This page will carry the connection guide once the host passes QA on production. Until then, ChatGPT is the host to use; see the [ChatGPT guide](/docs/agents/hosts/chatgpt). Host status comes from [/docs/catalog.json](/docs/catalog.json). For how any MCP host discovers POINTS, see [Discovery](/docs/agents/discovery). ## Draft setup (not yet QA-passed) This section is a draft for QA. It is not a supported connection and it is not QA-passed on production. ### claude.ai and Claude Desktop 1. Open Settings → Connectors → Add custom connector. 2. Enter the server URL `https://thepoints.io/mcp`. 3. Choose "Register automatically" or the default registration option. 4. Sign in to POINTS, review the requested scopes, and approve them. ### Claude Code 1. Run `claude mcp add --transport http points https://thepoints.io/mcp`. 2. Run `/mcp` in Claude Code and complete the browser sign-in and scope approval. ### Check the connection 1. Call `get_wallet_status` and `get_agent_pay_policy_vocabulary`, and confirm only the authorized account's stored data comes back. 2. Prepare a draft with `prepare_payment`, then approve or reject it in POINTS. 3. Read the draft with `get_payment_status`. The status shows `executed: false`. Approve does not execute. 4. Revoke the connection in POINTS and confirm that later calls return HTTP 401. --- title: Cursor description: Cursor support for the POINTS MCP server is planned. Use ChatGPT today, or follow the discovery guide for any MCP host. url: https://thepoints.io/docs/agents/hosts/cursor audience: [agents, operators] status: Planned --- # Cursor **[ChatGPT is the live host today.](/docs/agents/hosts/chatgpt)** Cursor is a planned MCP host for POINTS. It is not QA-passed on production, and POINTS does not publish a date. This page will carry the connection guide once the host passes QA on production. Until then, ChatGPT is the host to use; see the [ChatGPT guide](/docs/agents/hosts/chatgpt). Host status comes from [/docs/catalog.json](/docs/catalog.json). For how any MCP host discovers POINTS, see [Discovery](/docs/agents/discovery). ## Draft setup (not yet QA-passed) This draft is for the Cursor QA run only. It is not a production guarantee and does not change Cursor's Planned status. 1. Add the POINTS server to Cursor's MCP config at `~/.cursor/mcp.json` or the project `.cursor/mcp.json`: ```json { "mcpServers": { "points": { "url": "https://thepoints.io/mcp" } } } ``` The in-app POINTS setup modal also offers an **Add to Cursor** button. It opens Cursor's install prompt with the same URL prefilled and Cursor still asks you to confirm before anything connects. The raw deeplink is [Add to Cursor](cursor://anysphere.cursor-deeplink/mcp/install?name=points&config=eyJ1cmwiOiJodHRwczovL3RoZXBvaW50cy5pby9tY3AifQ%3D%3D). 2. Open Cursor Settings → MCP, find the `points` server, and choose **Connect**. Cursor opens a browser sign-in to POINTS. You do not need a client id or secret: Cursor registers itself and can call through the fixed loopback callback `http://localhost:8787/callback`, or the web/Agents callback `https://www.cursor.com/agents/mcp/oauth/callback`. 3. On the POINTS consent page, review the client name, the redirect host, and the requested scopes, then approve. The QA run approves only `balances:read payments:draft payments:status module-status:read` (add `identity:read` if prompted). 4. Confirm the green connection status and the advertised tools. See [MCP tools](/docs/agents/reference/mcp-tools). `prepare_payment` should be present and `create_payment_draft` should not be advertised. ### Check the connection 1. Ask Cursor to call `get_agent_pay_policy_vocabulary` and `get_wallet_status`. Expect the real vocabulary and only this account's stored data. 2. Prepare a draft with `prepare_payment` for the saved test payee. The response shows `status: "requires_approval"`. Approve does not execute. 3. Approve the draft in POINTS as the QA owner from the browser, then call `get_payment_status`. It shows `approved` and `executed: false`. 4. Wait past the 15-minute access-token lifetime and call a tool again. It works without a new consent step. Revoke the connection in POINTS and the next call returns HTTP 401. ### Troubleshooting | Symptom | What to check | |---|---| | Redirect mismatch: Cursor tried a fallback callback (port 8787 busy) | Free port 8787 and reconnect. The desktop IDE/CLI uses the fixed loopback callback on port 8787. | | `invalid_grant` at the token endpoint | Keep the `resource` value exactly `https://thepoints.io/mcp`, with no trailing slash. | | HTTP 401 on every call | The connection was revoked or the token expired. Reconnect. | | `Missing required scope: ` | Reconnect and approve the scope the tool needs. See [OAuth scopes](/docs/agents/reference/scopes). | Modes that still present the `cursor://` custom-scheme fallback are not supported. Use the loopback path above, or connect through Cursor web/Agents. --- title: OpenClaw description: Support for OpenClaw-class agent runtimes on the POINTS MCP server is planned. Use ChatGPT today, or follow the discovery guide. url: https://thepoints.io/docs/agents/hosts/openclaw audience: [agents, operators] status: Planned --- # OpenClaw **[ChatGPT is the live host today.](/docs/agents/hosts/chatgpt)** OpenClaw-class agent runtimes are a planned MCP host for POINTS. They are not QA-passed on production, and POINTS does not publish a date. This page will carry the connection guide once the host passes QA on production. Until then, ChatGPT is the host to use; see the [ChatGPT guide](/docs/agents/hosts/chatgpt). Host status comes from [/docs/catalog.json](/docs/catalog.json). For how any MCP host discovers POINTS, see [Discovery](/docs/agents/discovery). ## Draft setup (not yet QA-passed) This draft is for QA on an approved test account only. It is not a live guide, and OpenClaw-class runtimes are not QA-passed on production. ### Operator login (loopback callback) ```bash openclaw mcp add points --url https://thepoints.io/mcp --transport streamable-http --auth oauth \ --oauth-scope "balances:read transactions:read rewards:read optimize:read payments:draft payments:status identity:read module-status:read" openclaw mcp login points openclaw mcp doctor points --probe ``` Set `transport` to `streamable-http`; the OpenClaw default of `sse` is not supported here, and `GET /mcp` returns `405` with `Allow: POST`. `openclaw mcp login` registers itself, opens a browser sign-in to POINTS, and returns to a loopback callback on the port its local listener chose. You do not need a client id or secret. After the connection succeeds, `openclaw mcp doctor points --probe` should list the tools advertised in [/docs/agents/reference/mcp-tools.json](/docs/agents/reference/mcp-tools.json). ### Per-requester Gateway callback When a Gateway registers a public HTTPS origin, the per-requester callback is served on that origin, and the Gateway origin is registered automatically through Dynamic Client Registration. The callback must be an exact match: no trailing slash, query or fragment, and no `http` scheme for a non-loopback host. ### Generic MCP clients Any other OpenClaw-class runtime works the same way when it implements: - MCP Streamable HTTP `POST` requests. `GET /mcp` is `405`, and no server-sent-events stream is served. - The `Accept: application/json, text/event-stream` header. - OAuth 2.1 public-client Dynamic Client Registration with PKCE `S256`. - RFC 8707 `resource=https://thepoints.io/mcp` on the authorize and token requests. - A loopback callback (`127.0.0.1`, `[::1]` or `localhost`, any port) or one exact registered HTTPS callback. ### Disconnecting `openclaw mcp logout points` only deletes the token stored on your computer; the grant stays active on POINTS until it expires. To end access, also revoke the app on Agent Connections in POINTS, after which calls return HTTP 401. Each app has its own revoke. --- title: Quickstart description: Connect over MCP with OAuth, read the policy vocabulary, prepare a payment, get human approval, and check its status. Nothing executes. url: https://thepoints.io/docs/agents/quickstart audience: [agents, operators, developers] status: Live (authorization only) --- # Quickstart > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). This guide takes an agent from its first connection to a signed authorization. It ends with a payment draft that a human approved and that has not executed. ## Before you start - An MCP host that connects to remote MCP servers with OAuth. ChatGPT is the live host today; see the [ChatGPT guide](/docs/agents/hosts/chatgpt). - A POINTS account for the operator, the person who signs in, sets policy, and approves. [Sign up as an agent operator](/signup/agents). ## 1. Discover and connect 1. Point the host at `https://thepoints.io/mcp` (Streamable HTTP). 2. A call without a token gets HTTP 401 with a `WWW-Authenticate` header whose `resource_metadata` points to `/.well-known/oauth-protected-resource`. 3. The host reads that document, then the authorization server metadata at `/.well-known/oauth-authorization-server`. 4. The host registers itself at the `registration_endpoint` (dynamic client registration, public client), then runs the authorization code flow with PKCE (S256). 5. The operator signs in to POINTS, reviews the requested scopes, and grants them. This guide needs `payments:draft`, `payments:status`, and `module-status:read`. 6. The host calls `tools/list`. Every tool is described in the [MCP tools reference](/docs/agents/reference/mcp-tools). Endpoint details are on the [Discovery](/docs/agents/discovery) page. ## 2. Read the policy vocabulary Call `get_agent_pay_policy_vocabulary` with no arguments. Keep three things from the result: - `policySchemaVersion`: send it with every `prepare_payment` call. An unsupported version fails closed. - `categories`: the exact `value` strings to use for `category`. Aliases are rejected. - `velocityCaps` and the allow and block lists: what the operator's policy permits on this connection. The static part of the vocabulary is published at [/docs/agents/reference/policy-vocabulary.json](/docs/agents/reference/policy-vocabulary.json). ## 3. Prepare a payment Call `prepare_payment`: ```json { "amountCents": 2500, "currency": "USD", "merchant": "Example Compute Co", "category": "ai_compute", "reference": "GPU hours for job 42", "idempotencyKey": "job-42-gpu-hours", "policySchemaVersion": 1 } ``` When policy allows the payment to be proposed, the result is a draft waiting for a human: ```json { "payment_id": "", "status": "requires_approval", "merchant": "Example Compute Co", "amount": 2500, "currency": "USD", "policy_result": "allowed_with_approval", "estimated_fee": null, "estimated_reward": null, "expires_at": "" } ``` - The draft waits up to 24 hours for a decision (`expires_at`). - Retrying with the same `idempotencyKey` and the same data returns the same draft. Reusing the key with different data is refused. - When policy blocks the payment, the tool returns an error with a readable reason and no approvable draft. See [Errors](/docs/agents/reference/errors). ## 4. A human approves The operator opens Approvals in POINTS and approves or rejects the draft. Approval needs a signed-in POINTS session. MCP access tokens cannot reach the approval routes, so an agent cannot approve its own payment. At approval, POINTS signs an [authorization envelope](/docs/agents/concepts/authorization-envelope) that binds the amount, currency, payee, idempotency key, approver, and an `executableUntil` time, 1 hour after approval by default. The signing key stays on the server. ## 5. Check the status Call `get_payment_status` with the `payment_id`: ```json { "draftId": "" } ``` ```json { "id": "", "status": "approved", "amountCents": 2500, "currency": "USD", "createdAt": "", "expiresAt": "", "executed": false, "executionProvider": null, "executionRail": null, "providerStatus": null } ``` - `status` moves from `requires_approval` to `approved`, `rejected`, `expired`, or `revoked`. All values are in [Statuses](/docs/agents/reference/statuses). - `executed` is always `false`. - Once `executableUntil` passes, the draft reads as `expired`. See [Lifecycle](/docs/agents/concepts/lifecycle). - `get_payment_status` only returns drafts on the connected account. It never returns another account's drafts. The prepare result may include an optional `cash_check` warning for insufficient or unknown unreserved cash. The warning also appears on the approval card. Prepare warns today; the same codes become refusals at a future execution launch. ## What happens next Nothing executes. Approve does not execute, and the live state is published at [/docs/agents/status.json](/docs/agents/status.json). Read it before telling a user what an approval means. --- title: MCP & API reference description: Tools, scopes, statuses and policy vocabulary as JSON. url: https://thepoints.io/docs/agents/reference audience: [agents, operators, developers] --- # MCP & API reference > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). Every page here is generated from the code the Points MCP server runs, and each has a JSON twin. A test fails the build if the code and these pages disagree. | Page | JSON | Contents | |---|---|---| | [MCP tools](/docs/agents/reference/mcp-tools) | [mcp-tools.json](/docs/agents/reference/mcp-tools.json) | Every tool with its scope, annotations, and input schema, including the retired `create_payment_draft` | | [OAuth scopes](/docs/agents/reference/scopes) | [scopes.json](/docs/agents/reference/scopes.json) | The eight scopes and which tool needs which | | [Statuses](/docs/agents/reference/statuses) | [statuses.json](/docs/agents/reference/statuses.json) | Payment draft, approval, envelope, mandate, and wallet statuses | | [Policy vocabulary](/docs/agents/reference/policy-vocabulary) | [policy-vocabulary.json](/docs/agents/reference/policy-vocabulary.json) | Policy schema version, categories, matching rules, default velocity caps | | [Errors](/docs/agents/reference/errors) | [errors.json](/docs/agents/reference/errors.json) | prepare_payment failure classes, JSON-RPC errors, tool errors | Connected clients get the same tool list from `tools/list`, and the live policy for their connection from `get_agent_pay_policy_vocabulary`. OAuth discovery starts at [/.well-known/oauth-protected-resource](/.well-known/oauth-protected-resource); see [Discovery](/docs/agents/discovery). Stable refusal codes are not published yet. See [Errors](/docs/agents/reference/errors). --- title: Errors description: prepare_payment failure classes, JSON-RPC errors, and tool errors. Generated from code. url: https://thepoints.io/docs/agents/reference/errors audience: [agents, operators, developers] --- # Errors > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). Generated from code. Machine-readable: [/docs/agents/reference/errors.json](/docs/agents/reference/errors.json). ## prepare_payment cash check codes (warning today, refusal at a future execution launch) Prepare warns today through the optional `cash_check` result and the approval card. At a future execution launch, the same codes become refusals before a new reservation. Other refusals return a readable message that can change. A stored balance snapshot older than 24 hours is unknown by default. No payment is sent by prepare. | Code | Meaning | |---|---| | `unreserved_cash_insufficient` | The proposed draft exceeds unreserved cash. | | `unreserved_cash_unknown` | A recent available cash snapshot is required. | ## prepare_payment failure classes When `prepare_payment` fails unexpectedly, the tool error text is `prepare_payment failed: ` with one of these classes. | Class | Meaning | |---|---| | `database_unavailable` | POINTS could not reach its database. Retry later with the same idempotencyKey. | | `payment_prepare_failed` | The draft could not be prepared, for example because the agent is unavailable. Nothing was created. | | `invalid_tool_input` | The input was malformed, used a forbidden selector, or reused an idempotencyKey with different data. | | `policy_blocked` | Agent policy or permissions block this payment. | | `internal_tool_error` | An unexpected server error. Nothing was created. | ## JSON-RPC errors | Code | Meaning | |---|---| | `-32601` | Unknown tool or method. | | `-32602` | Invalid tool arguments. The error data names the field, never its value. | ## Tool errors - Any tool: `Missing required scope: ` when the grant lacks the tool's scope. Reconnect and approve the scope. - `create_payment_draft`: every call returns `create_payment_draft is no longer an advertised POINTS MCP tool. Refresh tool discovery and use prepare_payment for Agent Pay payment preparation.` - A revoked connection gets HTTP 401 on every call. --- title: MCP tools description: Every Points MCP tool with its OAuth scope, annotations, and input schema. Names, scopes, and schemas generated from code. url: https://thepoints.io/docs/agents/reference/mcp-tools audience: [agents, operators, developers] status: Live --- # MCP tools > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). Names, scopes, and schemas generated from code. Machine-readable: [/docs/agents/reference/mcp-tools.json](/docs/agents/reference/mcp-tools.json). Server `points-mcp` version `2.2.0`, MCP protocol `2025-11-25`, Streamable HTTP at `https://thepoints.io/mcp`. Every call needs an OAuth access token, and the tool's scope is checked on every call. No tool accepts an account identifier: the account comes from the OAuth grant. | Tool | Scope | Read-only | Listed by tools/list | |---|---|---|---| | [`get_account_summary`](#get-account-summary) | `balances:read` | Yes | Yes | | [`list_transactions`](#list-transactions) | `transactions:read` | Yes | Yes | | [`find_savings_opportunities`](#find-savings-opportunities) | `optimize:read` | Yes | Yes | | [`create_payment_draft`](#create-payment-draft) | `payments:draft` | No | No (retired, fails closed) | | [`prepare_payment`](#prepare-payment) | `payments:draft` | No | Yes | | [`get_payment_status`](#get-payment-status) | `payments:status` | Yes | Yes | | [`get_connection_identity`](#get-connection-identity) | `identity:read` | Yes | Yes | | [`get_account_status`](#get-account-status) | `module-status:read` | Yes | Yes | | [`get_agent_pay_policy_vocabulary`](#get-agent-pay-policy-vocabulary) | `module-status:read` | Yes | Yes | | [`get_wallet_status`](#get-wallet-status) | `module-status:read` | Yes | Yes | ## get_account_summary **Get account summary.** Read-only balance summary for the connected account. The available balance is unreserved cash, after Agent Pay reserved and escrowed amounts. Sources are labelled sandbox. - Scope: `balances:read` - Annotations: `readOnlyHint` true, `destructiveHint` false, `idempotentHint` true, `openWorldHint` false - Listed by tools/list: yes Input schema: ```json { "type": "object", "properties": {}, "additionalProperties": false } ``` ## list_transactions **List transactions.** Read-only sandbox transaction list for the connected account. - Scope: `transactions:read` - Annotations: `readOnlyHint` true, `destructiveHint` false, `idempotentHint` true, `openWorldHint` false - Listed by tools/list: yes Input schema: ```json { "type": "object", "properties": {}, "additionalProperties": false } ``` ## find_savings_opportunities **Find savings opportunities.** Read-only sandbox savings suggestions scoped to the connected account. - Scope: `optimize:read` - Annotations: `readOnlyHint` true, `destructiveHint` false, `idempotentHint` true, `openWorldHint` false - Listed by tools/list: yes Input schema: ```json { "type": "object", "properties": {}, "additionalProperties": false } ``` ## create_payment_draft **Create payment draft.** Retired. Not listed by tools/list. A direct call fails closed with an explicit message to use prepare_payment. - Scope: `payments:draft` - Annotations: `readOnlyHint` false, `destructiveHint` false, `idempotentHint` true, `openWorldHint` false - Listed by tools/list: no - Every call returns: `create_payment_draft is no longer an advertised POINTS MCP tool. Refresh tool discovery and use prepare_payment for Agent Pay payment preparation.` Input schema: ```json { "type": "object", "properties": { "amountCents": { "type": "integer", "minimum": 1, "maximum": 10000000 }, "currency": { "type": "string", "pattern": "^[A-Z]{3}$" }, "recipient": { "type": "string", "minLength": 1, "maxLength": 160 }, "reference": { "type": "string", "minLength": 1, "maxLength": 240 }, "idempotencyKey": { "type": "string", "pattern": "^[A-Za-z0-9_-]{8,120}$" } }, "required": [ "amountCents", "currency", "recipient", "reference", "idempotencyKey" ], "additionalProperties": false } ``` ## prepare_payment **Prepare agent payment.** Agent Pay entry point. Checks policy, spending controls, and caps, then stages a draft that always needs human approval. It never moves money. - Scope: `payments:draft` - Annotations: `readOnlyHint` false, `destructiveHint` false, `idempotentHint` true, `openWorldHint` false - Listed by tools/list: yes Input schema: ```json { "type": "object", "properties": { "amountCents": { "type": "integer", "minimum": 1, "maximum": 10000000 }, "currency": { "type": "string", "pattern": "^[A-Z]{3}$" }, "merchant": { "type": "string", "minLength": 1, "maxLength": 160 }, "category": { "type": "string", "enum": [ "ai_compute", "advertising_marketing", "saas_apis", "ecommerce_procurement", "logistics" ] }, "reference": { "type": "string", "minLength": 1, "maxLength": 240 }, "idempotencyKey": { "type": "string", "pattern": "^[A-Za-z0-9_-]{8,120}$" }, "paymentPattern": { "type": "string", "enum": [ "standard", "sell_side_job", "micropayment" ], "description": "Optional Agent Pay P2 pattern. sell_side_job holds escrow before work; micropayment reserves fee before send and charges only on HTTP 2xx. Never moves money while execution is disabled." }, "policySchemaVersion": { "type": "integer", "minimum": 1, "maximum": 32, "description": "Policy schema version from get_agent_pay_policy_vocabulary.policySchemaVersion. Unsupported versions fail closed on spend. Omit only for legacy clients." } }, "required": [ "amountCents", "currency", "merchant", "idempotencyKey" ], "additionalProperties": false } ``` ## get_payment_status **Get payment draft status.** Read-only status of a payment draft on the connected account, with read-time expiry applied. executed is always false. - Scope: `payments:status` - Annotations: `readOnlyHint` true, `destructiveHint` false, `idempotentHint` true, `openWorldHint` false - Listed by tools/list: yes Input schema: ```json { "type": "object", "properties": { "draftId": { "type": "string", "minLength": 1, "maxLength": 120 } }, "required": [ "draftId" ], "additionalProperties": false } ``` ## get_connection_identity **Get connection identity.** Read-only redacted identity of the connected account and its server-side mappings. No balances or secrets. - Scope: `identity:read` - Annotations: `readOnlyHint` true, `destructiveHint` false, `idempotentHint` true, `openWorldHint` false - Listed by tools/list: yes Input schema: ```json { "type": "object", "properties": {}, "additionalProperties": false } ``` ## get_account_status **Get account status.** Read-only account type and module activation status. - Scope: `module-status:read` - Annotations: `readOnlyHint` true, `destructiveHint` false, `idempotentHint` true, `openWorldHint` false - Listed by tools/list: yes Input schema: ```json { "type": "object", "properties": {}, "additionalProperties": false } ``` ## get_agent_pay_policy_vocabulary **Get Agent Pay policy vocabulary.** Read-only policy vocabulary: schema version, canonical categories, matching rules, velocity caps, and the allow and block lists for this connection. - Scope: `module-status:read` - Annotations: `readOnlyHint` true, `destructiveHint` false, `idempotentHint` true, `openWorldHint` false - Listed by tools/list: yes Input schema: ```json { "type": "object", "properties": {}, "additionalProperties": false } ``` ## get_wallet_status **Get wallet status.** Read-only stored wallet status (staging) for the connected AI Agent. No balances and no raw wallet identifiers. - Scope: `module-status:read` - Annotations: `readOnlyHint` true, `destructiveHint` false, `idempotentHint` true, `openWorldHint` false - Listed by tools/list: yes Input schema: ```json { "type": "object", "properties": {}, "additionalProperties": false } ``` --- title: Policy vocabulary description: Policy schema version, canonical categories, matching rules, and default velocity caps. Generated from code. url: https://thepoints.io/docs/agents/reference/policy-vocabulary audience: [agents, operators, developers] status: Live --- # Policy vocabulary > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). Generated from code. Machine-readable: [/docs/agents/reference/policy-vocabulary.json](/docs/agents/reference/policy-vocabulary.json). Call `get_agent_pay_policy_vocabulary` for the live values on your connection, including the operator's allow and block lists. Send the returned `policySchemaVersion` on every `prepare_payment` call. ## Policy schema version - Current: `1` - Supported range: `1` to `1` - An unsupported version fails closed. ## Categories | Value | Label | |---|---| | `ai_compute` | AI compute | | `advertising_marketing` | Advertising & marketing | | `saas_apis` | SaaS / APIs | | `ecommerce_procurement` | E-commerce procurement | | `logistics` | Logistics | There are 5 canonical categories. Aliases are not accepted. ## Matching rules - `mode`: `exact_canonical` - `caseNormalization`: `trim_lower` - `aliasesSupported`: `false` - `unknownCategoryDecision`: `deny` - `emptyAllowlistMeans`: `any_canonical_category_allowed_unless_blocked` - Use the exact `value` strings in prepare_payment.category and agent allowlists. - Aliases (e.g. saas, SaaS APIs) are rejected and do not bypass allowlists. - Policy matching is unchanged, except that unknown categories are denied. - Send prepare_payment.policySchemaVersion matching policySchemaVersion (or within min/max supported). Unsupported versions fail closed on spend. ## Default velocity caps Server defaults that limit how fast drafts can be prepared. The values that apply to your connection come back from the tool. | Cap | Default | |---|---| | `maxDraftsPerHour` | 12 | | `maxDraftsPerDay` | 48 | | `maxOutstandingDrafts` | 25 | | `maxAggregateCentsPerHour` | 100000 | | `maxAggregateCentsPerDay` | 500000 | A prepare that would exceed a cap is refused. These are per-agent velocity caps on prepared drafts. They are separate from spend-envelope aggregate caps, which are in progress (usage across payments is not persisted yet). --- title: OAuth scopes description: The OAuth scopes the Points MCP server supports and which tool needs which. Generated from code. url: https://thepoints.io/docs/agents/reference/scopes audience: [agents, operators, developers] status: Live --- # OAuth scopes > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). Generated from code. Machine-readable: [/docs/agents/reference/scopes.json](/docs/agents/reference/scopes.json). The same list is published as `scopes_supported` in [/.well-known/oauth-protected-resource](/.well-known/oauth-protected-resource). A client that registers dynamically without asking for scopes gets `module-status:read`. The account owner reviews the requested scopes on POINTS before granting them. | Scope | Grants | Tools | |---|---|---| | `balances:read` | Read the balance summary. | `get_account_summary` | | `transactions:read` | Read the sandbox transaction list. | `list_transactions` | | `rewards:read` | Adds the optional rewards summary to get_account_summary. | None directly | | `optimize:read` | Read savings suggestions. | `find_savings_opportunities` | | `payments:draft` | Prepare payment drafts for human approval. Never moves money. | `prepare_payment` | | `payments:status` | Read the status of payment drafts on the connected account. | `get_payment_status` | | `identity:read` | Read the redacted connection identity. | `get_connection_identity` | | `module-status:read` | Read account and module status, wallet status, and the Agent Pay policy vocabulary. | `get_account_status`, `get_agent_pay_policy_vocabulary`, `get_wallet_status` | --- title: Statuses description: Payment draft, approval, envelope, mandate, and wallet status values with their meaning. Generated from code. url: https://thepoints.io/docs/agents/reference/statuses audience: [agents, operators, developers] --- # Statuses > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). Generated from code. Machine-readable: [/docs/agents/reference/statuses.json](/docs/agents/reference/statuses.json). ## Payment draft status Applies to: get_payment_status.status. Read-time expiry applies: a pending draft past its approval window, or an approved draft past executableUntil, reads as expired. | Value | Meaning | |---|---| | `draft` | Created and not yet submitted for approval. | | `requires_approval` | Prepared by prepare_payment and waiting for a human decision. | | `approved` | A human approved it and a signed authorization envelope exists. Nothing has executed. | | `rejected` | A human rejected it. | | `expired` | The approval window or the signed executableUntil passed. A new prepare and approval are needed. | | `revoked` | An approved authorization was revoked before use. Its signature is cleared. | | `pending_operator_approval` | Waiting for the operator to approve or reject. | | `awaiting_approval` | Waiting for approval. | | `recipient_information_required` | The draft needs payee details before approval. | | `execution_pending` | Reserved for execution, which is not enabled. | | `completed` | Reserved for confirmed provider success, which cannot happen while execution is not enabled. | | `failed` | Reserved for a failed execution attempt. | ## Statuses governed by the approval window Applies to: Payment drafts (expiresAt). | Value | Meaning | |---|---| | `draft` | Expires when expiresAt passes. | | `requires_approval` | Expires when expiresAt passes. | | `pending_operator_approval` | Expires when expiresAt passes. | | `awaiting_approval` | Expires when expiresAt passes. | | `recipient_information_required` | Expires when expiresAt passes. | ## Statuses governed by executableUntil Applies to: Approved payment drafts and their envelopes. | Value | Meaning | |---|---| | `approved` | Reads as expired once the server clock reaches executableUntil (zero skew). | | `execution_pending` | Reads as expired once the server clock reaches executableUntil. | ## prepare_payment policy result Applies to: prepare_payment.policy_result. | Value | Meaning | |---|---| | `allowed_with_approval` | Policy allows the payment to be proposed. A human still has to approve it. | | `blocked` | Policy blocks the payment. No approvable draft is created. | ## Approval queue: pending Applies to: The operator approvals queue. | Value | Meaning | |---|---| | `draft` | Shown as pending. | | `requires_approval` | Shown as pending. | | `pending_operator_approval` | Shown as pending. | | `awaiting_approval` | Shown as pending. | ## Approval queue: history Applies to: The operator approvals queue. | Value | Meaning | |---|---| | `approved` | Approved. Approve does not execute. | | `rejected` | Rejected by a human. | | `expired` | The window passed before use. | | `revoked` | Revoked after approval, before use. | ## Spend envelope status Applies to: The spend envelope minted at approval. | Value | Meaning | |---|---| | `approved` | Minted at human approval with the signed fields and scope. | | `revoked` | Revoked. The signature is cleared and it can no longer be used. | | `expired` | Past executableUntil. | | `denied` | The approval was refused. | ## Approval ledger decision Applies to: Approval ledger entries for spend envelopes. | Value | Meaning | |---|---| | `approved` | A human approved the draft; this ledger entry records the signed envelope alongside it. | | `revoked` | The authorization was revoked by the owner or an admin. | | `expired` | The envelope expired. | | `denied` | The approval was refused. | ## Recurring mandate status Applies to: Recurring mandates. | Value | Meaning | |---|---| | `active` | Cycles can be prepared. Each cycle still needs a fresh human approval. | | `paused` | No cycles are prepared or claimed. | | `cancelled` | Cancelled by the owner. No further cycles. | | `completed` | No further cycles. | ## Mandate cycle status Applies to: Each cycle of a recurring mandate. | Value | Meaning | |---|---| | `pending_approval` | Opened for this cycle and waiting for a fresh human approval. | | `approved` | A fresh signed approval is attached. Claims before the cycle time are refused. | | `claimed` | The claim was recorded. A claim never moves money. | | `completed` | Reserved for execution, which is not enabled. | | `refused` | Refused, for example after an execution attempt was recorded. The slot is used up. | | `expired` | The cycle approval lapsed. The slot can be prepared again. | | `skipped` | Skipped by the owner, or marked missed when a cycle is not approved and claimed by the cycle time plus grace. | ## Wallet connection status Applies to: get_wallet_status.connectionStatus. | Value | Meaning | |---|---| | `not_connected` | No wallet is connected for this AI Agent. | | `pending` | Wallet setup has started and is not verified yet. | | `connected` | A staging wallet is connected and verified. | | `unavailable` | Status cannot be read right now. See unavailableReason. | | `error` | The last status check failed. See unavailableReason. | ## Wallet verification status Applies to: get_wallet_status.verificationStatus. | Value | Meaning | |---|---| | `not_verified` | Not verified. | | `pending` | Verification in progress. | | `verified` | Verified. | | `failed` | Verification failed. | ## Account module status Applies to: get_account_status.modules[].status (including the wallet module). | Value | Meaning | |---|---| | `active` | The module is active. | | `activating` | Activation is in progress. | | `ready_to_connect` | Ready to connect. | | `application_required` | An application is needed first. | | `application_started` | An application was started. | | `submitted` | The application was submitted. | | `in_review` | Under review. | | `action_required` | The account owner needs to act in POINTS, for example to re-authorize the wallet. | | `not_approved` | Not approved. | | `coming_soon` | Not available today. No date is published. | | `temporarily_unavailable` | Temporarily unavailable. | ## Payment pattern Applies to: prepare_payment.paymentPattern. Requires execution (not enabled). Values exist in code only. | Value | Meaning | |---|---| | `standard` | A single payment draft. | | `sell_side_job` | Escrow-before-work pattern. | | `micropayment` | Fee-before-send, charge-on-2xx pattern. | ## Escrow state Applies to: Escrow-before-work drafts. Requires execution (not enabled). Values exist in code only. | Value | Meaning | |---|---| | `none` | No escrow hold. | | `held` | Amount counted as escrowed. | | `releasable` | Work accepted; the hold could be released. | | `refundable` | The hold could be refunded. | | `released` | Terminal: released. | | `refunded` | Terminal: refunded. | ## Graduated autonomy level Applies to: Agent Pay policy. Requires execution (not enabled). Levels are computed and recorded for policy review. They never approve a payment. Every payment still needs human approval, and a level never overrides a policy deny, a block list, or a velocity cap. | Value | Meaning | |---|---| | `L0` | Lowest level: no history, a policy or list miss, or a velocity cap hit. | | `L1` | Known or allow-listed merchant with thin history, small amounts. | | `L2` | Good history and moderate frequency, larger amounts. | | `L3` | Highest level: strong history and an allow-listed merchant. | ## Settlement terminal status Applies to: Execution and settlement. Requires execution (not enabled). Values exist in code only. | Value | Meaning | |---|---| | `completed` | Reserved for confirmed provider success. | | `failed` | Reserved for a failed execution attempt. | --- title: Wallet status description: Read an AI Agent's Crossmint staging wallet status with get_wallet_status. Status only, with no balances or money movement. url: https://thepoints.io/docs/agents/wallet-status audience: [agents, operators] status: Live (limited) --- # Wallet status > **Agent Pay status:** Approve does not execute. Execution: not enabled. ACH settlement: not enabled. prepare_payment never moves money. Machine-readable: [/docs/agents/status.json](/docs/agents/status.json). An agent can read the status of its Crossmint staging wallet. This is status only: POINTS makes no custody, balance, or money-movement claims for this wallet. Read the [Crossmint wallet disclosure](/legal/crossmint-wallet-disclosure) before connecting one. ## get_wallet_status - Scope: `module-status:read`. No arguments. - Reads the stored status for the AI Agent on the connected account (the earliest one, if there are several). It does not fetch anything live. - Never returns balances, raw wallet addresses, or wallet identifiers. ```json { "connectionStatus": "connected", "provider": "crossmint", "environment": "staging", "blockchain": "solana", "walletType": "smart_wallet", "verificationStatus": "verified", "unavailableReason": null } ``` `environment` is always `staging`. ## Wallet states | `connectionStatus` | Meaning | |---|---| | `not_connected` | No wallet is connected for this AI Agent | | `pending` | Setup started and is not verified yet | | `connected` | A staging wallet is connected and verified | | `unavailable` | Status can't be read right now; `unavailableReason` says why | | `error` | The last status check failed; `unavailableReason` says why | `verificationStatus` is one of `not_verified`, `pending`, `verified`, or `failed`. ## action_required `get_account_status` reports each account module, including `wallet`. A wallet module in `action_required` means the account owner needs to act in POINTS, for example to re-authorize the wallet. The agent can't fix it, so tell the user to open POINTS. All values are generated from code in [Statuses](/docs/agents/reference/statuses). --- title: Consumers description: What POINTS offers individuals today, labelled by status. url: https://thepoints.io/docs/consumers audience: [consumers] --- # Consumers Consumer products are a later phase for POINTS. Pages on the site that show consumer features are demos or previews. | Product | Status | |---|---| | Points Pay send demo at [/send](/send) | Demo (no real money) | | Smart checking and rewards exchange | Later | See [Consumers](/consumers) for the current consumer overview. --- title: Developers description: The public developer surface today is the Points MCP server and its OAuth discovery. url: https://thepoints.io/docs/developers audience: [developers] --- # Developers The public developer surface today is the Points MCP server, its OAuth endpoints, and the discovery documents. Start with [For Agents](/docs/agents) and the [MCP & API reference](/docs/agents/reference). | Item | Status | |---|---| | Points MCP server and OAuth discovery | Live | | PTS gaming rewards, Forex, public SDK | Later | POINTS is talking with design partners about later developer products. Contact [support](/support) if you are interested. --- title: Merchants description: POINTS POS and the Merchant Dashboard, with honest status for each merchant product. url: https://thepoints.io/docs/merchants audience: [merchants] status: Live (limited) --- # Merchants The Points Merchant Dashboard and POINTS POS onboarding preparation are on production with limits. Merchant applications are reviewed by the POINTS team, provider onboarding automation is off on production, and card processing is not live yet. | Product | Status | |---|---| | Merchant Dashboard and POINTS POS onboarding preparation | Live (limited) | | Online payments and checkout | Planned | | Merchant loyalty and rewards | Planned | To apply, start at [POINTS POS](/points-pos) or [Merchant payments](/merchants). Detailed merchant guides will be added to this section. # POINTS changelog What shipped to production at thepoints.io, by commit. Dates are America/Phoenix. ## 2026-10-07: Blog: five user-group posts and a footer Products section PR #63 · commit `bd5d4d6` Five blog posts, one each for AI agents, agent operators, merchants, consumers, and developers, plus a Products section in the site footer. No change to product behavior. ## 2026-10-07: UC-21: saved-payee cycle drafts and an admin mandate view PR #61 · commit `2fbda2d` Mandate cycles can be drafted to a saved payee and need a fresh human approval each cycle. Approvals expire after 1 hour by default, and there's no automatic cycle scheduler yet. Money doesn't move while execution is not enabled. Adds a session-authenticated route that drafts a cycle payment to a saved payee, a read-only internal admin view of mandates for POINTS staff, and refuses a cycle claim made before the cycle date with HTTP 409. ## 2026-10-07: UC-21: authenticated mandate routes PR #60 · commit `be3e5b5` Session-authenticated API routes (not available over MCP) to create, list, read, prepare, skip, and cancel recurring payment mandates, plus attach and claim routes for cycles. A claim records the claim only, returns executed: false, and does not move money. ## 2026-10-07: UC-21 follow-ups PR #59 · commit `209d7f6` Expired or revoked cycle approvals can be reopened only with a fresh approval; cycles that may have been attempted are marked refused. Attaching a payment requires the mandate amount, currency, and payee to match, and claims re-check UC-26 scope (per-payment limits and the counterparty allow-list; usage across payments is not persisted yet). Unattended claims are refused unless the authorization allows them. Transaction errors are logged by type without secrets. ## 2026-10-07: Test suite fixes PR #58 · commit `3f7e262` Updated outdated unit tests; no change to product behavior. ## 2026-10-07: UC-21 recurring mandate hardening PR #57 · commit `51cfb7e` Only the mandate owner or the recorded approver can attach an approval. Mandate rows are locked during changes, a retried prepare returns the same cycle, and a claim and the move to the next cycle date commit together. ## 2026-10-05: UC-21: recurring mandates with a fresh approval each cycle PR #55 · commit `d359aa1` Adds recurring payment mandates and cycles. A mandate is not a standing approval: each cycle needs its own fresh, unused human approval, and prepare or claim is refused without one. Approve does not execute. Execution: not enabled. ## 2026-10-05: UC-26: approval scope on spend envelopes PR #56 · commit `fb31df1` Spend envelopes can carry a payment-count cap, a total cap, and a counterparty allow-list (empty means the approved payee only). Reusing an interactive approval unattended is refused by default. Aggregate caps are in progress: usage across multiple payments is not persisted yet. ## 2026-10-05: UC-22: spend envelope and approval ledger PR #53 · commit `8399901` Approving a draft records a signed spend envelope, and every decision (approved, revoked, expired, denied) is appended to an approval ledger. A human still approves from the draft. Approve does not execute. ## 2026-10-02: Payee external account id field PR #52 · commit `07de613` Payees can store the ACH provider's external account id, set by staff or the account owner. Only the id is stored, never routing or account numbers, and no payment path reads it yet. ACH settlement: not enabled. ## 2026-10-02: get_payment_status reports revoked PR #47 · commit `5e30a4e` get_payment_status now returns the revoked status for a revoked authorization instead of a tool error. ## 2026-10-02: Policy schema versioning PR #46 · commit `220cc20` Policy vocabulary responses and prepared drafts carry a policy schema version. A client that sends an unsupported version is refused before any spend is reserved. ## 2026-10-02: Revocation and zero clock skew PR #45 · commit `e42af70` An approved authorization that has not executed can be revoked; its status becomes revoked and its signature is cleared. Expiry checks allow zero clock skew. ## 2026-10-02: Cash bucket accounting PR #44 · commit `204b5dc` Spend accounting separates unreserved, reserved, and escrowed cash, so outstanding drafts and holds are not counted as spendable. The available balance shown is unreserved cash only. ## 2026-10-02: Read-time expiry from executableUntil PR #43 · commit `b00b03e` An approved authorization past its executableUntil time reads as expired immediately, and its reserved spend is released. ## 2026-10-02: Atomic reserve to settle PR #42 · commit `249b991` Preparing and approving a draft, and the settlement step, use row locks and conditional updates, so concurrent requests cannot reserve the same spend twice. A lost race is refused. ## 2026-10-02: ACH scaffolding (fail-closed) PR #41 · commit `6e2aaa2` Internal ACH provider scaffolding. Every ACH path is refused by default. ACH settlement: not enabled. ## 2026-10-02: P2: escrow, charge on 2xx, graduated autonomy PR #40 · commit `07f2c71` Code for escrow before work, charging only after an HTTP 2xx with the fee taken before sending, and graduated autonomy by merchant, amount, frequency, and history. These patterns require execution (not enabled). ## 2026-10-02: P1: spend reservation, policy vocabulary, velocity caps PR #39 · commit `63f4546` Stale pending drafts expire, and outstanding drafts reserve spend against daily and monthly limits. The canonical payment-category vocabulary is available over MCP, and unknown categories are denied. Velocity and anti-fragmentation caps apply. Approve does not execute. ## 2026-10-02: P0: signed authorization envelope PR #38 · commit `c9c3459` Approving a draft produces a signed authorization envelope covering amount, payee, asset, and expiry. Any mismatch, expiry, or missing key is refused. Approve does not execute. Execution: not enabled.