# RedVPN

> RedVPN is a VPN for people who need the open internet. Prepaid Premium periods (no subscription, no auto-renewal) can be bought by AI agents on behalf of a human through the Agentic Commerce Protocol (ACP) endpoints below or a short REST flow; delivery is instant: an account code plus connection credentials.

## Products and prices

- `usd-monthly` — 1 month: 3.99 USD (one-time, no auto-renew)
- `usd-year` — 1 year: 39.99 USD (one-time, no auto-renew)

Item ids are the `line_items[].id` values for checkout. Prices are in minor units in the API (`unit_amount`), major units here.

## Buy as an agent (short version)

1. Get an agent API key from the operator (`support@vpn.red`) — `Authorization: Bearer rvk_…` on every call. Keys are rate-limited.
2. `POST https://vpn.red/agentic/checkout_sessions` with `Idempotency-Key` and body `{"line_items":[{"id":"usd-monthly"}],"currency":"usd","buyer":{"email":"human@example.com"},"capabilities":{}}` → `status: ready_for_payment` and `capabilities.payment.handlers`.
3. `POST https://vpn.red/agentic/checkout_sessions/{id}/complete` with `payment_data`:
   - Stripe Shared Payment Token (ChatGPT / any agent holding one): `{"handler_id":"card_spt","instrument":{"type":"card","credential":{"type":"spt","token":"spt_…"}}}` → `status: completed`, `order` present.
   - No token: `{"handler_id":"card_hosted"}` → `status: complete_in_progress` + `continue_url`. Show the URL to the human, then poll `GET https://vpn.red/agentic/checkout_sessions/{id}` until `completed`.
4. Read the delivery: `order.fulfillments[0].digital_delivery.license_key` is the account code, `metadata.redvpn` has `cid`, `account_code`, `paid_until`, `profile` (redsocket endpoints + server public key) and `profile_url`.

## How the human redeems

- Install RedVPN (Android, iOS, macOS, Windows). Open Sign in › Account code, enter the code. Premium is active until `paid_until`.
- Linux CLI: `redvpn login --cid <cid>`.
- If an email was given at checkout, the same receipt (code + steps) is emailed and `https://vpn.red/me` shows the order after signing in with that address.

## Links

- [Discovery document](https://vpn.red/.well-known/acp.json): protocol version, API base URL, services.
- [OpenAPI for the agent endpoints](https://vpn.red/agentic/openapi.json)
- [ACP product feed](https://vpn.red/agentic/feed.json) and [OpenAI feed lines](https://vpn.red/agentic/feed.jsonl)
- [Human-readable page](https://vpn.red/agents)
- [Privacy](https://vpn.red/privacy)

## Optional

- [Full agent guide](https://vpn.red/llms-full.txt): every endpoint, every field, MCP server configuration, error codes.

---

# Full reference

Protocol: Agentic Commerce Protocol, API-Version `2026-04-17` (send it as the `API-Version` header; a missing header means the latest). Spec: https://github.com/agentic-commerce-protocol/agentic-commerce-protocol (spec/2026-04-17).

## Headers

- `Authorization: Bearer rvk_…` (required)
- `Idempotency-Key: <opaque, ≤255 chars>` (required on every POST; same key + same body replays with `Idempotent-Replayed: true`; same key + different body → 422 `idempotency_conflict`)
- `API-Version: 2026-04-17`, `Request-Id`, `Accept-Language`, `User-Agent` (optional; echoed where the spec says so)
- `Signature` + `Timestamp`: only enforced for keys the operator configured with a signing secret: base64(HMAC-SHA256(secret, Timestamp + "." + body)).

## Endpoints

- `POST https://vpn.red/agentic/checkout_sessions` → 201 CheckoutSession. Body: `line_items[]` (`{id, quantity?}`; `items[]` from the 2025-09-29 spec is accepted too), `currency` (lowercase ISO 4217; must match the item), `buyer` (`email`, `full_name`/`first_name`+`last_name`, `phone_number`), `capabilities`, `metadata`, `locale`. Exactly one item, quantity 1 — one prepaid period per session; otherwise `status: not_ready_for_payment` with `messages[].code = quantity_exceeded`.
- `GET https://vpn.red/agentic/checkout_sessions/{id}` → the session; 404 for unknown ids and for sessions of other keys.
- `POST https://vpn.red/agentic/checkout_sessions/{id}` → update `buyer`, `line_items`, `currency`, `metadata`.
- `POST https://vpn.red/agentic/checkout_sessions/{id}/complete` → body `payment_data` (+ optional `buyer`). Handlers available now:
- `card_spt` (dev.acp.tokenized.card, psp stripe, delegate_payment=true): Card (Stripe Shared Payment Token)
- `card_hosted` (red.vpn.hosted.card, psp stripe, delegate_payment=false): Card (hosted Stripe Checkout page for the human)
  Legacy `payment_data: {"token": "spt_…", "provider": "stripe"}` is mapped to `card_spt`. A decline comes back as 200 with `messages[]` `{type: error, code: payment_declined}` and `status: ready_for_payment` — retry with another instrument. Already-completed sessions return the same completed view.
- `POST https://vpn.red/agentic/checkout_sessions/{id}/cancel` → `status: canceled`; 405 once completed or canceled.
- `GET https://vpn.red/agentic/orders/{order_no}` → `{order, checkout_session_id, status, redvpn?}`; `redvpn` holds the fulfilment once paid.

## Session statuses used

`ready_for_payment`, `not_ready_for_payment`, `complete_in_progress` (hosted card or crypto: pay at `continue_url`, then poll), `completed`, `canceled`, `expired` (sessions live 60 minutes before payment).

## Fulfilment object (`metadata.redvpn`)

`order_no`, `brand`, `plan`, `period`, `cid`, `account_code`, `tier`, `paid_until` (RFC 3339 or null for lifetime), `profile` (`{protocol: "redsocket", cid, server_pubkey, pops: [{code, label, entries: [{host, port, protocol}]}]}`), `profile_url`, `redeem` (`app`, `cli`, `web`, `config`). The same credentials the apps and the CLI consume; the cid is the credential, the account code moves it to another device.

## Error object

4xx/5xx bodies are `{type: invalid_request | processing_error | service_unavailable, code, message, param?}`. Codes you will see: `unauthorized` (401), `rate_limited` (429, with `Retry-After`), `idempotency_key_required` (400), `idempotency_conflict` (422), `unsupported_api_version` (400, with `supported_versions`), `invalid_item_id` (400), `session_not_found` / `order_not_found` (404), `unknown_handler` (400), `session_not_cancelable` (405), `psp_unavailable` (503), `psp_error` (502).

## MCP server

A stdio MCP server ships with the cashier (`python -m app mcp`), tools `list_plans`, `create_checkout`, `complete_checkout`, `get_order`. It talks to this API with your key; configure the host with env `REDVPN_API_BASE=https://vpn.red` and `REDVPN_AGENT_KEY=rvk_…`. Example (Claude Desktop / Claude Code style):

    {"mcpServers": {"redvpn": {"command": "python", "args": ["-m", "app", "mcp"], "cwd": "/path/to/cashier-01", "env": {"REDVPN_API_BASE": "https://vpn.red", "REDVPN_AGENT_KEY": "rvk_…"}}}}

## Discovery

`https://vpn.red/.well-known/acp.json` — `protocol.supported_versions`, `api_base_url` (`https://vpn.red/agentic`), `transports: ["rest"]`, `capabilities.services: ["checkout"]`. No `/.well-known/ucp` (Google's Universal Commerce Protocol is a different schema; not implemented yet).

## Support

support@vpn.red · https://vpn.red/agents
