Paymod's API is not reachable right now: sign in, sign up, and dashboard actions won't work until it's back.

Documentation

Everything a human needs to set up Paymod and connect an agent to it. For an agent to read directly instead, point it at /SKILL.md.

Quickstart

  1. Sign up, then create an Agent Wallet from the dashboard (connects via Freighter; you own the key, not Paymod).
  2. Generate that wallet's credential, shown once.
  3. Set at least one policy rule scoped to that wallet (a daily limit, at minimum; an account-wide rule alone is a ceiling, not authority, and with nothing wallet-scoped configured every transfer is denied).
  4. Hand your agent the credential and point it at the API, the MCP server, or the SDK below.
curl -X POST http://localhost:3001/v1/transfers \
  -H "Authorization: Bearer pm_live_..." \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"amount":"1000000","destination":"G..."}'

Authentication

Two separate credential types, for two separate callers:

  • Wallet credentials (pm_live_...): for agents. Bearer token on every financial API call, scoped to exactly one Agent Wallet. Generated once from the dashboard's Wallets page or via POST /v1/wallets/:id/credentials; the secret is shown exactly once and never stored in recoverable form.
  • Sessions: for humans, via the dashboard. An httpOnly cookie set by POST /v1/auth/login, scoped to the signed-in user's one account.

REST API

Every endpoint is under /v1. Financial writes require an Idempotency-Key header: replaying the same key with the same body returns the cached result; the same key with a different body is a conflict.

Financial intents (wallet credential)

POST /v1/transfers: request a transfer. Returns AUTHORIZED, WAITING_APPROVAL, or DENIED.

GET /v1/intents/:id: look up an intent's decision and settlement.

GET /v1/budget: remaining daily/monthly budget for the calling wallet.

GET /v1/wallet/balance: the calling wallet's own contract balance.

POST /v1/x402/fetch: fetch a paywalled URL, paying automatically under policy if it returns 402.

Account management (session, or bootstrap token for ops)

GET/PUT /v1/policies?accountId=...: list or upsert spend rules, optionally scoped to a wallet.

GET/POST /v1/wallets?accountId=...: list or create Agent Wallets.

GET /v1/wallets/:id?accountId=...: a single wallet's status and contract details.

GET /v1/wallets/:id/balance?accountId=...: that wallet's live on-chain balance.

POST /v1/wallets/:id/activate: verify an already-deployed wallet contract and activate it.

POST /v1/wallets/:id/credentials: issue a new credential for a wallet.

GET /v1/audit?accountId=...: the account's append-only audit log.

Auth

POST /v1/auth/signup: create a user and their one account.

POST /v1/auth/login · POST /v1/auth/logout · GET /v1/auth/me

Public

GET /v1/config: chain config a browser needs to build a wallet deploy transaction (executor key, USDC contract, wallet WASM hash).

MCP Server

@paymod/mcp-server exposes Paymod as tools any MCP-compatible agent (Claude Desktop, etc.) can call directly: paymod_get_balance, paymod_get_budget, paymod_transfer, paymod_get_request_status, paymod_pay_x402.

{
  "mcpServers": {
    "paymod": {
      "command": "npx",
      "args": ["tsx", "/path/to/paymod/apps/mcp-server/dist/index.js"],
      "env": {
        "PAYMOD_API_KEY": "pm_live_...",
        "PAYMOD_API_URL": "http://localhost:3001"
      }
    }
  }
}

SDK

@paymod/sdk: a typed client for Node/TypeScript agents that aren't going through MCP.

import { PaymodClient } from "@paymod/sdk";

const client = new PaymodClient({ apiKey: "pm_live_..." });
const budget = await client.getBudget();
const transfer = await client.transfer({ amount: "1000000", destination: "G..." });
const status = await client.waitForRequest(transfer.intentId);

Policy Types

Checked in this order: the first non-pass stage decides. Account suspended → wallet not active → no wallet-scoped spending authority (fails closed; an account-wide rule alone is never enough) → blocklists (never overridable) → budgets → per-transaction limit → allowlists → x402 autopay ceiling → approval threshold → allow.

  • DAILY_LIMIT / MONTHLY_LIMIT
  • PER_TRANSACTION_LIMIT
  • APPROVAL_THRESHOLD
  • X402_MAX_AUTOPAY
  • ASSET_ALLOWLIST / ASSET_BLOCKLIST
  • NETWORK_ALLOWLIST / NETWORK_BLOCKLIST
  • DESTINATION_ALLOWLIST / DESTINATION_BLOCKLIST
  • ACTION_ALLOWLIST / ACTION_BLOCKLIST