Macro series and latest values¶
Three endpoints cover the time-series store: a catalogue (/v1/series), the observations of one series (/v1/series/{series_id}) and the newest value of many series at once (/v1/latest). The catalogue currently lists 693 series: Türkiye, Russia, EU, one China and one US series, with daily, weekly, monthly, quarterly and annual frequencies. For what each id means and its unit, see Series ids and units.
GET /v1/series¶
Searches the catalogue. Use it to find the id you need, then fetch the data with the other two endpoints.
curl -s -H "Authorization: Bearer $TRRU_KEY" -G "https://trru.atapinar.com/v1/series" \
--data-urlencode "search=policy rate" --data-urlencode "country=RU"
| Parameter | Type | Default | Meaning |
|---|---|---|---|
search |
string | empty | Case-insensitive substring match on the series id, the Turkish name (name_tr) or the English name (name_en). % and _ are matched literally. |
country |
string | empty | Country code, exact match after upper-casing: TR, RU, EU, CN, US. |
category |
string | empty | Category, exact match after lower-casing. Values in use include rates, fx, prices, expectations, reserves, markets, macro, fiscal, trade, energy, tourism, transport, aviation, payments, real_estate, consumption, business, companies, logistics, construction, labour, activity, external. |
All three filters combine with AND. With no filters you get the whole catalogue (693 rows at the time of writing), ordered by country, category, series id. The list is not paginated and is cut at 2000 rows, which the catalogue is far below.
Example response¶
Request: GET /v1/series?search=policy%20rate&country=RU
{
"data": {
"rows": [
{
"series_id": "ru.policy_rate_bis",
"name_tr": "Rusya MB politika faizi (BIS, aylık)",
"name_en": "Bank of Russia policy rate (BIS, monthly)",
"unit": "%",
"frequency": "monthly",
"country": "RU",
"category": "rates",
"first_obs": "2015-01-01",
"last_obs": "2026-09-01",
"source_id": "evds"
}
],
"row_count": 1,
"truncated": false
},
"meta": {
"sources": [
{ "source_id": "evds", "fetched_at": "2026-11-13T17:30:29.379365+00:00", "as_of": "2026-09-01" }
],
"request_id": "469f72f2464243f7856b5e1a4edb6828",
"truncated": false
}
}
Field notes¶
| Field | Meaning |
|---|---|
series_id |
Stable id used in the other endpoints, for example ru.key_rate, tr.exports_to.ru.usd. |
name_tr, name_en |
Turkish and English names. Both are filled for every series today. |
unit |
Unit string such as %, USD, RUB. Read it before comparing series. |
frequency |
daily, weekly, monthly, quarterly or annual. |
first_obs, last_obs |
First and last observation date held. For monthly data the date is the first day of the month. |
source_id |
Where the series comes from. Match it against /v1/sources. |
Similar ids
ru.policy_rate_bis is the BIS monthly series. The Bank of Russia's own daily key rate is ru.key_rate. When two series look alike, compare source_id, frequency and last_obs.
GET /v1/series/{series_id}¶
Returns observations of one series in long format, oldest first.
curl -s -H "Authorization: Bearer $TRRU_KEY" \
"https://trru.atapinar.com/v1/series/ru.key_rate?start=2026-10-01"
| Parameter | Type | Default | Meaning |
|---|---|---|---|
series_id (path) |
string | required | One series id. Only one id per call; for several series call /v1/latest or repeat the request. |
start |
date | empty | First observation date to include (YYYY-MM-DD, inclusive). |
end |
date | empty | Last observation date to include (inclusive). |
resample |
string | empty | Empty for raw observations, or week, month, quarter, year. Any other value returns 400 resample must be '', week, month, quarter or year. |
Row cap and truncation¶
A response holds at most 2000 rows. Rows are ordered by date ascending, so when a series is longer than the cap you get its oldest 2000 observations and truncated is true (both in data and in meta). Example: ru.key_rate without any parameters is a daily series with more than 2000 rows, so the call returns data starting in 2015 and ending long before today.
To read the recent part of a long series, set start, or resample:
# last 30 days of a daily series
curl -s -H "Authorization: Bearer $TRRU_KEY" \
"https://trru.atapinar.com/v1/series/ru.key_rate?start=2026-10-15"
# one value per month
curl -s -H "Authorization: Bearer $TRRU_KEY" \
"https://trru.atapinar.com/v1/series/ru.key_rate?resample=month&start=2026-01-01&end=2026-03-31"
Raw example¶
Request: GET /v1/series/ru.key_rate?start=2026-10-01. The real response has row_count 31; the rows list is trimmed here to the first three.
{
"data": {
"rows": [
{ "series_id": "ru.key_rate", "obs_date": "2026-10-01", "value": 14.0 },
{ "series_id": "ru.key_rate", "obs_date": "2026-10-02", "value": 14.0 },
{ "series_id": "ru.key_rate", "obs_date": "2026-10-05", "value": 14.0 }
],
"row_count": 31,
"truncated": false
},
"meta": {
"sources": [
{ "source_id": "cbr", "fetched_at": "2026-11-13T17:30:30.332163+00:00", "as_of": "2026-11-13" }
],
"request_id": "d6ad2bac8fbe490497fee29ce822951b",
"truncated": false
}
}
Resampled example¶
Request: GET /v1/series/ru.key_rate?resample=month&start=2026-01-01&end=2026-03-31 (live response, meta omitted).
{
"data": {
"rows": [
{ "series_id": "ru.key_rate", "period": "2026-01-01", "obs_date": "2026-01-30", "value": 16.0 },
{ "series_id": "ru.key_rate", "period": "2026-02-01", "obs_date": "2026-02-27", "value": 15.5 },
{ "series_id": "ru.key_rate", "period": "2026-03-01", "obs_date": "2026-03-31", "value": 15.0 }
],
"row_count": 3,
"truncated": false
}
}
Field notes¶
| Field | Meaning |
|---|---|
series_id |
Echo of the id. |
obs_date |
Date of the observation. For monthly data, the first of the month. In a resampled response it is the date of the last observation inside the period. |
period |
Only with resample: the first day of the week, month, quarter or year the row represents. |
value |
Number in the unit given by the catalogue. |
Resampling takes the last value in each period; it does not average or sum. That suits rates and index levels, not flows such as monthly trade totals (for flows, use the raw monthly series). meta.sources[].as_of is the newest obs_date returned.
Edge cases¶
- An unknown id is not an error: the response is
200with"rows": [],"row_count": 0and an emptymeta.sources. Check the id against/v1/series. startorendin another format (2026/01/01,01.01.2026) returns 400start/end must be YYYY-MM-DD.startlater thanendreturns an empty list.
GET /v1/latest¶
Newest observation per series, with the series name, unit and frequency. One call replaces many /v1/series/{id} requests for a dashboard.
curl -s -H "Authorization: Bearer $TRRU_KEY" \
"https://trru.atapinar.com/v1/latest?ids=ru.key_rate,tr.exports_to.ru.usd"
| Parameter | Type | Default | Meaning |
|---|---|---|---|
ids |
comma-separated string | empty | Series ids. Spaces and empty items are ignored. Empty (or only blanks and commas) returns all series, currently 693 rows; use it deliberately. |
Rows are ordered by series_id.
Example response¶
Request: GET /v1/latest?ids=ru.key_rate,tr.exports_to.ru.usd,no.such.series
{
"data": {
"rows": [
{
"series_id": "ru.key_rate",
"name_tr": "Rusya MB politika faizi (key rate)",
"unit": "%",
"frequency": "daily",
"as_of": "2026-11-13",
"value": 14.0,
"source_id": "cbr"
},
{
"series_id": "tr.exports_to.ru.usd",
"name_tr": "Türkiye'nin Rusya'a ihracatı (TİM konsolide)",
"unit": "USD",
"frequency": "monthly",
"as_of": "2026-10-01",
"value": 457415414.52000004,
"source_id": "tim"
}
],
"row_count": 2,
"truncated": false,
"missing": ["no.such.series"]
},
"meta": {
"sources": [
{ "source_id": "cbr", "fetched_at": "2026-11-13T17:30:30.332163+00:00", "as_of": "2026-11-13" },
{ "source_id": "tim", "fetched_at": "2026-11-13T09:45:38.503380+00:00", "as_of": "2026-10-01" }
],
"request_id": "c0fe592822fd47a58478944330f7cb42",
"truncated": false
}
}
Unknown ids¶
no.such.series was in the request and is absent from rows; the response is still 200. When you pass ids, data.missing lists the requested ids that are not registered series (an empty list when all exist). missing is left out when ids is empty (all series are returned).
Check data.missing
A row that is absent from rows is not "no change". Ids listed in data.missing do not exist as series (typo, renamed id). An id that exists but has no observation is in neither list.
Field notes¶
| Field | Meaning |
|---|---|
as_of |
Date of the latest observation of that series (monthly series: first of the month). Different series have different as_of; this is the data date, not the fetch time. |
value |
Latest value, in unit. |
name_tr |
Turkish series name. English names are in /v1/series. |
meta.sources[].fetched_at |
When that source was last refreshed successfully. Compare with as_of to tell "no new data yet" from "the refresh failed": see /v1/sources/freshness. |
Tips¶
- Cache the catalogue. It changes rarely; the values change daily.
- For a bulletin, call
/v1/latest?ids=...once, then/v1/series/{id}?start=...only for the series you chart. - Never hardcode an old
as_of: print it next to every number you publish.