FAQ¶
Can I call the API from a browser?¶
No, not directly. The API sends no CORS headers, so a browser blocks cross-origin fetch and XHR calls to it, and in any case a key placed in page JavaScript is visible to everyone who opens the page. Call the API from a server (a script, a backend, a serverless function) and give your front end the results, not the key. See Authentication.
Where do I get a key, and how do I replace one?¶
Keys are issued by the operator of the service, who also sets the scope (data or admin) and rate. A key is shown once at creation and stored hashed, so a lost key cannot be recovered. To rotate, ask for a new key, switch your integration to it, then ask for the old one to be revoked. The operator is whoever gave you access; the docs do not list a public support address.
My key worked yesterday and now returns 401¶
401 means the service no longer accepts what you sent: the key was revoked or replaced, the header is malformed, or something in the chain stripped it. Check that the header is exactly Authorization: Bearer <key> with no quotes or trailing whitespace, and that an HTTP proxy or client library is not dropping Authorization on redirects. The body is the same for "missing", "wrong" and "revoked", so you cannot tell them apart from the response. If the header is right, ask the operator whether the key was rotated.
Why does my series id return nothing?¶
A series id that does not exist is not an error. GET /v1/series/{id} answers 200 with "rows": [] and GET /v1/latest leaves the id out of rows and names it in data.missing. Common causes:
- Typo or wrong case. Ids are lowercase:
ru.key_rate, notRU.KEY_RATE. - The id guessed from a pattern does not exist. Not every partner has every series. Look it up with
GET /v1/series?search=<fragment>(Series ids and units). - A comma-separated list passed to
/v1/series/{id}. That route takes exactly one id. Use/v1/latest?ids=a,b,cfor the newest values of several series. - A date window with no data (
startafterlast_obs, or beforefirst_obs). Check the series metadata.
Why do numbers differ from TÜİK or TİM?¶
Several reasons, in rough order of importance:
- Different publishers measure differently. TİM (exporters' assembly) and TÜİK (statistical institute) publish Turkish exports with different coverage and timing. For the same month, the service holds both:
tr.exports_to.ru.usd(TİM) andtr.tuik.exports_to.ru.usd(TÜİK). They are not meant to match; pick one and stay with it. - Revisions. Publishers revise earlier months. The service stores what the publisher showed at the last successful refresh.
- Mirror data. Russia's imports by supplier come from the exporting countries' own reports, valued FOB and timed by their schedules, so they do not match Russian customs (Glossary).
- Units and rounding. USD vs USD millions, USD vs TRY, and floating-point noise in long decimals (
457415414.52000004). Check theunitfield and round for display. - Different sources for what looks like one thing: for example
tr.visitors.ru(EVDS) andtr.border.arrivals.ru(border statistics of the Ministry of Culture and Tourism) differ for the same month.
If a figure differs from the publisher's own page by more than rounding and revision, report it (next question).
How fresh is the data?¶
It depends on the source. Market data (FX, key rate, indices) is checked each business day; sanctions lists are checked daily; news every 30 minutes; monthly statistics appear when the publisher releases them, usually weeks after the month ends. Every response carries the answer for its own numbers: meta.sources[].fetched_at (last successful refresh) and as_of (newest data date). For all sources at once call GET /v1/sources/freshness. A table is on Coverage and freshness.
Why is a monthly value dated on the 1st?¶
Monthly observations are stored on the first day of the month they describe. tr.exports_to.ru.usd with obs_date 2026-10-01 is October 2026 in full, not 1 October. Quarterly rows use the first day of the quarter, annual rows 1 January.
How do I get more than 2000 rows?¶
There is no pagination. Series, latest and similar table results stop at 2000 rows and say so with truncated: true. The rows you get are the oldest ones, so for a long daily series always pass start. Options: narrow the window and make several requests, use resample=month (last value of each month), or use a dedicated endpoint with its own limit. See Responses and sources.
What do I do when I hit the rate limit?¶
The response is 429 with a Retry-After header. Sleep that many seconds and retry, and then fix the cause: batch ids into one /v1/latest call, use resample, cache, and give each integration its own key. The default is 120 requests per minute per key, shared by REST and MCP. See Rate limits.
Is there a sandbox or test environment?¶
No. There is one environment, and it is read-only. The API never writes data, so you can experiment freely against it; nothing you send can change the data. The only constraint is your key's rate limit. GET /v1/health needs no key and is a safe way to test connectivity.
Why does /v1/border/arrivals return no rows?¶
The endpoint defaults to country totals (no gate, no transport), and those exist only as monthly rows. If you pass freq=Y with no gate or transport filter, nothing matches. Yearly rows exist per gate and per transport mode: add gate=Antalya or transport=hava, or use freq=M for totals. The default nationality is Rusya Fed., the Turkish name as published; other nationalities use the published names (Beyaz Rusya (Belarus), Ukrayna, ...), and * selects all foreigners.
Why is China's trade with Russia only at chapter level?¶
China's customs service (GACC) publishes monthly trade with Russia by 2-digit HS chapter, not by HS6 product, for periods after 2024-12. The china_chapter_monthly block in a product check is therefore the value of the whole chapter, not of your product. Use it for the direction of China's trade, not for the product's market size.
Is a sanctions or restrictions result legal advice?¶
No. GET /v1/sanctions/check returns candidates ranked by name similarity; a candidate is not a confirmed match. Compare country, programme and identifiers, and prefer INN matches over name matches. /v1/restrictions/{hs} reports where an HS code appears in EU Regulation 833/2014 annexes, Russia's parallel-import list and the US CHP list; EU Regulation 269/2014 is not loaded (Coverage). Quote the annex, article and consolidated date and verify against the official text.
Does it work with MCP clients other than Claude?¶
Yes, any client that supports remote MCP over streamable HTTP with a custom Authorization header. The server is stateless and POST-only; a GET to /mcp returns 405. The same key and the same rate limit apply as for REST, and every HTTP request the client makes counts. See the MCP section.
How do I report a data problem?¶
Include:
- The request you made (method, path and query string) and the time (UTC).
- The
X-Request-Idresponse header ormeta.request_id. - What you expected, with the publisher's page or file where you saw it.
- The
meta.sourcesentry (fetched_atandas_of) from the response.
Send it to the operator who issued your key. Check GET /v1/sources/freshness first: if the source shows a recent last_error_at or stale: true, the cause is probably a failed refresh, which the operator can see on their side too.
Who do I contact?¶
The operator who issued your key. This is a personal project and the documentation does not publish a support address or a response-time commitment.