Administration

Select a person

Card controls

Developer reference

Developer platform

SimplePay APIs

Peer-to-peer card transactions and card controls. No authentication, no API keys, no rate limits. Everything lives under https://bank.decagon.tools.

Connect the MCP server to Claude Code

This is the fastest way to use SimplePay. The MCP server URL is:

https://bank.decagon.tools/api/public/mcp

Step 1 — run one command in your terminal

claude mcp add --transport http simplepay https://bank.decagon.tools/api/public/mcp

Step 2 — that's it

Restart Claude Code (or run claude mcp list to confirm it registered). Then just ask in plain language, for example:

  • "List the SimplePay users."
  • "Get Toby Tyler's transactions for September 2026."
  • "Show me pending payments for usr_toby_tyler_2254."

Prefer a config file?

Add this to .mcp.json (project) or claude_desktop_config.json:

{
  "mcpServers": {
    "simplepay": {
      "type": "http",
      "url": "https://bank.decagon.tools/api/public/mcp"
    }
  }
}

The MCP server exposes tools to list_users (discover user IDs) and get_transactions (lookup by user ID with optional date range and merchant filter), use get_transaction for a single payment, and close_cards or reset_cards to control card status. Full details are in the reference below.

REST API quick start

One endpoint, no auth. Pass a user ID and optional date range:

curl "https://bank.decagon.tools/api/public/transactions?user_id=usr_toby_tyler_2254&from=2026-09-01&to=2026-09-30"

Full reference

# SimplePay API

Peer-to-peer card transaction and card-status data. No authentication, no API keys, no rate limits.

Base URL: `https://bank.decagon.tools`

## Connect the MCP server (Claude Code)

SimplePay exposes a Model Context Protocol server so agents such as Claude Code can call it directly as a tool. No authentication.

- MCP endpoint: `POST https://bank.decagon.tools/api/public/mcp` (streamable HTTP / JSON-RPC 2.0)
- `GET https://bank.decagon.tools/api/public/mcp` for a plain JSON description of the server.

### Option 1 — one terminal command

```bash
claude mcp add --transport http simplepay https://bank.decagon.tools/api/public/mcp
```

That's it. Restart Claude Code (or run `claude mcp list` to confirm), then ask it things like "list the SimplePay users" or "get Toby Tyler's transactions for September 2026".

### Option 2 — config file

Add this to `.mcp.json` (project) or `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "simplepay": {
      "type": "http",
      "url": "https://bank.decagon.tools/api/public/mcp"
    }
  }
}
```

### MCP tools

**`list_users`** — no arguments. Lists every person with their string user ID, name, account number, email and phone. Use this first to discover a `user_id`.

**`get_transactions`** — look up transactions by user ID and date range.

| Argument | Required | Notes |
| --- | --- | --- |
| `user_id` | yes | String user ID (e.g. `usr_toby_tyler_2254`) or internal UUID. |
| `from` | no | Inclusive start date/time, ISO 8601. |
| `to` | no | Inclusive end date/time, ISO 8601. |
| `merchant_name` | no | Filter by counterparty/merchant name, case-insensitive partial match. |
| `limit` | no | 1–1000, default 500. |

**`get_transaction`** — fetch one transaction's full details. Single required argument `transaction_id` (the `transaction_id` returned by `get_transactions`).

**`close_cards`** — close a person's card and immediately issue and ship a replacement. Single required argument `user_id`. The response includes `new_card_issued: true`, `new_card_shipped: true`, and a new card with `shipping_status: "in_transit"`, number, expiration, and security code. Running it again replaces the previously issued card with another new one, so a person never has more than one closed card and one new card.

**`reset_cards`** — reset one person: reopen their card, delete their issued replacement card, reset their SMS history to three OTPs, and remove their transactions added after the demo baseline. Arguments: `user_id` (required).

**`send_sms`** — send an SMS to a person; it is appended to their SMS history. Required `user_id` and `message`, optional `sender` (defaults to `SimplePay`).

**`get_sms_messages`** — read a person's SMS history, newest first. Required `user_id`, optional `limit` (1–500, default 50).

All tools return compact JSON text content with the same shape as the matching REST endpoint (no whitespace padding, single `transaction_id` key) to keep token counts low for agents. Failures come back as a tool result with `isError: true` and an `error` message.

### Raw JSON-RPC example (no MCP client needed)

