Exchange rates
Read current and historical fiat currency pair rates, discover supported currencies, and understand how DALP selects one feed per pair and resolves inverse pairs.
The exchange rates API exposes fiat currency pairs for pricing, valuation, and reconciliation workflows. Call the routes under /api/v2 for all new integrations: they return DALP response envelopes and use the shared collection query format for lists.
The routes cover reads only. Feed setup, feed governance, and legal valuation policy remain outside this API contract.
Endpoints
| Job | Method and path | Use it for | Response shape |
|---|---|---|---|
| List exchange rates | GET /api/v2/exchange-rates | Discover available base and quote pairs, latest observations, and feed links. | Collection envelope with data, meta, and links. |
| Read the current pair rate | GET /api/v2/exchange-rates/{baseCurrency}/{quoteCurrency} | Read the latest observed rate for one currency pair. | Single-resource envelope with data and links.self. |
| Read historical pair rates | GET /api/v2/exchange-rates/{baseCurrency}/{quoteCurrency}/history | Inspect observations for one pair with collection filters and pagination. | Collection envelope with data, meta, and links. |
| List supported currencies | GET /api/v2/exchange-rates/supported-currencies | Build currency pickers from the ISO 4217 codes the configured exchange-rate source currently supports. | Single-resource envelope with data and links.self. |
Exchange rate routes use ISO 4217 alpha-3 currency codes. Use uppercase codes such as EUR and USD in path parameters and filters.
List available rates
Call the list endpoint before you request a specific conversion path. It returns one record per currency pair after DALP deduplicates the active feed rows for each pair. When several active feeds describe the same pair, DALP keeps the most recently observed feed; see feed selection for the full rule.
curl --globoff "https://your-platform.example.com/api/v2/exchange-rates?filter[baseCurrency]=EUR&filter[quoteCurrency]=USD&page[limit]=50&page[offset]=0&sort=-effectiveAt" \
-H "X-Api-Key: sm_dalp_xxxxxxxxxxxxxxxx"The response uses the collection envelope:
{
"data": [
{
"baseCurrency": "EUR",
"quoteCurrency": "USD",
"rate": 1.08,
"effectiveAt": "2026-03-22T10:30:00.000Z",
"updatedAt": "2026-03-22T10:31:00.000Z",
"feedAddress": "0xabcdef1234567890abcdef1234567890abcdef12"
}
],
"meta": {
"total": 1,
"facets": {
"baseCurrency": [{ "value": "EUR", "count": 1 }],
"quoteCurrency": [{ "value": "USD", "count": 1 }]
}
},
"links": {
"self": "/v2/exchange-rates?filter[baseCurrency]=EUR&filter[quoteCurrency]=USD&page[limit]=50&page[offset]=0&sort=-effectiveAt",
"first": "/v2/exchange-rates?filter[baseCurrency]=EUR&filter[quoteCurrency]=USD&page[limit]=50&page[offset]=0&sort=-effectiveAt",
"next": null,
"prev": null,
"last": "/v2/exchange-rates?filter[baseCurrency]=EUR&filter[quoteCurrency]=USD&page[limit]=50&page[offset]=0&sort=-effectiveAt"
}
}rate, effectiveAt, updatedAt, and feedAddress can be null when a listed pair exists but has no usable observation yet. Treat a listed pair as discoverable; do not assume it is fresh enough for a valuation workflow.
Read one current rate
Call the pair read endpoint when you already know the pair you need. DALP responds with 404 and EXCHANGE_RATE_NOT_FOUND when no current rate exists for the requested pair; the endpoint never returns null for a missing rate. When baseCurrency and quoteCurrency are the same code, DALP gives an identity rate of 1.
curl "https://your-platform.example.com/api/v2/exchange-rates/EUR/USD" \
-H "X-Api-Key: sm_dalp_xxxxxxxxxxxxxxxx"The response carries one data object and a self link:
{
"data": {
"baseCurrency": "EUR",
"quoteCurrency": "USD",
"rate": 1.08,
"effectiveAt": "2026-03-22T10:30:00.000Z"
},
"links": {
"self": "/v2/exchange-rates/EUR/USD"
}
}Feed selection
DALP keeps one rate per currency pair. When more than one active feed describes the same pair, DALP resolves a single record using these rules:
- A feed that has produced an observation outranks a feed with no observations yet.
- Among feeds with observations, the most recently observed rate wins, and that choice is stable: the same set of active feeds resolves to the same rate on every call.
Once a pair has at least one observed feed, the list and read endpoints agree on the resolved rate. A pair with overlapping observed feeds always returns one consistent rate, never a different feed on each request. Use feedAddress on a list record to confirm which feed produced the rate you read. Before any feed for a pair has been observed, the two endpoints differ: the list endpoint surfaces the pair as a discoverable record with a null rate, while the read endpoint returns 404 with EXCHANGE_RATE_NOT_FOUND. Treat a freshly registered pair as discoverable until its first observation lands.
Inverse-pair resolution on a read
The single-pair read at GET /api/v2/exchange-rates/{baseCurrency}/{quoteCurrency} also resolves the reverse pair when the requested direction has no observed feed:
- If an observed feed exists for the requested pair, DALP returns its rate directly.
- If the requested pair has no observed feed but the reverse pair does, DALP inverts the reverse-pair rate and serves that value.
- If neither direction has an observed feed, DALP responds with
404andEXCHANGE_RATE_NOT_FOUND.
A read can therefore return a usable rate for EUR/USD even when only a USD/EUR feed is observed, by inverting that reverse rate. The list route preserves feed direction: it returns each pair exactly as its feed describes it. To confirm whether a rate came from a direct or inverted feed, compare the read result against the corresponding list record.
Read historical rates
Call the history route when you need a time-bounded record of observations for reconciliation, reporting, or a valuation review.
curl --globoff "https://your-platform.example.com/api/v2/exchange-rates/EUR/USD/history?filter[effectiveAt][gte]=2026-03-01T00:00:00.000Z&filter[effectiveAt][lte]=2026-03-31T23:59:59.999Z&page[limit]=100&sort=-effectiveAt" \
-H "X-Api-Key: sm_dalp_xxxxxxxxxxxxxxxx"The history response uses the same collection envelope as the list endpoint:
{
"data": [
{
"baseCurrency": "EUR",
"quoteCurrency": "USD",
"rate": "1.08",
"effectiveAt": "2026-03-22T10:30:00.000Z"
}
],
"meta": {
"total": 1,
"facets": {}
},
"links": {
"self": "/v2/exchange-rates/EUR/USD/history?filter[effectiveAt][gte]=2026-03-01T00:00:00.000Z&filter[effectiveAt][lte]=2026-03-31T23:59:59.999Z&page[limit]=100&sort=-effectiveAt",
"first": "/v2/exchange-rates/EUR/USD/history?filter[effectiveAt][gte]=2026-03-01T00:00:00.000Z&filter[effectiveAt][lte]=2026-03-31T23:59:59.999Z&page[limit]=100&page[offset]=0&sort=-effectiveAt",
"next": null,
"prev": null,
"last": "/v2/exchange-rates/EUR/USD/history?filter[effectiveAt][gte]=2026-03-01T00:00:00.000Z&filter[effectiveAt][lte]=2026-03-31T23:59:59.999Z&page[limit]=100&page[offset]=0&sort=-effectiveAt"
}
}Historical rate values are decimal strings. Use decimal arithmetic instead of converting them through binary floating-point numbers in financial workflows.
List supported currencies
Call the supported-currencies endpoint before you render a target-currency picker. It returns the ISO 4217 alpha-3 codes currently present in the configured rate-source snapshot.
curl "https://your-platform.example.com/api/v2/exchange-rates/supported-currencies" \
-H "X-Api-Key: sm_dalp_xxxxxxxxxxxxxxxx"{
"data": {
"providerKey": "open-er-api",
"currencies": ["AED", "EUR", "USD"]
},
"links": {
"self": "/v2/exchange-rates/supported-currencies"
}
}providerKey identifies the configured exchange-rate source snapshot. Treat currencies as the allowed picker set for the next exchange-rate refresh cycle.
Parameters and fields
| Field | Location | Type | Notes |
|---|---|---|---|
baseCurrency | Path or filter | ISO 4217 fiat code | Currency the rate converts from. The list endpoint supports filter[baseCurrency]=EUR. |
quoteCurrency | Path or filter | ISO 4217 fiat code | Currency the rate converts to. The list endpoint supports filter[quoteCurrency]=USD. |
filter[q] | Query | string | Free-text search across base and quote currency codes on the list endpoint. |
filter[rate] | Query | number filter | Filter list or history rows by rate. Use operators such as filter[rate][gte]=1. |
filter[effectiveAt] | Query | timestamp filter | Filter list or history rows by observation timestamp. Use ISO 8601 UTC timestamps. |
filter[updatedAt] | Query | timestamp filter | Filter list rows by last update timestamp. |
page[limit] | Query | integer | Page size for collection responses. |
page[offset] | Query | integer | Offset for collection responses. |
sort | Query | string | Sort field. Prefix with - for descending order, such as sort=-effectiveAt. |
rate | Response | number, string, or null | List and current reads return numbers; history returns decimal strings; list items may be null. |
effectiveAt | Response | timestamp or null | Time when the returned rate became effective. List items may be null before an observation. |
updatedAt | Response | timestamp or null | Time when the listed rate record was last updated. |
feedAddress | Response | EVM address or null | Feed contract address for a listed pair when one is available. |
providerKey | Response | string | Identifier for the supported-currencies snapshot. |
currencies | Response | ISO 4217 fiat code array | Currency codes available from the supported-currencies endpoint. |
Related pages
- Token price resolution explains how token pricing can use base-price and FX feeds for converted token prices.
- Operational integration patterns covers retries, readback checks, and reconciliation patterns around API integrations.
- API reference remains the contract source for generated clients and route details.
Private file access
How DALP restricts KYC, organisation, and admin files to authenticated Console sessions and validates each request against the caller's object-key scope.
Price feeds
Read the on-chain price-feed registry through DALP. List registered feeds, read one feed, resolve a feed for a subject and topic, and inspect latest value, historical rounds, and staleness.