API Reference

Complete endpoint reference for the Unter payment gateway API.

Interactive API Documentation Explore the API interactively using the Swagger UI, available at /api/doc on your API instance.
Staging: api-staging.unter.tech/api/doc
Production: api.unter.tech/api/doc

Authentication

Authenticated endpoints require an API key sent via one of two headers:

HeaderFormat
X-API-Keyunter_<40 hex chars>
AuthorizationBearer unter_<40 hex chars>

Permissions

API keys are assigned specific permissions. Endpoints enforce permissions via attributes on the controller.

PermissionGrants Access To
create_paymentsCreating payment requests
view_paymentsListing and viewing payment requests
manage_paymentsUpdating and cancelling payment requests
manage_webhooksViewing, updating, and testing webhook settings

Endpoints marked "any" below require a valid API key but no specific permission.

Rate Limits

TierScopeLimitKey
Public readGET on /api/public/*60 / minClient IP
Public writePOST/PUT/PATCH/DELETE on /api/public/*20 / minClient IP
API keyAll /api/* (non-public)300 / minAPI key

When rate limited, the API returns HTTP 429 with Retry-After and X-RateLimit-Limit headers.

Public Endpoints

These endpoints require no authentication. They are used by the checkout widget and can be called from any origin.

MethodPathDescription
GET /api/health Health check. Returns {"status": "ok"}.
GET /api/public/chains List all supported blockchain networks.
GET /api/public/chains/{id} Get details for a specific chain.
GET /api/public/chains/{id}/tokens List tokens available on a specific chain.
GET /api/public/payment-requests/{id} View payment request details (by UUID or shortcode).
GET /api/public/payment-requests/{id}/status Get current payment status (for polling).
GET /api/public/payments/{id} View details for a specific payment.
POST /api/public/payment-requests/{id}/payments Submit a payment (transaction hash) for a payment request.
POST /api/public/payment-requests/{id}/routes Get available payment routes (swap/bridge options).
POST /api/public/payment-requests/{id}/balances/essential Quick balance check for connected wallet.
POST /api/public/payment-requests/{id}/balances/extended Full balance check with extended route options.
POST /api/public/build-transaction Build an unsigned blockchain transaction for wallet signing.
POST /api/public/check-approval Check if an ERC-20 token approval is needed.
POST /api/public/check-transaction-status Check on-chain transaction status.
POST /api/public/discover-wallet-tokens Discover tokens held by a wallet address.

Merchant Endpoints (Authenticated)

These endpoints require a valid API key via the X-API-Key or Authorization header.

Payment Requests

MethodPathPermissionDescription
POST /api/payment-requests create_payments Create a new payment request.
GET /api/payment-requests view_payments List all payment requests (filterable).
GET /api/payment-requests/{id} view_payments Get details for a specific payment request.
PATCH /api/payment-requests/{id} manage_payments Update a payment request.
POST /api/payment-requests/{id}/cancel manage_payments Cancel an active payment request.

Chains & Tokens

MethodPathPermissionDescription
GET /api/chains any List supported chains (authenticated view).
GET /api/chains/{id}/tokens any List tokens on a specific chain.

Webhooks

MethodPathPermissionDescription
GET /api/webhooks manage_webhooks Get current webhook configuration.
PUT /api/webhooks manage_webhooks Update webhook URL, secret, and event subscriptions.
POST /api/webhooks/test manage_webhooks Trigger a test webhook delivery.

Amount Format

All monetary amounts in API responses use a consistent structure:

{
  "raw": "1500000",
  "formatted": "1.500000",
  "decimals": 6
}
FieldTypeDescription
rawstringAmount in the token's smallest unit
formattedstringHuman-readable representation with full decimal precision
decimalsintNumber of decimal places for the token

The formatted field always includes trailing zeros to match the token's precision. For example, a token with 6 decimals will format 1000000 raw as "1.000000", not "1".

Address Validation

Wallet addresses submitted in payment requests are validated per chain type:

Chain TypeValidationExample
EVM (Ethereum, Polygon, Base, BSC)Hex, 42 chars: ^0x[0-9a-fA-F]{40}$0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
SolanaBase58, 32-44 charsEPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
TRONStarts with T, 34 charsTR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t