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

# Exchange Rates API — get NGN conversion rates

> Fetch current NGN-to-USDC and NGN-to-USDT exchange rates. Lock a rate for TEMPORARY onramps or use floating rates for PERMANENT accounts.

Exchange rates represent the current conversion price between Nigerian Naira and stablecoins. Before you create a TEMPORARY virtual account or an NGN payout offramp, you should fetch the latest rate and supply the returned `rate_id` in your request body to lock in a guaranteed conversion price. Rates are live market quotes with a short validity window — always fetch fresh before use.

## Authentication

All endpoints require either a Bearer token or an API key.

```
Authorization: Bearer <access_token>
```

```
X-Api-Key: dubu_sk_live_...
```

***

## Get exchange rates

`GET https://api.dubupay.com/api/v1/payments/rates`

Returns the current exchange rates for NGN conversions. You can filter by currency pair and side (buy or sell).

### Query parameters

<ParamField query="from" type="string">
  Source currency (e.g., `NGN`).
</ParamField>

<ParamField query="to" type="string">
  Target currency (e.g., `USDT` or `USDC`).
</ParamField>

<ParamField query="side" type="string">
  Trade direction. Typically `buy` or `sell`.
</ParamField>

### Response

<ResponseField name="data" type="array">
  List of rate objects for all available pairs (or the filtered pair if query params are provided).

  <Expandable title="rate object fields">
    <ResponseField name="id" type="string">
      A unique rate ID. Pass this as `rate_id` when creating a TEMPORARY onramp or an NGN payout offramp to lock in this rate.
    </ResponseField>

    <ResponseField name="pair" type="string">
      The currency pair, e.g., `NGN/USDT` or `NGN/USDC`.
    </ResponseField>

    <ResponseField name="rate" type="string">
      The conversion rate as a decimal string. For example, `"0.00063"` means 1 NGN = 0.00063 USDT.
    </ResponseField>

    <ResponseField name="side" type="string">
      The side this rate applies to: `buy` or `sell`.
    </ResponseField>

    <ResponseField name="expires_at" type="string">
      ISO 8601 timestamp after which this rate ID is no longer valid for locking.
    </ResponseField>

    <ResponseField name="timestamp" type="string">
      ISO 8601 timestamp of when the rate was fetched.
    </ResponseField>
  </Expandable>
</ResponseField>

### Example — fetch all rates

```bash theme={null}
curl "https://api.dubupay.com/api/v1/payments/rates" \
  -H "X-Api-Key: dubu_sk_live_..."
```

### Example — fetch NGN/USDT rate only

```bash theme={null}
curl "https://api.dubupay.com/api/v1/payments/rates?from=NGN&to=USDT" \
  -H "X-Api-Key: dubu_sk_live_..."
```

### Example response

```json theme={null}
{
  "success": true,
  "data": [
    {
      "id": "rate_abc123",
      "pair": "NGN/USDT",
      "rate": "0.00063",
      "side": "buy",
      "expires_at": "2024-01-15T10:35:00.000Z",
      "timestamp": "2024-01-15T10:30:00.000Z"
    },
    {
      "id": "rate_def456",
      "pair": "NGN/USDC",
      "rate": "0.00063",
      "side": "buy",
      "expires_at": "2024-01-15T10:35:00.000Z",
      "timestamp": "2024-01-15T10:30:00.000Z"
    }
  ]
}
```

***

## How rates are used

### TEMPORARY onramps — locked rate

When you create a TEMPORARY onramp, you pass the `rate_id` from this endpoint. The rate is locked for the 25-minute lifetime of the virtual account. If a deposit arrives within the window, the conversion happens at the locked rate — even if the market has moved.

```json theme={null}
{
  "type": "TEMPORARY",
  "amount": 50000,
  "rate_id": "rate_abc123",
  "settlement": {
    "mode": "ONCHAIN",
    "asset": "USDT",
    "chain": "TRON",
    "destination_address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE"
  }
}
```

### PERMANENT onramps — floating rate

PERMANENT onramps do not lock a rate at creation time. Instead, the prevailing market rate at the moment a deposit arrives is used for conversion. This gives customers a reusable account without requiring you to refresh rate IDs.

### NGN payout offramps — locked rate required

When you create an offramp with `settlement.mode` set to `NGN_PAYOUT`, you must supply a `rate_id`. This locks the USDT→NGN rate for the payout so the recipient receives a predictable amount.

***

## Rate freshness

<Warning>
  Rate IDs expire quickly. Always call `GET /payments/rates` immediately before creating a TEMPORARY onramp or an NGN payout offramp — do not cache rate IDs across sessions or reuse them across multiple requests. Use the `expires_at` field to confirm the rate is still valid before submitting.
</Warning>
