> For the complete documentation index, see [llms.txt](https://vnx.gitbook.io/vnx-global/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://vnx.gitbook.io/vnx-global/developer/guides/integrate-stablecoin-redeem.md).

# Integrate Stablecoin Redeem

*Redeem your own VCHF or VGBP at par into fiat or crypto, in one or two settlement legs.*

## Use case and audience

You are a fintech, exchange, or treasury that holds a **direct account with VNX** and needs to redeem VCHF or VGBP you hold to fiat (or convert proceeds to crypto). This is a direct client↔VNX relationship: **you are the Customer of record** who holds the tokens, signs the burn order, and receives the payout to your registered bank account or whitelisted wallet — you are not redeeming on behalf of your own end-users. VNX guarantees par redemption "at any time at face value" and runs the regulated leg — burning your tokens, reducing the fiduciary reserve, and wiring fiat — while you orchestrate the ordering and reconciliation on your side. This guide covers direct redemption, proprietary-trade buyback, and the optional fiat→crypto conversion leg.

## Architecture

See the verified flow in [Redeem Flow](/vnx-global/developer/flows/redeem-flow.md). The condensed view:

```mermaid
sequenceDiagram
    participant App as Your service
    participant V as VNX API
    participant FB as Fiduciary Bank (reserve)
    participant LP as Liquidity Pool
    participant CB as Your Bank
    App->>V: POST /private/burnTokens (ECDSA-signed)
    alt Direct redemption
      V->>FB: Reduce reserve
      FB-->>V: Fiat released
      V->>CB: Wire to your bank
    else Prop trade
      V->>LP: Buy stables to pool
      LP-->>V: Fiat available
      V->>CB: Wire to your bank
    end
    App->>V: Poll /private/querySupplyChanges + /private/queryPayments
```

## Prerequisites

* Your own KYB cleared.
* You hold redeemable VCHF or VGBP on your Platform balance, or have a whitelisted external wallet of your own to redeem from.
* An ECDSA key-pair registered with VNX; your private key signs each request.
* A `User-Agent` string on every request and adherence to the 1 req/sec per-public-key rate limit.
* For external-wallet redemption: Travel Rule originator data captured.

## Walkthrough

{% stepper %}
{% step %}

## 1. Sign every request

Every `/private/*` request carries `x-app-public-key`, `x-app-nonce` (always-increasing uint64, UNIX ms), and `x-app-signed-data` (base64url ECDSA-SHA256 signature over the URI path + canonical-JSON POST data + nonce), plus a `User-Agent`. Canonical JSON sorts object keys lexicographically; arrays keep order. `Content-Type` is `application/x-www-form-urlencoded`.
{% endstep %}

{% step %}

## 2. Submit a redemption (burn) request

```bash
curl -X POST https://api.vnx.io/api/v1/private/burnTokens \
  -H "User-Agent: MyClient/1.0" \
  -H "x-app-public-key: ${PUBLIC_KEY}" \
  -H "x-app-nonce: ${NONCE}" \
  -H "x-app-signed-data: ${SIGNATURE}" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "asset=VGBP" \
  "quantity=150000"
```

```json
{
  "timestamp": "2026-05-07T16:00:00Z",
  "txid": "0xdef...",
  "requestid": "req_01HV...",
  "fee": "0",
  "received": "150000.00",
  "received_currency": "GBP"
}
```

The burn reduces the reserve and triggers the fiat payout to your registered bank account.
{% endstep %}

{% step %}

## 3. Poll for status

There are no webhooks. Poll `/private/querySupplyChanges` to confirm the burn, and `/private/queryPayments` to follow the fiat payout. Match by `requestid` or `txid`.

```bash
curl -X POST https://api.vnx.io/api/v1/private/queryPayments \
  -H "User-Agent: MyClient/1.0" \
  -H "x-app-public-key: ${PUBLIC_KEY}" \
  -H "x-app-nonce: ${NONCE}" \
  -H "x-app-signed-data: ${SIGNATURE}" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "asset=VGBP"
```

Respect the 1 req/sec rate limit when polling; back off on `{code, status, message}` errors.
{% endstep %}

{% step %}

## 4. Redeem to crypto instead of fiat

To deliver proceeds as crypto rather than a bank payout, use the Stablecoin To Fiat-style conversion model via payment rails — see [Integrate Onramp Offramp](/vnx-global/developer/guides/integrate-onramp-offramp.md). On-chain delivery to a whitelisted external wallet requires calling `/private/withdraw` (body: `asset`, `quantity`, `destination`, optional `memo`/`dest_tag`).
{% endstep %}

{% step %}

## 5. Failed compliance path

Per the BP, a token failing compliance is held pending EDD; redemption stays in `pending_compliance` until cleared. Operations dashboards expose held items.
{% endstep %}
{% endstepper %}

## Test in UAT

Use the test base URL `https://api.uat.vnx.io/api/v1/` with your UAT credentials. Sign requests exactly as in production.

```bash
# Redeem (burn) VCHF 1,000
curl -X POST https://api.uat.vnx.io/api/v1/private/burnTokens \
  -H "User-Agent: MyClient/1.0" \
  -H "x-app-public-key: ${PUBLIC_KEY}" \
  -H "x-app-nonce: ${NONCE}" \
  -H "x-app-signed-data: ${SIGNATURE}" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "asset=VCHF" \
   "quantity=1000"
```

Expected UAT effects:

* A response with `txid` and `requestid`.
* `querySupplyChanges` shows the burn; `queryPayments` shows the fiat payout.

## Troubleshooting

| Symptom                            | Likely cause                                        | Fix                                           |
| ---------------------------------- | --------------------------------------------------- | --------------------------------------------- |
| 400 `unsupported_rail`             | Rail/currency mismatch                              | Use SEPA for EUR, SWIFT for GBP/CHF           |
| 403 `kyb_required`                 | Caller KYB not cleared                              | Coordinate with VNX onboarding                |
| 401 signature/nonce error          | Bad signature, stale nonce, or wrong canonical JSON | Recompute over path + canonical body + nonce  |
| Held entry in `querySupplyChanges` | AML/Travel Rule/EDD                                 | Coordinate with VNX support                   |
| 429 rate limited                   | Exceeded 1 req/sec per public key                   | Throttle and back off                         |
| Liquidity-constrained payout       | Net redemption pressure                             | Poll `queryPayments`; may use prop-trade path |

## Production checklist

* Always-increasing nonce (UNIX ms) per request; never reuse or decrease.
* Correct canonical-JSON serialization before signing every request.
* Rate-limit budget mapped to 1 req/sec; back off on 429 and `{code, status, message}` errors.
* Audit log captures `requestid`, `txid`, and nonce.
* Status reconciliation by polling `querySupplyChanges` and `queryPayments`.
* Net-redemption monitoring: stress >10% of circulating supply triggers liquidity review.
* Travel Rule data validated at request time for crypto legs.

## References

* [Redeem Flow](/vnx-global/developer/flows/redeem-flow.md)
* [Transfers](/vnx-global/developer/api/transfers.md)
* [Minting and Redemption](/vnx-global/institutional/products/minting-and-redemption.md)
* [Glossary](/vnx-global/glossary.md)
