Skip to main content
This page tracks significant changes to the Paycrest API and protocol. For full commit history, see the aggregator repository.

Q4 2026

Customer KYC required on on-ramp orders (October 2026)

Updated: every on-ramp order created with POST /v2/sender/orders must now identify the customer paying in, in source.kyc. See On-ramp customer KYC for the full field list.
  • Behavior change: an on-ramp order without source.kyc, or with a required field missing or malformed, returns 400 with "field": "Source" and a message listing every problem.
  • A person needs fullName, birthDate (18 or over) and idDocument. For NGN, the document must be the NIN and taxId must be the BVN. For KES, contact.phoneE164 must be a Kenyan mobile number.
  • An organization needs legalName, registrationNumber, registrationCountry and at least one director meeting the person rules.
  • Where the bank resolves the refund account holder’s name (NGN), it must match the customer in source.kyc.

Tron orders through the v2 API only (October 2026)

Updated: Tron (USDT) orders are now created through POST /v2/sender/orders only, the same as Solana. Off-ramp and on-ramp both work as before on v2.
  • Behavior change: v1 order creation on tron returns 400 “This network is available only via POST /v2/sender/orders”. The v1 error for Solana now reads the same.
  • Off-ramp: send exactly providerAccount.amountToTransfer. A smaller deposit is not credited; it is returned to your refundAddress, less the Tron network’s transfer cost.
  • On-ramp to Tron has a higher minimum order than other networks because of Tron’s transfer cost. An order below it is refused, and the error states the minimum.
  • Tron rates are unchanged: GET /v2/rates and v1 rates with network=tron.

Q3 2026

Sender fees on Solana (September 2026)

Updated: Solana orders now pay sender fees to a Solana address, configured like any other network. Set a fee address, fee percent and max fee cap on your Solana token in the dashboard (Settings › Trading), or pass a Solana senderFeeAddress on POST /v2/sender/orders.
  • Fees from Solana orders are paid out to your Solana fee address in batches, once they add up to at least 1 USDC or USDT. The payout’s network cost comes out of the batch.
  • Behavior change: if you had set an EVM senderFeeAddress for Solana orders, replace it with a Solana address.
  • Your Solana fee address needs a token account for the stablecoin (it has one once it has ever held the token).

Transaction fee payer (September 2026)

New: Senders choose who pays each order’s transaction fee (transactionFee, the order’s network cost). Set it per token in the dashboard under Settings › Trading › Transaction fee paid by, or per order with the new transactionFeePayer field on POST /v2/sender/orders:
  • sender (default): the transaction fee comes out of your sender fee first. You earn max(0, fee − transactionFee) and your customer sends amount + max(fee, transactionFee). With a fee smaller than the transaction fee, your customer tops up only the difference.
  • customer: your customer pays the transaction fee on top of your full sender fee, as before.
Behavior change: existing tokens default to sender. If you charge a sender fee, it now covers the transaction fee unless you choose customer. With no sender fee, nothing changes. API:
  • senderFee in responses and webhooks is the fee you earn on the order. amountToTransfer = amount + senderFee + transactionFee still holds.
  • PATCH /settings/sender accepts tokens[].transactionFeePayer, and GET /settings/sender returns it.
  • The transaction fee now goes to the protocol treasury. A refund after an order is created onchain returns amount + senderFee.
See Who pays the transaction fee.

Solana now supported (September 2026)

Solana is supported for off-ramp and on-ramp through the v2 Sender API.
  • Network identifier: solana
  • Tokens: USDT (6 decimals; mint Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB) and USDC (6 decimals; mint EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v)
  • Addresses: Base58 public keys (32–44 characters)
  • Orders: create with POST /v2/sender/orders — source.network: "solana" for off-ramp, destination.recipient.network: "solana" for on-ramp. v1 endpoints return 400 “Solana is available only via POST /v2/sender/orders”
  • Off-ramp: send exactly providerAccount.amountToTransfer of providerAccount.currency to providerAccount.receiveAddress, and include providerAccount.memo when it is present
  • On-ramp: the recipient wallet must already have a token account for the stablecoin’s mint
  • For Solana orders, provide an EVM address for senderFeeAddress (no longer the case: see “Sender fees on Solana” above)
