Phoenix Pay
API Reference

API Overview

Phoenix Pay REST API conventions, authentication, error handling, and pagination.

API Overview

The Phoenix Pay API is a JSON REST API. All endpoints return JSON responses and require a valid Zitadel bearer token for authentication (except the public signing key endpoint).

Base URL

https://pay.phoenixverse.io/api

All endpoint paths in this documentation are relative to this base URL.

Authentication

Every API request (except /api/.well-known/signing-key) must include a valid JWT access token in the Authorization header.

Authenticated request
curl https://pay.phoenixverse.io/api/deposits \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "Content-Type: application/json"

See the Authentication guide for details on obtaining and managing tokens.

Request Format

  • Content-Type: application/json for all POST/PUT requests
  • Character encoding: UTF-8
  • Amounts: Passed as decimal strings (e.g., "50.00", "0.001") to avoid floating-point precision issues
Example request body
{
  "reference_id": "order-12345",
  "amount": "50.00",
  "currency": "USDT"
}

Always send amounts as strings, not numbers. "50.00" is correct; 50.00 may lose precision during JSON parsing.

Response Format

All successful responses return JSON. Single-resource endpoints return the resource directly. List endpoints return a data array with a meta pagination object.

Single resource (200 OK)
{
  "id": "01912e4a-7b3c-7def-8a90-1234567890ab",
  "reference_id": "order-12345",
  "type": "deposit",
  "status": "awaiting_payment",
  "psp": "nowpayments",
  "requested_amount": "50.00",
  "received_amount": null,
  "currency": "USDT",
  "pay_currency": "usdttrc20",
  "pay_amount": "50.00",
  "checkout_url": null,
  "pay_address": "TXrk4d5x7Bj3e6g7Y8Zw...",
  "expires_at": "2026-03-11T14:30:00Z",
  "inserted_at": "2026-03-11T12:30:00Z",
  "updated_at": "2026-03-11T12:30:00Z"
}
List response (200 OK)
{
  "data": [
    {
      "id": "01912e4a-7b3c-7def-8a90-1234567890ab",
      "reference_id": "order-12345",
      "type": "deposit",
      "status": "settled",
      "..."
    },
    {
      "id": "01912e4b-8c4d-7def-9b01-2345678901bc",
      "reference_id": "order-12346",
      "type": "deposit",
      "status": "awaiting_payment",
      "..."
    }
  ],
  "meta": {
    "page": 1,
    "limit": 25,
    "total": 142,
    "total_pages": 6,
    "has_next": true,
    "has_prev": false
  }
}

Pagination

List endpoints use offset-based pagination with the following query parameters:

ParameterTypeDefaultMaxDescription
pageinteger1-Page number (1-indexed)
limitinteger25100Number of results per page

The response meta object contains:

FieldTypeDescription
pageintegerCurrent page number
limitintegerResults per page
totalintegerTotal number of matching records
total_pagesintegerTotal number of pages
has_nextbooleanWhether there is a next page
has_prevbooleanWhether there is a previous page
Paginated request
curl "https://pay.phoenixverse.io/api/deposits?page=2&limit=10" \
  -H "Authorization: Bearer <token>"

Error Format

Error responses include an error field with a human-readable message.

Error response
{
  "error": "missing required parameter: reference_id"
}

For validation errors (400) and processing errors (422), the error field describes what went wrong. For server errors (500), a generic "internal_error" message is returned.

Common HTTP Status Codes

StatusMeaning
200 OKRequest succeeded
201 CreatedResource created successfully (deposits, payouts)
400 Bad RequestMissing or invalid request parameters
401 UnauthorizedMissing or invalid authentication token
403 ForbiddenAuthenticated but insufficient permissions
404 Not FoundResource does not exist or belongs to a different tenant
422 Unprocessable EntityRequest was well-formed but could not be processed (e.g., no PSP configured for the requested currency)
500 Internal Server ErrorUnexpected server error

See the Status Codes page for a complete reference.

Rate Limiting

Phoenix Pay applies rate limiting to protect against abuse. Current limits:

Endpoint TypeLimit
Create endpoints (POST)100 requests/minute per tenant
Read endpoints (GET)300 requests/minute per tenant
Webhook endpointsUnlimited (PSP-initiated)

When rate limited, the API returns a 429 Too Many Requests response with a Retry-After header indicating when to retry.

Rate limits are applied per tenant (organization), not per token. Multiple service accounts under the same organization share the same rate limit.

API Endpoints

On this page