Docs / Rates Data API / Endpoints / Retrieve a rate

Retrieve a rate

Returns one rate by id, `<source>:<date>:<code>`. A past bulletin is immutable, so what this resolves to does not change once it exists.

GET https://api.softon.dev/v1/rates/{id} Copy

Parameters

ParameterTypeDescription
id required string The rate id from a list response, `<source>:<date>:<code>`. Stable for the life of the record: a past bulletin is immutable, so the row this resolves to does not change once it exists.

Request

curl https://api.softon.dev/v1/rates/cbar:2026-09-05:USD \
  -H "Authorization: Bearer $SOFTON_KEY"

Response

The envelope is identical on every softon.dev API: data, meta, error. Only the shape inside data changes per dataset — see the response envelope.

{
  "data": {
    "id": "cbar:2026-09-04:RUB",
    "source": "cbar",
    "date": "2026-09-04",
    "effective_date": "2026-09-04",
    "carried_forward": false,
    "kind": "currency",
    "base": "AZN",
    "code": "RUB",
    "name": "100 Rusiya rublu",
    "unit": "unit",
    "nominal": 100,
    "value": 1.9579,
    "rate_per_unit": 0.019579,
    "source_url": "https://www.cbar.az/currencies/04.09.2026.xml",
    "bulletin_url": "https://www.cbar.az/currencies/04.09.2026.xml",
    "ingested_at": "2026-09-14T22:53:47.016591Z"
  },
  "meta": { "request_id": "req_9Fv3" },
  "error": null
}

Fields of data

FieldTypeDescription
id string Stable identifier, "<source>:<date>:<code>" — `cbar:2026-09-05:USD`. Opaque: treat the whole string as the id rather than parsing the halves out of it.
source string Which scraper delivered this bulletin. `cbar` is the Central Bank of Azerbaijan.
date date The calendar date this row answers for, **Asia/Baku**. Azerbaijan is UTC+4 year-round with no DST, so a consumer computing "today" in UTC gets yesterday's date for the four hours after 20:00 Baku — which is a real bug this feed's predecessor shipped, not a hypothetical one.
effective_date date The date the bank says these rates take effect from — the bulletin's own `ValCurs Date=`, never inferred from the date requested. On a business day it equals `date`; on a weekend, a public holiday or a future date it is the last business day before it.
carried_forward boolean `date != effective_date`: these numbers were published earlier and are still standing. **Filter `carried_forward=false` for a strict business-day series**; take every row for a dense daily one and know which values are repeats. The upstream answers `200` with a full bulletin for every date string including weekends and dates in the future, so this flag is the only thing that distinguishes a fresh publication from a repeat.
kind string `currency` or `metal`. The four bank metals (XAU, XPD, XPT, XAG) are the metals.
base string The currency the rate is expressed in. Always `AZN` for this source.
code string ISO 4217 code, or the metal's X-code. 42 per bulletin: 38 currencies and 4 bank metals. `SDR` is the IMF basket rather than a currency, and is carried as the bank publishes it.
name string · nullable The bank's own label, in Azerbaijani, including the multiplier it prints there — "1 ABŞ dolları", "100 Yapon iyeni".
unit string What one of `nominal` is: `unit` for a currency, `troy_ounce` for a metal.
nominal integer How many units `value` is quoted for. Seven currencies quote per 100 — KRW, KZT, HUF, UZS, PKR, RUB and JPY — and everything else per 1. Reading `value` without dividing by this is how a rouble comes out a hundred times too large.
value number The published figure, unrounded: AZN per `nominal` units.
rate_per_unit number `value / nominal`, unrounded. **This is the number you almost certainly want**: AZN for one unit of `code`, or for one troy ounce of a metal.
source_url string · nullable The document requested for `date`.
bulletin_url string · nullable The document these numbers were published in, i.e. the one for `effective_date`. Differs from `source_url` on a carried-forward row.
ingested_at timestamp When this version was stored.

Try it

v1 · stable
Send the request to see a response.