What is a Rate?
A rate is a firm FX quote that guarantees an exchange rate for converting NGN to USDC/USDT. Each rate has:- Exchange Rate: NGN → USD/USDC/USDT conversion ratio
- TTL (Time-to-Live): ~30-minute validity window
- Rate ID: Unique identifier for binding to onramps
- Minimum Deposit: Per-chain minimum amounts
New rates are generated approximately every 10 minutes. Rates expire ~30 minutes after creation.
Rate Properties
| Property | Description | Example |
|---|---|---|
rate_id | Unique identifier | rate_8x7k2mq9p |
from | Source currency | NGN |
to | Destination currency | USDC, USDT, USD |
rate | Conversion rate (from → to) | 1545.50 (1 USDC = 1545.50 NGN) |
inverse_rate | Inverse rate (to → from) | 0.000647 (1 NGN = 0.000647 USDC) |
fee_bps | Fee in basis points | 50 (0.5%) |
min_deposit_ngn | Minimum NGN amount per chain | 1500.00 |
created_at | When rate was generated | 2026-01-14T15:05:00Z |
expires_at | When rate becomes invalid | 2026-01-14T15:35:00Z |
Getting Rates
Request current exchange rates usingGET /v1/rates:
Query Parameters
| Parameter | Required | Description | Allowed Values |
|---|---|---|---|
from | ✅ Yes | Source currency | NGN |
to | ❌ No | Destination currency (defaults to USDC) | USDC, USDT, USD |
USD is treated as equivalent to USDC/USDT in v0.1. Depeg scenarios are not handled.Rate Validity
Rates expire approximately 30 minutes after creation. Timeline:Rate Generation Schedule
New rates are generated approximately every 10 minutes:| Time | Rate ID | Valid Until |
|---|---|---|
| 15:05 | rate_abc | 15:35 |
| 15:15 | rate_def | 15:45 |
| 15:25 | rate_ghi | 15:55 |
| 15:35 | rate_jkl | 16:05 |
Rate Semantics by Onramp Type
- Throwaway Onramps
- Permanent Onramps
Locked to
rate_id at creation timeWhen you create a throwaway onramp:- You specify a
rate_id - Onramp is bound to that rate
- Deposits within rate validity execute at that rate
- Deposits after rate expiry are
FLAGGED
Minimum Deposits
Each rate includesmin_deposit_ngn, which specifies the minimum NGN amount for the destination chain.
| Chain | Min Deposit NGN | Approx USD |
|---|---|---|
| BASE | 1,500 | ~$1.00 |
| Ethereum | 1,500 | ~$1.00 |
| Polygon | 1,500 | ~$1.00 |
Minimum deposits are designed to cover on-chain gas fees. Deposits below minimum are rejected with status
FAILED.Rate Calculation
The rate includes Daya’s spread (fee):- Market rate: 1550 NGN/USDC
- Fee: 50 bps (0.5%)
- Displayed rate: 1550 × (1 - 0.005) = 1545.50 NGN/USDC
Handling Rate Expiry
1
Request rate before onramp creation
Always call
GET /v1/rates immediately before creating an onramp.2
Check expires_at
Ensure
expires_at is at least 25 minutes in the future (for throwaway onramps with 25-min TTL).3
Show expiry to users
Display a countdown timer so users know they must complete the transfer quickly.
4
Handle expired rate errors
If
POST /v1/onramp returns rate_expired, request a fresh rate and retry.Edge Cases
No valid rate available
No valid rate available
Scenario: FX venue is temporarily unavailableAPI Response:Merchant action: Retry after a few minutes or notify users of temporary unavailability.
Rate expires during onramp creation
Rate expires during onramp creation
Scenario: Rate expires between Merchant action: Request a fresh rate and retry onramp creation.
GET /v1/rates and POST /v1/onrampAPI Response:Deposit after rate expiry
Deposit after rate expiry
Scenario: User transfers NGN after rate expiresResult: Deposit status →
FLAGGEDReason: "Deposit received after rate expiry"Resolution: Manual operations review required.Rate Immutability
Once a rate is published:- It cannot be modified
- It cannot be extended beyond
expires_at - It cannot be retroactively applied
Best Practices
Cache rates with TTL
Cache rates with TTL
Cache rates client-side with respect to
expires_at. Refresh when approaching expiry.Show countdown timers
Show countdown timers
Display remaining validity time to users:
Handle rate unavailability gracefully
Handle rate unavailability gracefully
Log rate usage
Log rate usage
Log which
rate_id was used for each onramp creation for troubleshooting.Testing Rates
In sandbox, rates are simulated but follow the same behavior as production:- Generated every ~10 minutes
- Expire after ~30 minutes
- Same API surface
- Rate expiry handling
- Onramp creation with expired rates
- Deposit after rate expiry scenarios