Skip to content

Responses and sources

All REST endpoints return JSON in one of two shapes: a success envelope or an error body.

The envelope

{
  "data": { "...": "endpoint-specific payload" },
  "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
  }
}
Field Type Meaning
data object The payload. List-style endpoints use {"rows": [...], "row_count": n, "truncated": bool}; dossier-style endpoints (product check, company card, restrictions, sanctions check) use named blocks. See each endpoint page.
meta.sources array One entry per data source that contributed to this response. Empty for responses that carry no data from a source (/v1/health, /v1/sources, /v1/sources/freshness).
meta.request_id string Hex id of this request. Identical to the X-Request-Id response header.
meta.truncated boolean true when a row cap cut the result (see below). Mirrors data.truncated when the payload has one, otherwise false.

Errors use a different body, with no data and no meta: {"error": {"code": "...", "message": "..."}}. See Errors.

meta.sources: source_id, fetched_at, as_of

Every number the API returns can be traced to a source. Each entry in meta.sources has three fields:

Field Type Meaning
source_id string Identifier of the data source (cbr, evds, tim, tuik_trade ...). The full list with names is in GET /v1/sources and in Coverage and freshness.
fetched_at string or null When this source was last refreshed successfully, ISO 8601 timestamp in UTC. null if it has never succeeded.
as_of string or null The newest data date among the rows of this source in this response. A date (2026-10-01), or a timestamp for news. null when the data has no meaningful date (for example some sanctions lists and the Common High Priority Items List, which carry no dated observations).

Why two dates? They answer different questions.

  • fetched_at says how recently the service checked the publisher. It tells you whether the pipeline is alive.
  • as_of says how recent the data itself is. It tells you what period the numbers describe.

A real example from GET /v1/latest: the Bank of Russia key rate is refreshed on the afternoon of 2026-11-13 and its newest value is dated 2026-11-13, so both dates agree. The TİM export figure was fetched the same morning, but the newest month it contains is October 2026 (2026-10-01), because TİM publishes monthly:

{
  "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"}
  ]
}

Reading them together:

  • A recent fetched_at with an old as_of is normal for monthly and quarterly data: the publisher has not released anything newer. It is not a stale pipeline.
  • An old fetched_at means the refresh has been failing or is overdue; check GET /v1/sources/freshness (Coverage and freshness).
  • fetched_at is the time of the last successful run, not proof that something changed in that run.
  • Monthly observations are dated on the first day of the month they describe: 2026-10-01 means October 2026.

as_of is computed from the rows in the response, not from the whole series. If you request a window that ends earlier than the newest data, as_of reflects your window.

Warning

When a response is truncated, the rows you received are not necessarily the newest ones. GET /v1/series/ru.key_rate with no start returns the oldest 2000 rows, and its meta.sources[0].as_of is 2023-01-10, not today. Always pass start for long daily series, or use resample.

Truncation and row caps

There is no pagination. Instead every endpoint has a cap on rows, and the response tells you when the cap was hit:

  • data.truncated and meta.truncated are true.
  • data.row_count is the number of rows actually returned, not the number that matched.

A real example, GET /v1/changes?since=2026-11-01&limit=3 (the full list has hundreds of entries; three rows were returned):

{"data": {"rows": ["…3 rows…"], "row_count": 3, "truncated": true}, "meta": {"truncated": true}}

(Rows abbreviated here; …3 rows… is a placeholder, not part of the response.)

Endpoint Row cap
/v1/series, /v1/series/{id}, /v1/latest, /v1/sources and other table-style results with no limit parameter 2000 rows
/v1/changes limit, at most 1000 (default 200)
/v1/companies/search limit, at most 100 (default 25)
/v1/sanctions/check limit, at most 50 (default 15)
/v1/calendar 300 rows (no limit parameter; narrow with days, kind, country)
/v1/docs/search limit, at most 30 (default 8)
/v1/border/arrivals limit, at most 2000 (default 200)
/v1/news/search, /v1/news/latest limit, 1 to 100 (defaults 20 and 30)

To get everything when a result is truncated, narrow the request: a shorter start/end window, resample=month, a more specific filter, or several requests with consecutive windows.

Request ids

Every response, success or error, carries an X-Request-Id header. On success the same value is in meta.request_id. Error bodies do not contain it, so read the header. When you report a problem (FAQ), include the request id, the URL and the time.

JSON types

Kind Representation Example
Dates ISO 8601 YYYY-MM-DD strings "obs_date": "2026-10-01"
Timestamps ISO 8601 with UTC offset "fetched_at": "2026-11-13T17:30:30.332163+00:00", "published_at": "2026-11-13T18:48:34+00:00"
Numbers JSON numbers. Decimals are converted to floating point, so large values can carry floating-point noise. 457415414.52000004 (round it for display)
Counts JSON integers "visitors": 203733, "row_count": 2
Booleans true / false "truncated": false
Missing values null. Missing is not zero: a null value means no figure, 0.0 means a reported zero. "as_of": null, "name_en": null
Text UTF-8, including Turkish and Cyrillic characters. Decode responses as UTF-8. "name_ru": "ОАО \"РЖД\""
Units Carried in the data (unit field on series rows: %, USD, RUB per USD, USD bn ...), never implied see Series ids and units

Series observations are in long format: one row per series_id and obs_date.

{"series_id": "ru.key_rate", "obs_date": "2026-10-01", "value": 14.0}

With resample, rows also carry period (the first day of the week, month, quarter or year) and obs_date (the last observation date inside that period):

{"series_id": "ru.key_rate", "period": "2026-02-01", "obs_date": "2026-02-27", "value": 15.5}

Responses over MCP

MCP tools return the same data as a JSON string in the tool result text, with the sources as a top-level sources array next to the payload keys instead of an envelope. Fields and values are the same as in REST. Errors come back as {"error": {"code": ..., "message": ...}} inside the tool result. See the MCP pages.

No pagination

There are no page, offset or cursor parameters anywhere. Result size is controlled per endpoint by limit (where the endpoint has one), by date windows and by filters. If you need a long history, request it in windows or resample.