S
docs.syncra.money

Syncra Merchant API V2

Syncra Merchant API V2 — complete integration documentation

Merchant API V2

Welcome to the Syncra Merchant API V2 documentation. This API is built for merchants (online services, platforms, retailers) who need reliable and scalable real-time P2P payment processing.

With our API you can fully automate accepting payments (PayIn), sending payouts (PayOut), managing balances, tracking disputes, managing whitelist passes, and USDT crypto withdrawals.


Basic information

Base URL

All requests to Merchant API V2 go to the following base address:

https://api.syncra.money/api/v1/p2p/merchant

The legacy API version (V1) is available at https://api.syncra.money/v1/ for compatibility with previously integrated merchants only. The full V1 sunset date is January 12, 2027: after that date, all V1 requests return 410 Gone (until the shutdown, every V1 response carries the Deprecation, Sunset, and Link; rel="successor-version" headers). New customers are strongly encouraged to use the V2 endpoints on the main path from the start.

Data format

The interface is designed REST-first with JSON:

  • Requests must carry the Content-Type: application/json header.
  • All response bodies are JSON (except CSV export with Accept: text/csv).
  • Field names are snake_case.
  • Timestamps are ISO 8601 (for example, 2026-07-12T15:00:00Z).
  • Money amounts are int64 in minor units (kopecks/cents/satoshi); in API JSON responses, int64 values are passed as strings ("amount": "100000" — the proto3 JSON format, which prevents precision loss in JS clients). Webhook bodies carry amounts the same way, as strings (see Callbacks).
  • Successful responses use a single envelope per response type: a single object — directly ({"deal": {...}}); all listings (GET /deals, GET /callbacks, GET /payment-methods, GET /appeals, /passes, /banks, /currencies, /wallet/deposits, /wallet/withdrawals, /deals/turnover) — the single envelope {"data": [...], "next_page_token": ""} (AIP-158: an empty string = the last page; the envelope carries no other fields — total_count is not exposed over HTTP). The exception is GET /balance ({"wallets": [...]}): it is not a listing but a balance projection.
  • All errors (non-2xx) are RFC 9457 application/problem+json (see Error codes): type/title/status/detail (with nested gRPC details)/instance; tracing is via the X-Trace-Id header. An invalid request state (insufficient balance, a daily limit, a repeated appeal) → 400 (not 409).

Limits and rate limiting

To protect the platform, request rate limiting is enforced, configurable per merchant:

  • Default: 10,000 requests per minute per merchant token (the per-merchant rate_limit_per_minute; the window is a calendar UTC minute).

  • Every response carries the X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers (Unix seconds of the window reset).

  • On exceeding the limit — HTTP 429 Too Many Requests with an RFC 9457 problem+json body (see Error codes):

    {
      "type": "about:blank",
      "title": "Too Many Requests",
      "status": 429,
      "detail": "{\"code\":8,\"message\":\"merchant rate limit exceeded (limit: 10000/min)\",\"details\":[]}",
      "instance": "/api/v1/p2p-engine"
    }

Section overview

The documentation is organized into functional sections — start with the one matching your task:

Deal response fields (MerchantDealInfo) use canonical V2 names: deal_id (NOT id), payment_url (NOT payment_page_url), deal_type, target_requisite. The full field list is in the Deals section.


Quick start

A first test request — retrieving the merchant balance:

curl -X GET https://api.syncra.money/api/v1/p2p/merchant/balance \
  -H "X-Merchant-Token: your_merchant_token_here" \
  -H "X-Signature: t=1783856120,v1=9e87d0c3c8801d0a5198d023b6b19a16f2c8d2037920ab3e09819cd8e412cfab" \
  -H "Content-Type: application/json"

The response (RetrieveMerchantBalanceResponse) is a top-level wallets[] array (no data wrapper); each element is a real merchant wallet from the money service with its own currency and wallet_id: wallet_id, currency, available, frozen, total (all amounts are int64 in minor units, passed as strings in JSON). A live staging response:

{
  "wallets": [
    {
      "wallet_id": "1af2d1ee-7fc3-4796-9dda-10d97af62094",
      "currency": "USDT",
      "available": "95982",
      "frozen": "4018",
      "total": "100000"
    },
    {
      "wallet_id": "9b2fcbd6-b6f4-4f17-a94d-b7309f84bde5",
      "currency": "USDT",
      "available": "0",
      "frozen": "0",
      "total": "0"
    }
  ]
}

For details on computing the X-Signature signature header and protection against replay attacks, see Authentication. For receiving webhooks, see Callbacks.

On this page