API: providerAccount.amountToTransfer (amount + senderFee + transactionFee) and providerAccount.currency are now returned on every off-ramp order, on every network; providerAccount.memo is returned only when the deposit must include it. 503 “Network temporarily unavailable” means the network or a quote for the amount is briefly unavailable — nothing was created; retry shortly. See Supported Stablecoins and Troubleshooting.

Onchain sender attribution via ERC-8021 (August 2026)

New: The aggregator now stamps the EVM transactions it submits with an ERC-8021 schema-0 data suffix carrying the sender’s trading name from their KYB profile. It is applied to the transactions the aggregator submits for an order: creation, settlement, and refunds. Orders placed through the Sender API carry public onchain attribution with no integration work.
  • Sender code: the sender’s KYB trading name (for example, AcmeCorp). Senders with no trading name on file get no suffix.
  • Suffix layout (parsed backwards from the end of calldata): comma-joined ASCII codes · 1-byte length · 1-byte schema 0x00 · 16-byte marker 0x8021...8021.
  • EVM only: Starknet and Tron transactions carry no suffix.
Important: the suffix is a public, human-readable attribution tag. It is not used for sender identification. Sender resolution, webhook delivery, and order lookup continue to use metadata.apiKey inside the encrypted messageHash, which is unchanged and not deprecated. Direct Gateway integrators can append their own suffix to createOrder calldata for public attribution. See Onchain Attribution (ERC-8021).

Optimistic provider routing (August 2026)

Order routing is now optimistic: a ranked queue of up to 3 providers is resolved once, at order creation, and assignment walks it in order instead of re-ranking the public orderbook on every retry. The fulfilling provider is known upfront and routing no longer drifts between creation and fulfilment. Updated: GET /v2/rates/{network}/{from}/{amount}/{to} — each side’s providerIds now carries up to 3 provider ids ranked best first, in the order assignment would try them. Previously always 0 or 1 entry. providerIds[0] is still the provider whose rate is in rate, so clients reading [0] are unaffected. Pinned (?provider_id=) quotes still return exactly one id. The fallback provider is never listed. New: order creation accepts an explicit providerIds queue — destination.providerIds on POST /v2/sender/orders, recipient.providerIds on POST /v1/sender/orders, and providerIds inside the encrypted recipient for onchain orders. Pass the ids from a rate quote to route the order to the providers your user was quoted. The singular providerId is retained for backward compatibility on both flows; providerIds covers every case it does, so new integrations need only the array form. Behavior change: the recipient encryption size check now budgets for a full 3-provider queue on every order — including orders that send no providerIds — because a queue may be resolved onto the order and rides in the message hash at gateway submit. The effective budget for accountIdentifier + accountName + memo + metadata is ~49 bytes smaller within the 500-byte cap (~41 when pinning a providerId). Requests that previously passed can now return 400 "Recipient data too large for encryption". Trim memo and metadata if you were near the limit. Behavior change: pinning an on-ramp order to a provider restricted to other senders now returns 400 provider X cannot serve this order. Off-ramp has always enforced this; on-ramp previously accepted such a pin and routed the order. It applies to providerId as well as providerIds, so on-ramp integrations that pin providers should confirm they are authorized for them. Exhausting a queue is not an immediate refund — fallback assignment runs after the last entry, then refund only after the refund window. See Get Token Rate, Pin a provider queue, and Smart Contract Interaction.

Optional senderFeeAddress on V2 create order (July 2026)

Updated: POST /v2/sender/orders accepts an optional top-level senderFeeAddress. senderFee and senderFeePercent remain mutually exclusive. Applies to both off-ramp and onramp. V1 create order is unchanged (still requires fee and refund addresses on the sender profile). See Sender API Integration — Sender Fees and Initiate Order.

Markets orderbook query filters (July 2026)

Updated: GET /v2/markets accepts optional query filters to narrow the returned orderbook: Filters apply only to data.book. data.aggregates remain network-wide (unfiltered), matching dashboard behavior (global KPIs, filtered table). See Get Markets.

Q2 2026

Starknet and Tron network support (July 2026)

Starknet (chain ID 23448594291968334) and Tron (chain ID 728126428) are fully supported by the aggregator. Starknet
  • Gateway: 0x06ff3a3b1532da65594fc98f9ca7200af6c3dbaf37e7339b0ebd3b3f2390c583
  • Network identifier: starknet
  • Tokens: USDT and USDC (6 decimals)
  • Addresses: felt hex (0x + 63–64 hex characters)
