Documentación de la API
Referencia de la API de requisitos de visado de Orizn: 49,750 pares pasaporte/destino en 15 idiomas, con cada endpoint, cada parámetro y una respuesta de ejemplo real.
Inicio rápido
Cada cuenta de Orizn incluye una clave API personal. Pásala en el header x-api-key (o el parámetro de consulta?api_key= ) y ya estás en marcha.
¿Trabajas con un stack concreto? Los tutoriales de integración te llevan de una carpeta vacía a una llamada funcionando — MCP, REST, JavaScript, Python, Rust, LangChain, React y Next.js. Cada bloque de código de esas páginas se ejecutó antes de publicarse.
# Free key: evaluation only. Shipping to users? -> commercial license required. curl "https://visa.orizn.app/api/v1/visa?passport=FRA&destination=JPN&lang=en" \ -H "x-api-key: YOUR_API_KEY"
GET /api/v1/visa/check?passport=FRA&destination=JPNNo se necesita clave — ejecuta esta llamada de demostración en vivo desde tu navegador. Obtienes una respuesta 200 real de la API, en el mismo dominio.
URL base: https://visa.orizn.app · JSON de entrada/salida · UTF-8 · CORS abierto en todos los endpoints públicos.
1. Autenticación
Hay tres formas de autenticarse, según el endpoint:
header x-api-key
La opción por defecto para código de producto. También se acepta vía ?api_key= como parámetro de consulta.
sin credenciales
Stats, score, live, register, flujos de afiliados. /visa/check también funciona sin clave cuando se llama desde visa.orizn.app, localhost, o una extensión de Chrome.
cookie orizn_token
Endpoints del dashboard (rotación de claves, checkout/portal de Stripe, analíticas). Se establece automáticamente al iniciar sesión en el dashboard.
# 1) API key — recommended curl "https://visa.orizn.app/api/v1/visa?passport=FRA&destination=JPN" \ -H "x-api-key: YOUR_API_KEY" # 2) API key via query string (only when headers can't be set) curl "https://visa.orizn.app/api/v1/visa?passport=FRA&destination=JPN&api_key=YOUR_API_KEY" # 3) Session cookie (dashboard endpoints) curl "https://visa.orizn.app/api/v1/visa/auth/ensure-key" \ --cookie "orizn_token=YOUR_SESSION"
Nunca expongas tu clave en código cliente distribuido a usuarios no confiables — pasa por un proxy en tu backend. Las claves se pueden rotar en cualquier momento desde el dashboard.
Convenciones
2. Endpoints
Todos los endpoints viven bajo https://visa.orizn.app. Las insignias bajo cada ruta indican el modo de autenticación y el plan mínimo. Los endpoints públicos tienen un botón Ejecutar ▶ que puedes disparar aquí mismo.
The endpoints you'll actually call from product code.
/api/v1/visaclave api · cualquier planInteligencia de visa completa
The flagship endpoint. Returns documents, process, fees, embassies, transit, vaccinations, safety advisories, overstay penalties, and more — in 15 languages. Plan gating: free returns the core fields plus upgrade stubs; starter unlocks every extended field except remote-work-visa and reciprocity history; pro+ returns everything including bidirectional embassy info.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| passport | string | Sí | ISO 3166-1 alpha-3 (p. ej. FRA). |
| destination | string | Sí | ISO 3166-1 alpha-3 (p. ej. JPN). |
| lang | string | No | Uno de los 15 códigos soportados (ver Idiomas). Disponible en todos los planes, incluido el gratuito. |
curl "https://visa.orizn.app/api/v1/visa?passport=FRA&destination=JPN" \ -H "x-api-key: YOUR_API_KEY"
{
"data": {
"passport": "FRA",
"destination": "JPN",
"requirement": "visa_free",
"visa_free_days": 90,
"visa_required": false,
"description": "France citizens can enter Japan without a visa for a stay of up to 90 days. A valid passport is required.",
"documents_required": [
"Valid passport (6 months minimum)",
"Return or onward ticket",
"Proof of accommodation",
"Proof of sufficient funds"
],
"process": [
"No prior formalities required",
"Present valid passport upon arrival",
"Entry stamp will be issued at border control"
],
"processing_time": "Immediate on arrival",
"cost": "Free",
"validity": "90 days from entry",
"max_stay": "90 days (extendable under conditions)",
"source": "official",
"verified": true,
"source_url": "https://www.mofa.go.jp/j_info/visit/visa/short/novisa.html",
"last_verified_at": "2026-10-28T17: 23: 03.299Z",
"last_verified": "2026-10-28"
},
"meta": {
"lang": "en",
"api_version": "1.0",
"coverage": "199 passports x 250 destinations",
"languages": 15,
"powered_by": "Orizn Visa API"
}
}/api/v1/visa/checkclave api · cualquier planVerificación rápida de visa
Lightweight yes/no — returns just the requirement type and allowed stay. The embedded _upgrade_preview field counts what the full /visa endpoint would have returned, so you can drive upsell UI without a second call.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| passport | string | Sí | ISO 3166-1 alpha-3. |
| destination | string | Sí | ISO 3166-1 alpha-3. |
curl "https://visa.orizn.app/api/v1/visa/check?passport=FRA&destination=JPN" \ -H "x-api-key: YOUR_API_KEY"
{
"passport": "FRA",
"destination": "JPN",
"requirement": "visa_free",
"visa_free_days": 90,
"visa_required": false,
"_hint": "Upgrade to get documents, process, embassies, photo specs and 28 more fields.",
"_upgrade_preview": {
"documents_required": 4,
"process_steps": 3,
"embassy_info": true,
"transit_visa": true,
"visa_fees": false,
"vaccinations": 0,
"safety_advisory": "level 1",
"languages": 15,
"upgrade_url": "https://visa.orizn.app/visa-api/pricing"
}
}/api/v1/visa/bulkclave api · hobby+Destinos en bloque para un pasaporte
One passport against up to 25 destinations in a single round-trip. Pass a comma-separated destinations list (required, max 25 per call). Each returned pair counts as one request against your monthly quota. Returns a curated subset of the extended fields (fees, safety, health, vaccinations, insurance, entry-by-mode, remote-work).
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| passport | string | Sí | ISO 3166-1 alpha-3. |
| destination | string | No | Lista ISO3 separada por comas, p. ej. JPN,THA,BRA. Omítelo para devolver todos los destinos. |
| lang | string | No | Por defecto en. Uno de los 15 códigos soportados. |
curl "https://visa.orizn.app/api/v1/visa/bulk?passport=FRA" \ -H "x-api-key: YOUR_API_KEY"
{
"passport": "FRA",
"lang": "en",
"total": 199,
"destinations": [
{
"destination": "JPN",
"requirement": "visa_free",
"visa_free_days": 90,
"description": "Visa-free for up to 90 days.",
"passport_validity_months": 3,
"visa_fee": { "single_entry": { "amount": 0, "currency": "JPY" } },
"safety": { "level": 1 },
"health_requirements": { "covid_test": false },
"vaccinations_required": [],
"insurance_required": { "required": false },
"entry_by_mode": { "air": 90, "land": 90, "sea": 90 },
"remote_work_visa": { "available": false }
}
]
}/api/v1/visa/groupclave api · hobby+Viaje en grupo — intersección multi-pasaporte
Built for group travel: pass 2-10 passports and get back every destination accessible by ALL of them, with the per-passport breakdown and the group's worst-case requirement. By default a destination qualifies when every passport is visa_free, eta, visa_on_arrival or e_visa — narrow or widen with the allow param (e.g. allow=visa_free for strictly visa-free). group_visa_free_days is the minimum allowed stay across the group, i.e. the binding constraint for a shared trip. Destinations are sorted easiest-first. Each passport×destination pair served counts as one request.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| passports | string | Sí | Lista ISO3 separada por comas, de 2 a 10 códigos distintos. Ejemplo: USA,FRA,IND. |
| allow | string | No | Tipos de requisito que califican, separados por comas. Por defecto: visa_free,eta,visa_on_arrival,e_visa. |
curl "https://visa.orizn.app/api/v1/visa/group?passports=USA,FRA,IND" \ -H "x-api-key: YOUR_API_KEY"
{
"passports": ["USA", "FRA", "IND"],
"allow": ["visa_free", "eta", "visa_on_arrival", "e_visa"],
"total": 97,
"excluded": { "requirement_not_allowed": 100, "incomplete_data": 4 },
"destinations": [
{
"destination": "FJI",
"group_requirement": "visa_free",
"group_visa_free_days": 120,
"by_passport": {
"USA": { "requirement": "visa_free", "visa_free_days": 120 },
"FRA": { "requirement": "visa_free", "visa_free_days": 120 },
"IND": { "requirement": "visa_free", "visa_free_days": 120 }
}
}
]
}/api/v1/visa/decisionclave api · cualquier planItinerary decision — answers a trip, not a pair
Post a whole trip — passport, ordered stops with dates, transit stops, passport expiry — and get a per-step decision plus the blockers only a full itinerary reveals: days accumulated across repeat visits to the same country, passport validity measured against each arrival date, and an expiry that falls before the last exit. Every field states its granularity (pair or destination) and every gap comes back as status: "unknown" with a reason, never as a default value. verdict is no_blocker_found or blocked — it reports what the data supports, it is not legal advice.
{
"passport": "FRA",
"residence": "VNM",
"passport_expiry": "2027-03-01",
"itinerary": [
{ "country": "THA", "from": "2026-09-01", "to": "2026-09-20" },
{ "country": "VNM", "from": "2026-09-20", "to": "2026-10-10" },
{ "country": "THA", "from": "2026-10-10", "to": "2026-10-25" }
],
"transit": ["SGP"],
"purpose": "tourism"
}curl -X POST "https://visa.orizn.app/api/v1/visa/decision" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "passport": "FRA", "residence": "VNM", "passport_expiry": "2027-03-01", "itinerary": [ { "country": "THA", "from": "2026-09-01", "to": "2026-09-20" }, { "country": "VNM", "from": "2026-09-20", "to": "2026-10-10" }, { "country": "THA", "from": "2026-10-10", "to": "2026-10-25" } ], "transit": ["SGP"], "purpose": "tourism" }'
{
"data": {
"passport_country": "FRA",
"steps": [
{
"country": "THA", "from": "2026-09-01", "to": "2026-09-20", "days": 20,
"admission": "allowed",
"regime": { "status": "known", "value": "visa_free", "granularity": "pair",
"source_url": null, "last_verified": null },
"max_stay": { "status": "known", "days": 30, "granularity": "pair", "basis": "visa_free_days" },
"passport_validity_months": { "status": "known", "months": 6, "granularity": "destination" }
}
],
"transit": [
{ "country": "SGP", "status": "destination_rule", "granularity": "destination",
"note": "Applies to the airport, not to this nationality. Confirm with the carrier before booking." }
],
"passport": { "expiry": "2027-03-01", "status": "checked", "valid_through_itinerary": true,
"per_destination": [{ "country": "THA", "arrival": "2026-09-01",
"required_months": 6, "satisfied": true }] },
"blockers": [
{ "type": "stay_exceeds_allowance", "country": "THA",
"detail": "Itinerary spends 36 day(s) in THA, above the 30-day allowance recorded for this pair." }
],
"unknowns": [
{ "field": "residence",
"reason": "Residence is not a dimension of the dataset. Decisions assume a passport holder applying as a national; residence permits may grant additional rights not modelled here." }
],
"verdict": "blocked"
},
"meta": { "api_version": "1.0", "pairs_charged": 3, "max_steps": 12 }
}/api/v1/visa/statspúblico — sin authfuera de cuotaEstadísticas de cobertura
Public, no auth, edge-cached for one hour. Use it on marketing pages to display live coverage numbers and a breakdown of how many pairs fall into each requirement bucket.
curl "https://visa.orizn.app/api/v1/visa/stats"
{
"coverage": {
"visa_details": 49750,
"passports": 199,
"destinations": 250,
"passport_index_pairs": 49750,
"translations": 691261,
"languages": 15
},
"supported_languages": [
{ "code": "en", "name": "English" },
{ "code": "fr", "name": "Français" }
],
"requirement_distribution": {
"visa_free": 14210,
"visa_required": 12740,
"e_visa": 4830,
"visa_on_arrival": 5102,
"eta": 2103,
"no_admission": 600
},
"api_version": "1.0",
"docs": "https://visa.orizn.app"
}Puntuaciones de movilidad públicas — un solo pasaporte o comparación lado a lado.
/api/v1/visa/scorepúblico — sin authfuera de cuotaPuntuación de movilidad del pasaporte
Composite mobility score and global rank for one passport. The score factors in visa-free / visa-on-arrival / e-visa access, destination diversity, and an economic weighting. Public — no key required.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| passport | string | Sí | ISO 3166-1 alpha-3. |
curl "https://visa.orizn.app/api/v1/visa/score?passport=FRA"
{
"passport": "FRA",
"score": 96.4,
"rank": 3,
"breakdown": {
"visa_free": { "count": 158, "weight": 0.55 },
"visa_on_arrival": { "count": 17, "weight": 0.15 },
"e_visa": { "count": 20, "weight": 0.10 },
"diversity": { "continents": 6, "weight": 0.10 },
"economic": { "score": 88, "weight": 0.10 }
},
"total_accessible": 195
}/api/v1/visa/score/comparepúblico — sin authfuera de cuotaComparar dos pasaportes
Side-by-side comparison of two passports: their individual scores, the set difference of destinations they unlock, and a normalised combined-passport score (the max destinations any single passport can reach is 250 → 1000 points). Powers dual-citizenship calculators and second-passport landing pages.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| passport1 | string | Sí | Primer pasaporte, ISO 3166-1 alpha-3. |
| passport2 | string | Sí | Segundo pasaporte, ISO 3166-1 alpha-3. Debe ser distinto de passport1. |
curl "https://visa.orizn.app/api/v1/visa/score/compare?passport1=FRA&passport2=MAR"
{
"passport1": { "code": "FRA", "score": 96.4, "rank": 3 },
"passport2": { "code": "MAR", "score": 41.2, "rank": 75 },
"combined": {
"score": 988,
"total_accessible": 197,
"only_passport1": ["USA", "CAN", "GBR"],
"only_passport2": ["DZA", "TUN"],
"both": ["JPN", "THA", "BRA"],
"neither": ["PRK"]
},
"share_text": "FRA + MAR unlock 197/250 destinations — share your dual-passport score on https://visa.orizn.app"
}Stream SSE en tiempo real + snapshot reciente para widgets de prueba social.
/api/v1/visa/livepúblico — sin authfuera de cuotaStream de actividad en vivo (SSE)
Server-Sent Events. Each successful /visa or /visa/check call worldwide produces an event with the passport + destination + timestamp. A `: keepalive` comment is sent every 2 s when no new traffic. Perfect for social-proof tickers on landing pages.
curl "https://visa.orizn.app/api/v1/visa/live"
// Content-Type: text/event-stream
data: {"passport":"USA","destination":"JPN","timestamp":"2026-05-31T09: 14: 00Z"}
data: {"passport":"IND","destination":"ARE","timestamp":"2026-05-31T09: 13: 58Z"}
: keepalive/api/v1/visa/live/recentpúblico — sin authfuera de cuotaSnapshot de actividad reciente
Same data as /live but as a single JSON snapshot — last 20 events, plus aggregate counters and the top-5 most popular corridors today. Edge-cached for 5 seconds.
curl "https://visa.orizn.app/api/v1/visa/live/recent"
{
"entries": [
{ "passport": "USA", "destination": "JPN", "timestamp": "2026-05-31T09: 14: 00Z" },
{ "passport": "IND", "destination": "ARE", "timestamp": "2026-05-31T09: 13: 58Z" }
],
"stats": { "today": 14328, "this_week": 92041, "total": 1248302 },
"top_corridors": [
{ "pair": "USA→JPN", "count": 412 },
{ "pair": "IND→ARE", "count": 388 },
{ "pair": "DEU→THA", "count": 301 }
]
}Suscribe dispositivos (iOS / Android) a alertas de cambios de política.
/api/v1/visa/devicesclave api · cualquier planfuera de cuotaRegistrar un dispositivo para push
Subscribe an APNs / FCM device token to receive push notifications when visa policies change. Each device tracks one passport plus an optional wishlist of destinations and a set of preferences (instant alerts, weekly digest, wishlist-only, positive-changes-only).
{
"device_token": "8a3f...e2b1",
"passport_iso3": "FRA",
"platform": "ios",
"bundle_id": "com.orizn-visa",
"wishlist_iso3": ["THA", "JPN", "BRA"],
"locale": "en",
"tz": "Europe/Paris",
"premium": false,
"preferences": {
"instant": true,
"digest_weekly": true,
"only_wishlist": false,
"only_positive": false
}
}curl -X POST "https://visa.orizn.app/api/v1/visa/devices" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "device_token": "8a3f...e2b1", "passport_iso3": "FRA", "platform": "ios", "bundle_id": "com.orizn-visa", "wishlist_iso3": ["THA", "JPN", "BRA"], "locale": "en", "tz": "Europe/Paris", "premium": false, "preferences": { "instant": true, "digest_weekly": true, "only_wishlist": false, "only_positive": false } }'
{ "device_id": 42 }/api/v1/visa/devices/{id}clave api · cualquier planfuera de cuotaActualizar la suscripción de un dispositivo
Update any subset of the subscription fields — passport, wishlist, locale, timezone, premium flag, preferences. At least one field is required.
{
"wishlist_iso3": ["THA", "JPN", "BRA", "PRT"],
"preferences": { "only_wishlist": true }
}curl -X PATCH "https://visa.orizn.app/api/v1/visa/devices/42" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "wishlist_iso3": ["THA", "JPN", "BRA", "PRT"], "preferences": { "only_wishlist": true } }'
{ "updated": true, "device_id": 42 }/api/v1/visa/devices/{id}clave api · cualquier planfuera de cuotaDar de baja un dispositivo
Permanently delete the device subscription. Use this when the user revokes notifications or uninstalls.
curl -X DELETE "https://visa.orizn.app/api/v1/visa/devices/42" \ -H "x-api-key: YOUR_API_KEY"
{ "deleted": true, "device_id": 42 }Entrega de cambios de política servidor a servidor. Payloads firmados con HMAC.
/api/v1/visa/webhooksclave api · business+fuera de cuotaListar tus webhooks
Returns every webhook subscription owned by your account, including its filters, last trigger time, and failure counter.
curl "https://visa.orizn.app/api/v1/visa/webhooks" \ -H "x-api-key: YOUR_API_KEY"
{
"webhooks": [
{
"id": 17,
"url": "https://your-app.com/orizn-hook",
"passport_filter": ["FRA"],
"destination_filter": null,
"active": true,
"created_at": "2026-05-29T09: 14: 00Z",
"last_triggered_at": "2026-05-31T08: 02: 11Z",
"failures": 0
}
]
}/api/v1/visa/webhooksclave api · business+fuera de cuotaCrear un webhook
Register a URL to receive POSTs whenever a policy change matches your filter. The response contains a one-time secret — store it now, we won't show it again. Sign verifications use HMAC-SHA256 of the raw body keyed by the secret.
{
"url": "https://your-app.com/orizn-hook",
"passport_filter": ["FRA"],
"destination_filter": ["THA", "JPN"]
}curl -X POST "https://visa.orizn.app/api/v1/visa/webhooks" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.com/orizn-hook", "passport_filter": ["FRA"], "destination_filter": ["THA", "JPN"] }'
{
"webhook": {
"id": 17,
"url": "https://your-app.com/orizn-hook",
"passport_filter": ["FRA"],
"destination_filter": ["THA", "JPN"],
"active": true,
"secret": "whsec_4f2a91c8...e2b1",
"created_at": "2026-05-31T09: 14: 00Z"
},
"message": "Webhook created. Store the secret — it won't be shown again."
}/api/v1/visa/webhooks?id={id}clave api · business+fuera de cuotaEliminar un webhook
Permanently delete a webhook subscription you own.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| id | int | Sí | Id del webhook, obtenido de list/create. |
curl -X DELETE "https://visa.orizn.app/api/v1/visa/webhooks?id=42?id=42" \ -H "x-api-key: YOUR_API_KEY"
{ "deleted": true, "id": 17 }Subclaves por entorno que comparten la cuota de la cuenta propietaria.
/api/v1/visa/team-keysclave api · business+fuera de cuotaListar las claves de equipo
Return every team subkey under your account. Each team key inherits its owner's plan and shares the same monthly quota — useful for isolating environments or attributing usage.
curl "https://visa.orizn.app/api/v1/visa/team-keys" \ -H "x-api-key: YOUR_API_KEY"
{
"team_keys": [
{
"id": 7,
"api_key": "orizn_visa_team_a1b2c3...",
"name": "ci-staging",
"active": true,
"requests_month": 14823,
"requests_total": 184238,
"created_at": "2026-05-12T11: 04: 00Z"
}
]
}/api/v1/visa/team-keysclave api · business+fuera de cuotaCrear una clave de equipo
Mint a new team subkey. The key is prefixed orizn_visa_team_ and immediately usable in the x-api-key header. Shared quota with the owner account.
{ "name": "ci-staging" }curl -X POST "https://visa.orizn.app/api/v1/visa/team-keys" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "ci-staging" }'
{
"team_key": {
"id": 7,
"api_key": "orizn_visa_team_a1b2c3...",
"name": "ci-staging",
"active": true,
"requests_month": 0,
"requests_total": 0,
"created_at": "2026-05-31T09: 14: 00Z"
},
"message": "Team key created. It shares the monthly quota of the owner account."
}/api/v1/visa/team-keys?id={id}clave api · business+fuera de cuotaDesactivar una clave de equipo
Soft delete — flips active to false. Existing requests with the key start returning 403 immediately.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| id | int | Sí | Id de la clave de equipo. |
curl -X DELETE "https://visa.orizn.app/api/v1/visa/team-keys?id=42?id=42" \ -H "x-api-key: YOUR_API_KEY"
{ "deactivated": true, "team_key": { "id": 7, "name": "ci-staging" } }Registro autoservicio, rotación de claves y facturación alojada en Stripe.
/api/v1/visa/registerpúblico — sin authfuera de cuotaRegistrarse (obtener una clave API gratuita)
Self-serve signup. Returns a free-plan API key (100 req/month). Idempotent on email — re-registering returns the existing key instead of creating a duplicate.
{ "name": "Ada Lovelace", "email": "[email protected]" }curl -X POST "https://visa.orizn.app/api/v1/visa/register" \ -H "Content-Type: application/json" \ -d '{ "name": "Ada Lovelace", "email": "[email protected]" }'
{
"api_key": "orizn_visa_a06113a2e4f0...",
"plan": "free",
"message": "API key created successfully."
}/api/v1/visa/auth/ensure-keycookie de sesiónfuera de cuotaObtener la clave API del usuario conectado
Dashboard helper: validates the orizn_token cookie against api.orizn.app/auth/me, then returns the matching visa_api_users row — creating one on the free plan if the Orizn account doesn't have one yet.
curl "https://visa.orizn.app/api/v1/visa/auth/ensure-key" \ --cookie "orizn_token=YOUR_SESSION"
{
"user": {
"id": 42,
"orizn_id": "01HZ...",
"email": "[email protected]",
"name": "Ada Lovelace",
"photo": "https://...",
"plan": "pro",
"api_key": "orizn_visa_a06113...",
"requests_month": 14238,
"requests_total": 412938,
"monthly_limit": 250000,
"created_at": "2026-04-12T11: 04: 00Z"
}
}/api/v1/visa/auth/regenerate-keycookie de sesiónfuera de cuotaRotar la clave API
Generate a new key and invalidate the old one. Use this when a key may have leaked. Affects only the owner row, not team subkeys.
curl -X POST "https://visa.orizn.app/api/v1/visa/auth/regenerate-key" \ --cookie "orizn_token=YOUR_SESSION" \ -H "Content-Type: application/json" \ -d '{}'
{
"api_key": "orizn_visa_b71224...",
"message": "API key rotated. Update your clients."
}/api/v1/visa/stripe/checkoutcookie de sesiónfuera de cuotaIniciar el checkout de un plan de pago
Returns a Stripe Checkout session URL. Redirect the user to it; on success Stripe pings our webhook which upgrades their plan. Annual billing with a valid affiliate_id grants a 30-day trial.
{
"plan": "pro",
"billing": "monthly",
"affiliate_id": "aff_4f2a91c8"
}curl -X POST "https://visa.orizn.app/api/v1/visa/stripe/checkout" \ --cookie "orizn_token=YOUR_SESSION" \ -H "Content-Type: application/json" \ -d '{ "plan": "pro", "billing": "monthly", "affiliate_id": "aff_4f2a91c8" }'
{ "url": "https://checkout.stripe.com/c/pay/cs_test_..." }/api/v1/visa/stripe/portalcookie de sesiónfuera de cuotaAbrir el portal de facturación de Stripe
Returns a one-time URL into Stripe's customer portal — invoices, payment method, plan changes, cancellation.
curl -X POST "https://visa.orizn.app/api/v1/visa/stripe/portal" \ --cookie "orizn_token=YOUR_SESSION" \ -H "Content-Type: application/json" \ -d '{}'
{ "url": "https://billing.stripe.com/p/session/..." }Gana un 15% de comisión sobre las suscripciones referidas — web + iOS.
/api/v1/visa/affiliate/registerpúblico — sin authfuera de cuotaConvertirse en afiliado
Open a partner account. We mint an affiliate_id (format aff_<8 hex>) you embed in checkout URLs to earn 15% commission on every subscription you refer. Idempotent on email.
{
"name": "Ada Lovelace",
"email": "[email protected]",
"website": "https://travelblog.example",
"payment_method": "paypal",
"payment_info": "[email protected]",
"source": "web"
}curl -X POST "https://visa.orizn.app/api/v1/visa/affiliate/register" \ -H "Content-Type: application/json" \ -d '{ "name": "Ada Lovelace", "email": "[email protected]", "website": "https://travelblog.example", "payment_method": "paypal", "payment_info": "[email protected]", "source": "web" }'
{
"affiliate_id": "aff_4f2a91c8",
"dashboard_url": "https://visa.orizn.app/affiliate?aff=aff_4f2a91c8&email=ada%40example.com",
"message": "Affiliate account ready. Share your link to earn 15% commission."
}/api/v1/visa/affiliate/track-clickpúblico — sin authfuera de cuotaRegistrar un clic de afiliado
Increment the click counter for an affiliate_id. Fire-and-forget from your landing pages and ad creatives.
{ "affiliate_id": "aff_4f2a91c8" }curl -X POST "https://visa.orizn.app/api/v1/visa/affiliate/track-click" \ -H "Content-Type: application/json" \ -d '{ "affiliate_id": "aff_4f2a91c8" }'
{ "ok": true }/api/v1/visa/affiliate/apply-referralclave api · cualquier planfuera de cuotaVincular un referido a un usuario
Bind YOUR account to a referrer after sign-up — typical use is the iOS app collecting a referral code post-registration. Requires your API key: the referred account is the one owning the key. Sets referred_by; the referrer earns 15% on your future subscriptions.
{ "referral_code": "aff_4f2a91c8" }curl -X POST "https://visa.orizn.app/api/v1/visa/affiliate/apply-referral" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "referral_code": "aff_4f2a91c8" }'
{
"ok": true,
"message": "Referral applied successfully. The referrer will earn 15% commission on your future subscriptions.",
"referred_by": "aff_4f2a91c8"
}/api/v1/visa/affiliate/statspúblico — sin authfuera de cuotaDatos del dashboard de afiliados
Lifetime + this-month performance for an affiliate account: clicks, conversions, referred users, revenue, commission breakdowns by product and platform, and the 20 most recent transactions. Authenticated via either the orizn_token cookie (Orizn account login) or affiliate_id + email query params.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
| affiliate_id | string | No | Obligatorio sin cookie de sesión. Formato aff_<8 hex>. |
| string | No | Obligatorio sin cookie de sesión. Debe coincidir con el email del afiliado. |
curl "https://visa.orizn.app/api/v1/visa/affiliate/stats"
{
"affiliate_id": "aff_4f2a91c8",
"active": true,
"source": "web",
"clicks": 1423,
"conversions": 28,
"referred_users": 28,
"revenue_cents": 419800,
"commission_rate": 0.15,
"commission_cents": 62970,
"this_month": { "transactions": 7, "revenue_cents": 138600, "commission_cents": 20790 },
"by_product": {
"orizn.visa.premium.annual": { "transactions": 18, "commission_cents": 47100 },
"orizn.visa.premium.monthly": { "transactions": 10, "commission_cents": 15870 }
},
"by_platform": { "ios": 22, "web": 6 },
"recent_transactions": [
{ "product": "orizn.visa.premium.annual", "platform": "ios", "amount_cents": 19800, "commission_cents": 2970, "date": "2026-05-30T18: 14: 00Z" }
],
"payment_method": "paypal",
"payment_info_masked": "a***@paypal.com",
"links": {
"visa_app": "https://visa.orizn.app?aff=aff_4f2a91c8",
"guide": "https://visa.orizn.app/guide?aff=aff_4f2a91c8",
"extension": "https://visa.orizn.app/extension?aff=aff_4f2a91c8",
"api": "https://visa.orizn.app/api?aff=aff_4f2a91c8"
}
}Campos de la respuesta
Cada respuesta de GET /api/v1/visa incluye los campos de abajo. Los campos sin relevancia para un par dado valen null, un array vacío, o se omiten — puedes confiar en la forma, no en la presencia.
| campo | Tipo | Descripción |
|---|---|---|
| passport | string | ISO 3166-1 alpha-3 (p. ej. FRA) |
| destination | string | ISO 3166-1 alpha-3 (p. ej. JPN) |
| requirement | enum | visa_free | visa_required | e_visa | visa_on_arrival | eta | no_admission |
| visa_free_days | int | null | Número de días permitidos sin visa (null si se requiere visa) |
| visa_required | bool | True si se necesita cualquier trámite de visa |
| description | string | Resumen legible y localizado |
| documents_required | string[] | Documentos que llevar/presentar |
| process | string[] | Proceso de solicitud paso a paso |
| tips | string[] | Consejos de viaje |
| country_info | object | Moneda, idioma, zona horaria, capital |
| verified | bool | True only when an official source confirms this exact pair |
| source | string | null | Where the value came from (e.g. official, manual) |
| source_url | string | null | Official page this pair was read from — null until the pair has been re-sourced |
| last_verified_at | string | null | ISO 8601 date source_url was last read — null whenever source_url is null |
| last_verified | string | null | Same date as last_verified_at, as YYYY-MM-DD (the field /check and MCP also return) |
| requirement_status | string | Only on legally unsettled pairs. Currently the single value uncertain — key absent otherwise |
| requirement_status_note | string | null | Plain-English reason the regime is unsettled, safe to show to a traveler |
| campo | Tipo | qué te dice |
|---|---|---|
| transit_visa | object | Reglas de visa de tránsito y horas de tránsito libre en los principales hubs |
| passport_validity_months | int | Validez mínima del pasaporte exigida a la entrada |
| visa_fee | object | Coste de la visa de entrada única y de entradas múltiples, con moneda |
| processing_days | object | Tiempos de tramitación estándar / exprés / urgente |
| photo_specs | object | Dimensiones de la foto (mm), fondo, reglas sobre gafas y cubrecabezas |
| vaccinations_required | string[] | Vacunas obligatorias (p. ej. yellow_fever) |
| insurance_required | object | Cobertura mínima de seguro de viaje requerida |
| dual_nationality_warnings | string[] | Advertencias para dobles nacionales (p. ej. servicio militar) |
| stamp_warnings | string[] | Sellos en el pasaporte que pueden bloquear la entrada |
| minor_rules | object | Reglas para viajeros menores de 18 años |
| overstay_penalty | object | Multa por día, duración de la prohibición de entrada, responsabilidad penal |
| entry_by_mode | object | Límites de estancia distintos según llegada por aire / tierra / mar |
| remote_work_visa | object | Disponibilidad de visa de nómada digital, duración, tarifa |
| extension_rules | object | Si la estancia se puede extender, días máximos, tarifa, dónde |
| reciprocity_history | object[] | Historial de cambios de política entre los dos países |
| safety | object | Nivel de alerta de viaje (1–4) con fuente y última actualización |
| best_apply_period | string | Ventana de solicitud recomendada |
| health_requirements | object | Test COVID, prueba de vacunación, cuarentena, controles sanitarios |
| embassy.your_embassy_at_destination | object | La embajada de tu país en el destino — emergencias |
| embassy.visa_application_embassy | object | La embajada del destino en tu país — dónde solicitar |
Data quality
Every /visa response carries source_url and last_verified_at: the official page a pair was read from, and the date it was last read. Cite them in your own UI — that is what they are for.
Both fields are null on pairs that have not been re-sourced yet, and that is most of them. 56 of the 199 passport countries currently have an official source on file; the rest are answered from the consolidated dataset without a citation. A null here means we cannot show you a document, not that the answer is wrong — but if your product makes a claim a user could act on, treat a null as unverified and say so.
Coverage grows; the numbers above are a snapshot, not a ceiling. Do not branch on the count — branch on the field.
Most visa datasets answer every pair with a definite requirement, because their schema has no way to say anything else. Some pairs do not have a definite answer. When a country leaves a bloc whose freedom-of-movement treaty was the legal basis for entry, what happens at the border and what the law guarantees stop being the same thing. Burkina Faso, Mali and Niger left ECOWAS on 2025-01-29: visa-free movement between them and the remaining member states now rests on unilateral, revocable declarations rather than on a treaty.
On those pairs the response carries requirement_status: "uncertain" and a requirement_status_note you can show to a traveler verbatim. requirement itself is untouched — it stays visa_free, because that is what happens at the border today. The status says the right no longer exists; the requirement says the practice continues. Both are true, and a comparison test found no other source that reports the difference.
Because it is a separate, additive field, a client that ignores it sees no change at all — nothing breaks, you simply keep the old blind spot. The key is absent on every pair that is not affected, so test for presence, not for a value. Currently uncertain is the only value.
Three gaps, stated here because an endpoint you are meant to defend a decision with has to name its blind spots. They also come back inside every response, in the unknowns array, per field and per country — you never have to remember this page at runtime.
- Transit is a dead end on most of the map. A transit rule exists for 44 of 250 destinations and is recorded per transited country, not per nationality — so even where it exists it never says whether this passport may transit. Every other destination returns status: "unknown". Confirm transit with the carrier, always.
- residence and purpose are accepted, echoed back, and not modelled. The dataset has no residence dimension and covers short-stay tourism only. Send a residence different from the passport, or a purpose other than tourism, and you get an entry in unknowns saying exactly that — a residence permit may grant rights this endpoint cannot see.
- Length of stay is only computed where a numeric allowance exists. visa_free_days is the one figure the dataset holds; where the permitted stay depends on the permit issued, max_stay is unknown rather than a parsed guess, and no accumulation blocker can be raised for that country.
verdict: "no_blocker_found" is worded the way it is on purpose. It means the checks that could run found nothing — not that the trip is cleared.
Matriz de planes
| funcionalidad | Gratuito | hobby (legacy) | starter $49 | pro $199 | business $699 |
|---|---|---|---|---|---|
| Solicitudes mensuales | 100 | 10,000 | 30,000 | 250,000 | 1,000,000 |
| Tasa de ráfaga (req/s) | 10 | 25 | 50 | 100 | 200 |
| /visa, /visa/check | ✓ (15 idiomas) | ✓ (15 idiomas) | ✓ (15 idiomas) | ✓ | ✓ |
| /visa — campos extendidos | stubs | stubs | todos excepto remote-work, reciprocity | todos | todos |
| /visa/bulk (todos los destinos) | — | ✓ | ✓ | ✓ | ✓ |
| /visa/group (multi-pasaporte) | — | ✓ | ✓ | ✓ | ✓ |
| /visa/decision (itinerary) | ✓ | ✓ | ✓ | ✓ | ✓ |
| Suscripciones push de dispositivos | ✓ | ✓ | ✓ | ✓ | ✓ |
| Webhooks (servidor a servidor) | — | — | — | — | ✓ |
| Subclaves de equipo | — | — | — | — | ✓ |
| Score, compare, stats, live | ✓ (público) | ✓ | ✓ | ✓ | ✓ |
Los planes Enterprise añaden solicitudes ilimitadas, tasas de ráfaga personalizadas, despliegue on-premise, IPs dedicadas y un SLA del 99,95%. Habla con nosotros.
5. Límites
Quotas reset on the 1st of each calendar month (UTC). Only the five counted endpoints — /visa, /visa/check, /visa/bulk, /visa/group y /visa/decision — increment your monthly counter. Score, stats, live, devices, webhooks and team-keys management are gratis respecto a tu cuota.
| Plan | Precio | Límite mensual | Tasa | aspectos clave |
|---|---|---|---|---|
| Evaluation | $0 | 100 | 10 req/s | non-commercial evaluation, no SLA |
| Commercial | 49$/mes | 30,000 | 50 req/s | + commercial use rights, all 15 languages, extended fields |
| Production | 199$/mes | 250,000 | 100 req/s | + uptime SLA, named contact, 1 business day support |
| License | from $600/mo | Personalizado | Personalizado | + white-label, redistribution, dataset snapshot |
Por encima de tu cuota recibes HTTP 429 con X-RateLimit-Reset indicando cuándo se abre la siguiente ventana.
Headers de respuesta
| header | valor | dónde |
|---|---|---|
| X-RateLimit-Limit | Cuota mensual de tu plan | /visa, /visa/check, /visa/bulk |
| X-RateLimit-Remaining | Llamadas restantes este mes | /visa, /visa/check, /visa/bulk |
| X-RateLimit-Reset | Marca de tiempo ISO del próximo reinicio (solo se envía con 429) | /visa, /visa/check, /visa/bulk |
| X-Plan | Tu plan actual (free, starter, pro, business, enterprise) | /visa, /visa/check, /visa/bulk |
| X-Powered-By | orizn Visa API v1 | Todos los endpoints autenticados |
| X-Orizn-Upgrade | URL de la página de mejora (solo en free) | /visa, /visa/check |
| Vary | Accept (presente cuando la negociación Markdown está disponible) | /visa, /visa/check |
| Cache-Control | public, max-age=3600 (stats) · max-age=5 (live/recent) · no-store (live) | Endpoints públicos |
6. Códigos de error
Los errores devuelven un cuerpo JSON con una forma estable. Usa el estado HTTP para enrutar, el cuerpo para diagnosticar, y las píldoras de error de cada endpoint de arriba cuando quieras saber exactamente qué código 4xx viene de qué condición.
| Código | Significado | causa típica |
|---|---|---|
| 400 | Solicitud inválida | Parámetro ausente o malformado — código no ISO3, lang no soportado, cuerpo inválido |
| 401 | No autorizado | Falta el header x-api-key / la query api_key / la cookie orizn_token |
| 403 | Prohibido | Clave inválida o inactiva, o tu plan no incluye este endpoint |
| 404 | No encontrado | Sin datos para este par / recurso que no te pertenece |
| 409 | Conflicto | Carrera de restricción de unicidad (registro de afiliado) — seguro de reintentar |
| 429 | Demasiadas solicitudes | Cuota mensual o tasa de ráfaga excedida |
| 500 | Error interno | Problema transitorio del backend — reintenta con backoff exponencial |
{
"error": "Monthly limit exceeded (100 req/month on free plan). Upgrade at https://visa.orizn.app",
"plan": "free",
"limit": 50,
"upgrade_url": "https://visa.orizn.app/visa-api/pricing"
}7. Idiomas soportados
Pasa lang como parámetro de consulta (o en el cuerpo JSON en los POST). Por defecto en. Los 15 idiomas están disponibles en todos los planes, incluido el gratuito.
SDKs oficiales
Wrappers escritos a mano — totalmente tipados, con reintentos, backoff ante límites de tasa y un tipo de error estructurado.
npm install orizn # JavaScript / TypeScript pip install orizn # Python cargo add orizn # Rust npx orizn-visa-mcp # MCP server (Claude, Cursor, Codex) pip install langchain-orizn # LangChain Python npm install @orizn/langchain # LangChain JS
8. Registro de cambios
Campos extendidos + referencia completa de endpoints
- 21 nuevos campos opcionales en /visa: tránsito, tarifas, especificaciones de foto, vacunas, seguro, embajadas, seguridad, sanciones por sobreestancia, historial de reciprocidad, visa de trabajo remoto, reglas de extensión.
- Nueva herramienta MCP
check_transit_visa; descripciones enriquecidas para que los agentes elijan la herramienta correcta. - La página de docs ahora cubre los 28 endpoints públicos — datos de visa, scoring, live, dispositivos, webhooks, claves de equipo, cuenta, afiliados.
- SDK v1.1:
[email protected](npm),orizn==1.1.0(PyPI),[email protected]. - Retrocompatible — los clientes antiguos siguen funcionando, los campos nuevos son aditivos.
Lanzamiento
- 49,750 pares pasaporte/destino cubiertos
- 15 idiomas soportados (en, fr, es, pt, de, it, ja, ko, zh, ru, ar, hi, th, vi, tl)
- Endpoints: check, visa, bulk, changes, stats, register
- Planes: Free (100/mes), Starter (49$), Pro (199$), Business (699$), Enterprise
- Dashboard con analíticas de uso, facturación y documentación interactiva