Endpoints#

Complete API reference for all PayWatcher endpoints.

Overview#

Base URL#

bash
https://api.masem.at

All endpoints are relative to this base URL (e.g. https://api.masem.at/v1/payments).

Authentication#

Every request requires an API key in the x-api-key header:

bash
curl https://api.masem.at/v1/payments \
  -H "x-api-key: mms_paywatcher_YOUR_API_KEY"

Response Format#

All responses use an envelope format:

Single object:

json
{
  "data": { ... }
}

List with pagination:

json
{
  "data": [ ... ],
  "meta": {
    "page": 1,
    "limit": 25,
    "total": 142
  }
}

Error:

json
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
}

Error Codes#

HTTP StatusCodeDescription
400 / 422VALIDATION_ERRORInvalid request parameters or body
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENAPI key lacks required scope
404NOT_FOUNDResource does not exist
500INTERNAL_ERRORServer error — retry later

Create Payment#

POST /v1/payments

Create a new payment intent. Returns a payment object with a unique exactAmount and depositAddress for your customer.

Request Body#

FieldTypeRequiredDescription
amountstringYesAmount in USDC (e.g. "49.00")
currencystringYesCurrency code — only "USDC" supported
chainstringYesBlockchain network (e.g. "base") — see Supported Networks. Same value as network
networkstringNoPreferred alias for chain. If both are provided, network takes precedence. Defaults to "base". Supported: base, ethereum, arbitrum, optimism, polygon
metadataobjectNoKey-value pairs for your reference (max 10 keys)
expires_innumberNoSeconds until expiry (default: 3600 = 1 hour)
webhook_urlstringNoOverride the global webhook URL for this payment

Response#

json
{
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "amount": "49.00",
    "exactAmount": "49.000042",
    "status": "pending",
    "depositAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
    "currency": "USDC",
    "chain": "base",
    "network": "base",
    "chainId": 8453,
    "explorerUrl": null,
    "confirmations": 0,
    "confirmationsRequired": 6,
    "txHash": null,
    "metadata": {
      "order_id": "ORD-123",
      "customer": "john@example.com"
    },
    "expiresAt": "2026-01-15T11:00:00Z",
    "createdAt": "2026-01-15T10:00:00Z",
    "updatedAt": "2026-01-15T10:00:00Z"
  }
}

Example#

bash
curl -X POST https://api.masem.at/v1/payments \
  -H "x-api-key: mms_paywatcher_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "49.00",
    "currency": "USDC",
    "chain": "base",
    "metadata": {
      "order_id": "ORD-123",
      "customer": "john@example.com"
    },
    "expires_in": 3600,
    "webhook_url": "https://your-app.com/webhook"
  }'

Get Payment#

GET /v1/payments/:id

Retrieve a single payment by its ID.

Path Parameters#

ParameterTypeDescription
idstringPayment UUID

Response#

json
{
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "amount": "49.00",
    "exactAmount": "49.000042",
    "status": "confirmed",
    "depositAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
    "currency": "USDC",
    "chain": "base",
    "network": "base",
    "chainId": 8453,
    "explorerUrl": "https://basescan.org/tx/0x7a3f9c2e1d4b5a6f8e0c3d2b1a9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1",
    "confirmations": 6,
    "confirmationsRequired": 6,
    "txHash": "0x7a3f9c2e1d4b5a6f8e0c3d2b1a9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1",
    "metadata": {
      "order_id": "ORD-123",
      "customer": "john@example.com"
    },
    "expiresAt": "2026-01-15T11:00:00Z",
    "createdAt": "2026-01-15T10:00:00Z",
    "updatedAt": "2026-01-15T10:05:00Z"
  }
}

Response Fields (Multi-Chain)#

FieldTypeDescription
networkstringBlockchain network identifier (e.g. "base", "ethereum", "arbitrum")
chainIdnumberEVM chain ID (e.g. 8453 for Base, 1 for Ethereum)
explorerUrlstring | nullDirect link to the transaction on the block explorer (null if no transaction yet)

Example#

bash
curl https://api.masem.at/v1/payments/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
  -H "x-api-key: mms_paywatcher_YOUR_API_KEY"

List Payments#

GET /v1/payments

List payments with optional filtering, sorting, and pagination.

Query Parameters#

ParameterTypeDefaultDescription
statusstringFilter by status (comma-separated, e.g. "pending,confirmed")
networkstringFilter by network (e.g. "base", "ethereum")
fromstringISO 8601 date — only payments created after this date
tostringISO 8601 date — only payments created before this date
pagenumber1Page number
limitnumber25Items per page (max: 100)
sortstring"created_at"Sort field (only "created_at" supported)
orderstring"desc"Sort direction: "asc" or "desc"

Response#

json
{
  "data": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "amount": "49.00",
      "exactAmount": "49.000042",
      "status": "confirmed",
      "depositAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
      "currency": "USDC",
      "chain": "base",
      "network": "base",
      "chainId": 8453,
      "explorerUrl": "https://basescan.org/tx/0x7a3f9c2e1d4b5a6f8e0c3d2b1a9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1",
      "confirmations": 6,
      "confirmationsRequired": 6,
      "txHash": "0x7a3f9c2e1d4b5a6f8e0c3d2b1a9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1",
      "metadata": null,
      "expiresAt": "2026-01-15T11:00:00Z",
      "createdAt": "2026-01-15T10:00:00Z",
      "updatedAt": "2026-01-15T10:05:00Z"
    }
  ],
  "meta": {
    "page": 1,
    "limit": 25,
    "total": 142
  }
}