Tron
  • Gateway: THyFP5ST9YyLZn6EzjKjFhZti6aKPgEXNU
  • Network identifier: tron
  • Tokens: USDT (6 decimals; contract TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t)
  • Addresses: Base58Check starting with T
Docs cleanup: Scroll and Asset Chain are no longer listed as supported networks. Prefer the Sender API for Starknet and Tron orders; see Gateway Contract Addresses and Supported Stablecoins.

Public markets orderbook & provider rate position (June 2026)

New: GET /v2/markets — unauthenticated public endpoint returning the live protocol orderbook and network-wide aggregate statistics. No API key required; CORS open; ~10 s cache; per-IP rate limited.
  • data.book — array of provider quote rows (one per provider × side × token × fiat × network), including rate, rateType, min, max, balance, balanceUsd, settled, and successPercent.
  • data.aggregates — network-wide stats: settled volume/txns (24h/7d/30d/all-time), success rate, median delivery seconds, active providers/senders, live liquidity USD, and corridor/token/network counts.
Updated: GET /v1/provider/rates/{token}/{fiat} and GET /v2/provider/rates/{token}/{fiat} — each side (buy, sell) now carries an optional position object so providers can benchmark their effective rate against the best public peer in the same corridor: position is omitted when no qualifying public offers exist or you have no effective rate configured (backward compatible). See Get Markets and Get Market Rate.

Webhook delivery logs & retry API (June 2026)

Senders can now audit and replay webhook deliveries instead of re-triggering the order flow when an endpoint is briefly down. New endpoints:
  • GET /v2/sender/webhooks — list deliveries (newest first); filters: status, event, event_id, order_id, from, to.
  • GET /v2/sender/webhooks/:id — full delivery record including request payload and response body.
  • POST /v2/sender/webhooks/:id/retry — replay a delivery. ?sync=true replays immediately and returns the HTTP result inline; otherwise a new delivery is queued and the API returns 202 with its ID.
Behavior change: non-2xx responses now count as failed deliveries and are retried (previously only transport errors were). Retries use exponential backoff and expire after a cumulative 24-hour window, after which the sender is emailed once. See Webhook delivery logs & retry and List Webhook Deliveries.

Verify-account mobile money normalization (June 2026)

POST /v1/verify-account and POST /v2/verify-account now normalize mobile_money accountIdentifier values before provider verification (country dial code, strip + and leading 0). Supported fiat dial codes: KES 254, UGX 256, TZS 255, GHS 233.
  • Optional request field metadata (KES Till/Paybill) skips normalization when appropriate.
  • Response data may still be "OK" when the account is valid but no display name is returned (e.g. some M-Pesa corridors).
See Verify Account.

KES Till and Paybill off-ramp (May 2026)

Off-ramp to Kenya mobile rails now supports Till (buy goods) and Paybill in addition to phone M-Pesa.
  • On create, set destination.recipient.metadata.channel to Mobile, Till, or Paybill (use Mobile for phone M-Pesa; omit channel only when the identifier is a standard mobile number).
  • Paybill may require metadata.businessNumber.
  • Optional destination.kyc on off-ramp is recipient-only (no sender/provider KYB on create).
  • v2 GET / webhooks: destination.recipient.metadata echoes create-time recipient metadata; destination.kyc when stored.
  • Till/Paybill identifiers are not normalized as phone numbers on create or verify-account.
See Sender API Integration — KES mobile money and Supported Currencies.

Optional direction on v2 order lists and stats (April 2026)

GET /v2/sender/orders and GET /v2/provider/orders accept an optional query parameter direction, either onramp or offramp, to return only orders for that flow. Omit it to list both directions (default). On list endpoints, values other than onramp or offramp are ignored (no direction filter is applied). GET /v2/sender/stats and GET /v2/provider/stats accept the same optional direction parameter; omitted means totals and aggregates include both directions. Invalid direction values return 400 Bad Request. HMAC (ApiKeyAuth) on GET: request signatures are built from all query parameters—include direction in the signed payload when you send it (e.g. alongside timestamp and currency on provider stats).

Q1 2026

Public v2 rates path and buy/sell quotes (April 2026)