```bash
curl -X POST "https://bank.decagon.tools/api/public/mcp" \
  -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_transactions","arguments":{"user_id":"usr_toby_tyler_2254","from":"2026-09-01","to":"2026-09-30"}}}'
```

Supported methods: `initialize`, `tools/list`, `tools/call`, `ping`.

## GET /api/public/transactions

Returns every transaction for one person, newest first.

### Query parameters

| Name | Required | Notes |
| --- | --- | --- |
| `user_id` | yes | The person's string user ID (e.g. `usr_toby_tyler_2254`). The internal UUID also works. Alias: `userId`. |
| `from` | no | Inclusive start date/time, ISO 8601 (`2026-09-01` or `2026-09-01T00:00:00Z`). Alias: `start_date`. |
| `to` | no | Inclusive end date/time, ISO 8601. Alias: `end_date`. |
| `merchant_name` | no | Filter by counterparty/merchant name, case-insensitive partial match. Alias: `merchant`. |
| `limit` | no | 1–1000, default 500. |

### Example

```bash
curl "https://bank.decagon.tools/api/public/transactions?user_id=usr_toby_tyler_2254&from=2026-09-01&to=2026-09-30"
```

### Response

```json
{"user_id":"usr_toby_tyler_2254","user_name":"Toby Tyler","account_number":"7131463462","count":1,"transactions":[{"transaction_id":"a7963676-9d48-4d4c-b9e8-191d7ba9d4ec","amount":42.18,"date":"2026-09-16T16:51:14.317364+00:00","merchant_name":"Jordan Avery","type":"USD","currency_code":"USD","status":"posted"}]}
```

Responses are compact JSON (no whitespace padding) to keep token counts low for agents.

### Field reference

- `transaction_id` — the transaction's unique ID. Use it with `GET /api/public/transactions/{transaction_id}`.
- `amount` — number. Up to 8 decimal places for crypto, 2 for USD.
- `date` — ISO 8601 timestamp of the transaction.
- `merchant_name` — counterparty (a person for p2p transfers, or a merchant).
- `type` — `USD` | `crypto`.
- `currency_code` — `USD`, `BTC`, `ETH`, `USDC`, `SOL`.
- `status` — `pending` | `posted` | `declined` | `refunded`.

### Errors

| Status | Body | Meaning |
| --- | --- | --- |
| 400 | `{"error":"user_id query parameter is required"}` | Missing `user_id`. |
| 404 | `{"error":"Unknown user_id"}` | No person with that ID. |
| 500 | `{"error":"..."}` | Server-side failure. |

CORS is open (`Access-Control-Allow-Origin: *`); `OPTIONS` returns 204.

## POST /api/public/cards/close

Closes the person's card, issues a replacement, and marks the new card shipped and in transit in the same call. Send the person's string user ID as JSON.

A person ends up with exactly two cards: the closed original and the newly issued card. Calling this again replaces the previously issued card with another new one.

```bash
curl -X POST "https://bank.decagon.tools/api/public/cards/close" \
  -H "content-type: application/json" \
  -d '{"user_id":"usr_toby_tyler_2254"}'
```

```json
{"user_id":"usr_toby_tyler_2254","status":"closed","cards_closed":1,"new_card_issued":true,"new_card_shipped":true,"new_card":{"card_number":"4242817305946120","expiration_month":"07","expiration_year":"32","security_code":"418","status":"open","shipping_status":"in_transit"}}
```

## POST /api/public/cards/reset

Resets a single person: reopens their card, deletes their issued replacement card, resets their SMS history to just three one-time passcodes, and removes their transactions added after the demo baseline. Other people are untouched. Body: `{"user_id":"..."}` (required).

```bash
curl -X POST "https://bank.decagon.tools/api/public/cards/reset" -H "content-type: application/json" -d '{"user_id":"usr_toby_tyler_2254"}'
```

```json
{"user_id":"usr_toby_tyler_2254","status":"open","cards_reset":1,"issued_cards_removed":1,"sms_reset":3,"transactions_removed":2}
```

## GET /api/public/transactions/{transaction_id}

Returns the full details of a single transaction, including which person it belongs to. No query parameters, no auth.

```bash
curl "https://bank.decagon.tools/api/public/transactions/a7963676-9d48-4d4c-b9e8-191d7ba9d4ec"
```

