---
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": "<draft 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": "<ISO 8601 time>"
}
```

- 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": "<draft id>" }
```

```json
{
  "id": "<draft id>",
  "status": "approved",
  "amountCents": 2500,
  "currency": "USD",
  "createdAt": "<ISO 8601 time>",
  "expiresAt": "<ISO 8601 time>",
  "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.