GET /v2/rates/{network}/{from}/{amount}/{to} is the supported public rates URL. The network is a path segment (not the network query used on v1). from and to may be a token + fiat pair (either order; not two tokens) or two fiat codes. Fiat–fiat quotes bridge through USDC on the same network; amount is in from fiat; sell / buy use asymmetric inverse-corridor semantics (not simple reciprocals). Path order does not imply trade direction for token/fiat—omit side to get both sides when available. Responses use structured buy and sell objects (rate, providerIds, orderType, refundTimeoutMinutes) instead of a single scalar data value. Optional query parameters:
  • side: buy or sell to return only one side.
  • provider_id: exactly 8 alphabetic characters to pin the quote to one provider.
Legacy: GET /v1/rates/{token}/{amount}/{fiat} with optional network query is unchanged and still returns a single rate in data. Provider market rate: GET /v1/provider/rates/{token}/{fiat} and GET /v2/provider/rates/{token}/{fiat} now return buy and sell objects, each with marketRate, minimumRate, and maximumRate (replacing the previous flat marketBuyRate / marketSellRate fields). See Get Token Rate and Get Market Rate.

FX on-ramp settleIn principal alignment (April 2026)

No REST schema changes. For FX on-ramp pay-in, the aggregator now sizes onchain settleIn principal using Gateway fee settings (providerToAggregatorFx) so that, after the contract’s floored aggregator fee, the recipient still receives at least the quoted net crypto amount. Liquidity reserve and ERC-20 approve amounts align with that gross principal plus sender fee, and snapshots stored on the order keep release/cleanup consistent if chain settings move later. Onchain principal amounts may differ slightly from older builds that used a looser ceiling gross-up; recipients should match the quoted net more precisely.

Q1 2026

v2 API — On-ramp & Off-ramp (March 2026)

The v2 API introduces a unified endpoint for both off-ramp and on-ramp flows, replacing the v1 offramp-only schema. New endpoints:
  • POST /v2/sender/orders — create off-ramp or on-ramp orders
  • GET /v2/sender/orders/:id — get a single v2 order
  • GET /v2/sender/orders — list v2 orders
  • GET /v2/provider/orders — provider view of v2 orders
  • GET /v2/provider/orders/:id — provider view of a single v2 order
What changed: The v1 API remains fully supported. No breaking changes to existing v1 integrations. Migration notes: If you’re building a new integration, use v2. Key differences to be aware of:
  1. The source and destination objects use a type discriminator ("crypto" or "fiat") to distinguish off-ramp from onramp.
  2. For off-ramp, the source.refundAddress field replaces the v1 returnAddress field.
  3. All numeric values (amount, rate, fees) are returned as string in v2 — parse them as needed.
  4. The providerAccount in the create response is a virtual account (V2FiatProviderAccount) for on-ramp orders, replacing the receiveAddress string from v1.
See the Sender API Integration Guide for full v2 off-ramp and on-ramp documentation.

On-ramp in production (March 2026)

Fiat-to-stablecoin on-ramp is live across active corridors. Available via the v2 API.

Scroll network support (Q1 2026)

Scroll (chain ID 534352) is now fully supported by the aggregator. Gateway contract: 0x663C5BfE7d44bA946C2dd4b2D1Cf9580319F9338. Previously marked “Coming Soon” — now live across USDT and USDC.

2025

cNGN support added

cNGN (Compliant Naira) is now supported as a stablecoin across Ethereum, Base, Polygon, and BNB Smart Chain. This is the first local-currency stablecoin supported by the protocol.

Lisk network support

Lisk (chain ID 1135) added to the aggregator. Gateway contract: 0xff0E00E0110C1FBb5315D276243497b66D3a4d8a.

Protocol launch (February 2025)

Initial mainnet deployment across Base, Polygon, BNB Smart Chain, and Arbitrum One. NGN corridor live with bank transfer and mobile delivery.

API Versioning Policy

The Paycrest API uses URL-based versioning (/v1/, /v2/). Within a major version:
  • Additive changes (new optional fields, new endpoints) are non-breaking and may be introduced at any time
  • Breaking changes (removed fields, changed field types, changed semantics) require a new major version
v1 will continue to be supported until an explicit deprecation notice is issued with at least 90 days’ advance notice.