Stable REST API v1

Russian visa rules, with provenance built in

Build traveler checks and country guidance from a centrally reviewed ruleset. Every material rule can be traced to official Russian MFA, KD MID or an official Russian mission source.

Base URL: https://api.russianvisa.co/v1

Trust model

Human publication gate
Source changes create review tasks; they never publish a rule automatically.
Versioned Last Known Good
Responses identify the published ruleset used for the decision.
Scoped access
Public reads are anonymous; history and change feeds require a scoped key.

Quickstart

Resolve a traveler route

This public endpoint accepts ISO country codes and explicit travel dates. The response contains the deterministic recommendation, applicable normalized rules, official sources, ruleset metadata and a request ID.

cURL

curl -X POST https://api.russianvisa.co/v1/check/traveler \
  -H "Content-Type: application/json" \
  -d '{
    "nationality": "IN",
    "residence_country": "AE",
    "purpose": "tourism",
    "arrival_date": "2026-11-10",
    "departure_date": "2026-11-23",
    "entries": "1",
    "passport_type": "ORDINARY"
  }'

JavaScript

const response = await fetch("https://api.russianvisa.co/v1/check/traveler", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    nationality: "IN",
    residence_country: "AE",
    purpose: "tourism",
    arrival_date: "2026-11-10",
    departure_date: "2026-11-23",
    entries: "1",
    passport_type: "ORDINARY"
  })
});

const payload = await response.json();
console.log(payload.data.result, payload.data.sources);
Server-side examples: Python and PHP

Python

import requests

response = requests.post(
    "https://api.russianvisa.co/v1/check/traveler",
    headers={"X-API-Key": "YOUR_SERVER_SIDE_KEY"},
    json={
        "nationality": "IN",
        "residence_country": "AE",
        "purpose": "tourism",
        "arrival_date": "2026-11-10",
        "departure_date": "2026-11-23",
        "entries": "1",
        "passport_type": "ORDINARY",
    },
    timeout=5,
)
response.raise_for_status()
decision = response.json()["data"]

PHP

<?php
$payload = json_encode([
  "nationality" => "IN",
  "residence_country" => "AE",
  "purpose" => "tourism",
  "arrival_date" => "2026-11-10",
  "departure_date" => "2026-11-23",
  "entries" => "1",
  "passport_type" => "ORDINARY"
]);

$request = curl_init("https://api.russianvisa.co/v1/check/traveler");
curl_setopt_array($request, [
  CURLOPT_POST => true,
  CURLOPT_POSTFIELDS => $payload,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_TIMEOUT => 5,
  CURLOPT_HTTPHEADER => [
    "Content-Type: application/json",
    "X-API-Key: " . getenv("RUSSIANVISA_API_KEY")
  ]
]);
$decision = json_decode(curl_exec($request), true)["data"];

Core endpoints

PurposeMethodPathUse
Traveler decisionPOST/v1/check/travelerResolve a route from passport, residence, purpose and trip dates.
Country rulesGET/v1/countriesList or inspect published passport-country rule summaries.
Site facts snapshotGET/v1/site-factsLoad the current ruleset identity, core eVisa facts, country decisions and official-source metadata in one cacheable request.
Normalized rulesGET/v1/rulesBrowse immutable, versioned rule values and verification status.
Official sourcesGET/v1/sourcesInspect the official MFA/KD MID evidence catalog.
RulesetGET/v1/rulesetIdentify the current Last Known Good published ruleset.
Rule historyGET/v1/rules/{ruleCode}/historyRead immutable prior versions; history:read key required.
Change intelligenceGET/v1/changesReview detected source changes; changes:read key required.

Authentication and quotas

Anonymous read access includes the current ruleset, countries, rules, sources and traveler checks. Anonymous traffic is limited to 30 requests per minute and 1,000 per month per privacy-preserving network identity. Approved clients receive a key for higher plan quotas and protected scopes.

curl https://api.russianvisa.co/v1/changes \
  -H "X-API-Key: rvr_live_…"

Keys are displayed only when issued. Store them in a server-side secret manager; never embed them in browser code or commit them to Git.

Caching and conditional requests

Read responses provide an ETag. Send it back as If-None-Match; unchanged data returns HTTP 304 without a response body. Cache headers vary by endpoint, while request IDs make operational support traceable.

curl -i https://api.russianvisa.co/v1/ruleset \
  -H 'If-None-Match: "stored-etag"'

Errors

Errors use a stable object with code, message, request_id and optional field-level details. HTTP status codes retain their normal meaning.

Versioning

The URL carries the API major version. Published data has its own immutable ruleset version, effective dates and per-rule version number.

Privacy

Send decision inputs, not traveler identity. The API does not require names, passport numbers, email addresses or payment data.

Production integration checklist

  1. 1. Server only. Keep live keys in a secret manager and call the API from your backend.
  2. 2. Record the ruleset. Store meta.ruleset.version with the decision you display.
  3. 3. Cache safely. Persist the response and ETag; reuse it on HTTP 304 and during a short upstream outage.
  4. 4. Preserve evidence. Show official source URLs and the returned verification date beside material guidance.
  5. 5. Fail closed. If neither a current response nor a reviewed cached response exists, do not invent a recommendation.
  6. 6. Separate identity. Do not send names, passport numbers, emails or payment data to the Rules API.

Attribution and legal notice

Anonymous responses set meta.attribution_required to true. Display “Visa rules powered by RussianVisa.co” with a link to this site. RussianVisa.co is an independent information service and is not operated by the Government of the Russian Federation. Always expose the returned official source links and verification date in traveler-facing decisions.