> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paycrest.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Changelog

> A record of notable API, protocol, and documentation changes.

This page tracks significant changes to the Paycrest API and protocol. For full commit history, see the [aggregator repository](https://github.com/paycrest/aggregator).

***

## Q2 2026

### 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:

| Field               | Description                                                                                                                               |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `bestPublicRate`    | Best rate among enabled non-testnet public peers (highest for sell; lowest for buy)                                                       |
| `yourEffectiveRate` | Your effective rate for this corridor                                                                                                     |
| `deltaVsBest`       | `yourEffectiveRate − bestPublicRate` — positive means higher; for sell positive is more competitive, for buy negative is more competitive |

`position` is omitted when no qualifying public offers exist or you have no effective rate configured (backward compatible).

See [Get Markets](/api-reference/general/get-markets) and [Get Market Rate](/api-reference/provider/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](/implementation-guides/sender-api-integration#webhook-delivery-logs--retry) and [List Webhook Deliveries](/api-reference/sender/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`, MWK `265`.

* 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](/api-reference/general/verify-account).

***

### KES Till and Paybill offramp (May 2026)

**Offramp** 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 offramp 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](/implementation-guides/sender-api-integration#kes-mobile-money-m-pesa-till-paybill)** and **[Supported Currencies](/resources/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](/api-reference/general/get-token-rate) and [Get Market Rate](/api-reference/provider/get-market-rate).

***

### FX onramp settleIn principal alignment (April 2026)

No REST schema changes. For **FX onramp** 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 — Onramp & Offramp (March 2026)

The v2 API introduces a unified endpoint for both offramp and onramp flows, replacing the v1 offramp-only schema.

**New endpoints:**

* `POST /v2/sender/orders` — create offramp or onramp 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:**

| Feature             | v1                                    | v2                                                             |
| ------------------- | ------------------------------------- | -------------------------------------------------------------- |
| Direction support   | Offramp only                          | Offramp + onramp                                               |
| Request schema      | Flat: `token`, `network`, `recipient` | Polymorphic: `source`, `destination` with `type` discriminator |
| Amount direction    | Always crypto                         | `amountIn: "fiat"` or `"crypto"`                               |
| Sender fee          | Fixed amount via dashboard            | Dashboard required; `senderFeePercent` on request overrides it |
| Numeric field types | `decimal.Decimal`                     | `string`                                                       |
| Webhook version     | `webhookVersion: "1"`                 | `webhookVersion: "2"`                                          |

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 offramp from onramp.
2. For offramp, 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 onramp orders, replacing the `receiveAddress` string from v1.

See the [Sender API Integration Guide](/implementation-guides/sender-api-integration) for full v2 offramp and onramp documentation.

***

### Onramp in production (March 2026)

Fiat-to-stablecoin onramp 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`.

### BRL corridor live

Brazilian Real (BRL) via PIX now available as an active corridor. Mobile/PIX delivery only.

### 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.