Example#

bash
curl "https://api.masem.at/v1/payments?status=confirmed&limit=10&order=desc" \
  -H "x-api-key: mms_paywatcher_YOUR_API_KEY"

Webhook History#

GET /v1/payments/:id/webhooks

Retrieve the webhook delivery history for a specific payment.

This endpoint returns snake_case field names.

Path Parameters#

ParameterTypeDescription
idstringPayment UUID

Response#

json
{
  "data": [
    {
      "event": "payment.confirmed",
      "attempt_number": 1,
      "response_code": 200,
      "error": null,
      "created_at": "2026-01-15T10:05:00Z"
    }
  ]
}

Response Fields#

FieldTypeDescription
eventstringEvent type (e.g. "payment.confirmed")
attempt_numbernumberDelivery attempt number (starts at 1)
response_codenumber | nullHTTP status code from your server
errorstring | nullError message if delivery failed
created_atstringISO 8601 timestamp of the delivery attempt

Example#

bash
curl https://api.masem.at/v1/payments/a1b2c3d4-e5f6-7890-abcd-ef1234567890/webhooks \
  -H "x-api-key: mms_paywatcher_YOUR_API_KEY"

Read Config#

GET /v1/paywatcher/config

Retrieve the current tenant configuration.

This endpoint returns snake_case field names.

Response#

json
{
  "data": {
    "tenant_slug": "acme-corp",
    "tenant_name": "Acme Corp",
    "contact_email": "dev@acme.com",
    "tier": "starter",
    "deposit_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
    "confirmations": 6,
    "confirmation_override": null,
    "webhook_url": "https://acme.com/webhook",
    "enabled": true,
    "created_at": "2026-01-01T00:00:00Z",
    "updated_at": "2026-01-15T10:00:00Z"
  }
}

Response Fields#

FieldTypeDescription
tenant_slugstringUnique tenant identifier
tenant_namestringDisplay name
contact_emailstringContact email address
tierstringSubscription tier
deposit_addressstringYour own wallet address. PayWatcher monitors it but never holds funds.
confirmationsnumberDefault confirmation threshold
confirmation_overridenumber | nullCustom confirmation threshold (null = use default)
webhook_urlstring | nullGlobal webhook URL
enabledbooleanWhether the tenant is active
created_atstringISO 8601 creation timestamp
updated_atstringISO 8601 last update timestamp

Example#

bash
curl https://api.masem.at/v1/paywatcher/config \
  -H "x-api-key: mms_paywatcher_YOUR_API_KEY"

Update Config#

PATCH /v1/paywatcher/config

Update the tenant configuration. Only the fields you include in the request body will be updated.

This endpoint accepts and returns snake_case field names.

Request Body#

FieldTypeRequiredDescription
webhook_urlstringNoHTTPS URL for webhook deliveries
confirmation_overridenumber | nullNoCustom confirmation threshold (2–20), or null to reset to default (6)

Response#

Returns the full updated tenant config (same schema as Read Config).

json
{
  "data": {
    "tenant_slug": "acme-corp",
    "tenant_name": "Acme Corp",
    "contact_email": "dev@acme.com",
    "tier": "starter",
    "deposit_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18",
    "confirmations": 6,
    "confirmation_override": 12,
    "webhook_url": "https://acme.com/webhook",
    "enabled": true,
    "created_at": "2026-01-01T00:00:00Z",
    "updated_at": "2026-01-15T10:30:00Z"
  }
}

Example#

bash
curl -X PATCH https://api.masem.at/v1/paywatcher/config \
  -H "x-api-key: mms_paywatcher_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "webhook_url": "https://your-app.com/webhook",
    "confirmation_override": 12
  }'

Test Webhook#

POST /v1/paywatcher/config/test-webhook

Send a test webhook to your configured webhook URL to verify it's working.

This endpoint returns snake_case field names.

Request Body#

No request body required.

Response#

json
{
  "data": {
    "success": true,
    "response_code": 200,
    "error": null
  }
}

Response Fields#

FieldTypeDescription
successbooleanWhether the test webhook was delivered successfully
response_codenumber | nullHTTP status code from your server
errorstring | nullError message if delivery failed

Example#

bash
curl -X POST https://api.masem.at/v1/paywatcher/config/test-webhook \
  -H "x-api-key: mms_paywatcher_YOUR_API_KEY"

View API Key#

GET /v1/paywatcher/config/api-key

Retrieve your masked API key and its scopes.

This endpoint returns snake_case field names. The full API key is never returned — only a masked version.

Response#

json
{
  "data": {
    "masked_key": "mms_paywatcher_abc...xyz",
    "scopes": ["payments:read", "payments:write"],
    "created_at": "2026-01-15T10:00:00Z"
  }
}

Response Fields#

FieldTypeDescription
masked_keystringMasked API key (first and last characters visible)
scopesstring[]Permissions granted to this key
created_atstringISO 8601 timestamp when the key was created

Example#

bash
curl https://api.masem.at/v1/paywatcher/config/api-key \
  -H "x-api-key: mms_paywatcher_YOUR_API_KEY"

Next Steps#

  • Quick Start — Get started with your first payment in under 15 minutes
  • Webhooks — Webhook events, retry logic, and signature verification
  • Examples — Code examples in multiple languages