```json
{"transaction":{"transaction_id":"a7963676-9d48-4d4c-b9e8-191d7ba9d4ec","amount":42.18,"date":"2026-09-16T16:51:14.317364+00:00","merchant_name":"Jordan Avery","type":"USD","currency_code":"USD","status":"posted","created_at":"2026-09-16T16:51:14.317364+00:00","user_id":"usr_toby_tyler_2254","user_name":"Toby Tyler","account_number":"7131463462"}}
```

| Status | Body | Meaning |
| --- | --- | --- |
| 400 | `{"error":"Invalid transaction id"}` | Not a valid transaction ID. |
| 404 | `{"error":"Unknown transaction id"}` | No transaction with that ID. |

## POST /api/public/transactions/create

Posts a new transaction for a person. It appears in the SimplePay Backend ledger immediately.

| Field | Required | Notes |
| --- | --- | --- |
| `user_id` | yes | String user ID (e.g. `usr_toby_tyler_2254`) or internal UUID. |
| `amount` | yes | Transaction amount. |
| `merchant_name` | yes | Counterparty or merchant name (alias `merchant`). |
| `date` | no | ISO 8601 date/time. Defaults to now. |
| `account_type` | no | `business` or `merchant`. Defaults to `business`. |
| `type` | no | `USD` or `crypto`. Defaults to `USD`. |
| `currency_code` | no | `USD`, `BTC`, `ETH`, `USDC`, `SOL`. |
| `status` | no | `pending`, `posted`, `declined`, `refunded`. Defaults to `pending`. |

```bash
curl -X POST "https://bank.decagon.tools/api/public/transactions/create" \
  -H "content-type: application/json" \
  -d '{"user_id":"usr_toby_tyler_2254","amount":42.18,"merchant_name":"Jordan Avery","status":"pending"}'
```

```json
{"success":true,"user_id":"usr_toby_tyler_2254","transaction":{"transaction_id":"a7963676-9d48-4d4c-b9e8-191d7ba9d4ec","amount":42.18,"date":"2026-09-21T04:12:00.000Z","merchant_name":"Jordan Avery","type":"USD","currency_code":"USD","status":"pending"}}
```

| Status | Body | Meaning |
| --- | --- | --- |
| 400 | `{"error":"user_id, amount and merchant_name are required"}` | Missing or invalid field. |
| 404 | `{"error":"Unknown user_id"}` | No person with that user ID. |

## POST /api/public/sms/send

Sends an SMS to a person. The message is appended to that person's SMS history and shows up immediately in the SimplePay Backend SMS sidebar.

| Field | Required | Notes |
| --- | --- | --- |
| `user_id` | yes | String user ID (e.g. `usr_toby_tyler_2254`) or internal UUID. |
| `message` | yes | The SMS text, up to 1000 characters. |
| `sender` | no | Sender name or shortcode shown on the message. Defaults to `SimplePay`. |

```bash
curl -X POST "https://bank.decagon.tools/api/public/sms/send" \
  -H "content-type: application/json" \
  -d '{"user_id":"usr_toby_tyler_2254","message":"Your SimplePay one-time passcode is 204-118."}'
```

```json
{"success":true,"message_id":"7f1c...","user_id":"usr_toby_tyler_2254","recipient_phone":"612-554-0419","sender":"SimplePay","message":"Your SimplePay one-time passcode is 204-118.","sent_at":"2026-09-18T18:02:11.204Z"}
```

| Status | Body | Meaning |
| --- | --- | --- |
| 400 | `{"error":"user_id and message are required"}` | Missing or empty field. |
| 404 | `{"error":"Unknown user_id"}` | No person with that user ID. |

## GET /api/public/sms

Reads a person's SMS history, newest first.

```bash
curl "https://bank.decagon.tools/api/public/sms?user_id=usr_toby_tyler_2254&limit=20"
```

```json
{"user_id":"usr_toby_tyler_2254","recipient_phone":"612-554-0419","count":2,"messages":[{"message_id":"7f1c...","direction":"outbound","sender":"SimplePay","message":"Your SimplePay one-time passcode is 204-118.","sent_at":"2026-09-18T18:02:11.204Z"}]}
```

## Machine-readable endpoints

- `GET https://bank.decagon.tools/api/public/docs` — this document as Markdown (`?format=json` for JSON).
- `GET https://bank.decagon.tools/api/public/openapi.json` — OpenAPI 3.1 spec.
- `POST https://bank.decagon.tools/api/public/mcp` — MCP server (see above).