Orizn Visa API · v1.1

Documentation API

De l'intelligence visa prête pour la production — 40 027 paires passeport/destination, 30 points de données chacune, 15 langues. 28 endpoints REST répartis sur 8 surfaces produit.

Spécification OpenAPI 3.0.3
Importez-la dans Postman, Insomnia ou RapidAPI, ou générez un SDK client dans n'importe quel langage.
opérationnel en 60 secondes

Démarrage rapide

Chaque compte Orizn est livré avec une clé API personnelle. Passez-la via le header x-api-key (ou le paramètre de requête?api_key= ) et vous êtes en ligne.

curl "https://visa.orizn.app/api/v1/visa?passport=FRA&destination=JPN&lang=en" \
  -H "x-api-key: YOUR_API_KEY"

URL de base : https://visa.orizn.app · JSON en entrée/sortie · UTF-8 · CORS ouvert sur tous les endpoints publics.

1. Authentification

Il existe trois façons de s'authentifier, selon l'endpoint :

1 · Clé API

Header x-api-key

Le défaut pour du code produit. Aussi accepté via le paramètre de requête ?api_key= .

2 · Public

aucune authentification

Stats, score, live, inscription, flux d'affiliation. /visa/check est aussi accessible sans clé depuis visa.orizn.app, localhost ou une extension Chrome.

3 · Session

Cookie orizn_token

Endpoints du dashboard (rotation de clé, checkout/portail Stripe, analytics). Posé automatiquement à la connexion au 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"

N'exposez jamais votre clé dans du code client distribué à des utilisateurs non fiables — passez par votre backend. Les clés peuvent être régénérées à tout moment depuis le dashboard.

ce que tous les endpoints partagent

Conventions

ISO 3166-1 alpha-3
Tous les codes passeport et destination sont des codes ISO à 3 lettres (FRA, USA, JPN). 199 pays couverts — la liste canonique vit sur /api/v1/visa/stats.
Versionnage
v1 is stable. New fields are additive — we never rename or remove keys in a minor release. Major releases ship under /api/v2.
CORS
Chaque endpoint public envoie Access-Control-Allow-Origin: *. Le preflight OPTIONS est implémenté sur tous les endpoints de données.
Négociation de contenu
Les endpoints /visa et /visa/check respectent Accept: text/markdown et renvoient un rendu Markdown lisible au lieu du JSON — idéal pour les outils de chat.
Idempotence
POST /register, POST /affiliate/register, POST /affiliate/ios-purchase et POST /devices sont idempotents sur leur clé naturelle (email, transaction_id, device_token).
Temps
Tous les timestamps sont en ISO 8601 avec suffixe UTC. Les quotas mensuels se réinitialisent le 1er de chaque mois, UTC.
28 endpoints · 8 surfaces

2. Endpoints

Tous les endpoints vivent sous https://visa.orizn.app. Les badges sous chaque chemin indiquent le mode d'authentification et le plan minimum.

Données visa

The six endpoints you'll actually call from product code.

GET/api/v1/visaclé api · tout plan

Intelligence visa complète

The flagship endpoint. Returns 30 data points: 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.

Parametres
ParametreTypeRequisDescription
passportstringOuiISO 3166-1 alpha-3 (ex. FRA).
destinationstringOuiISO 3166-1 alpha-3 (ex. JPN).
langstringNonL'un des 15 codes supportés (voir Langues). Le plan gratuit est limité à l'anglais — les autres langues demandent Starter+.
exemple
curl "https://visa.orizn.app/api/v1/visa?passport=FRA&destination=JPN" \
  -H "x-api-key: YOUR_API_KEY"
Reponse · 200 OK
{
  "data": {
    "passport": "FRA",
    "destination": "JPN",
    "requirement": "visa_free",
    "visa_free_days": 90,
    "visa_required": false,
    "description": "French citizens can enter Japan visa-free for up to 90 days.",
    "documents_required": ["Valid passport (3 months)", "Return or onward ticket"],
    "process": ["No prior formalities", "Immigration form on arrival"],
    "tips": ["Carry proof of sufficient funds"],
    "country_info": { "currency": "JPY", "language": "Japanese", "timezone": "UTC+9", "capital": "Tokyo" },
    "verified": true,
    "transit_visa": { "hubs": [{ "airport": "NRT", "city": "Tokyo", "transit_visa_required": false, "transit_free_hours": 24 }] },
    "passport_validity_months": 3,
    "visa_fee": { "single_entry": { "amount": 0, "currency": "JPY" } },
    "processing_days": { "standard": null, "express": null },
    "photo_specs": { "width_mm": 35, "height_mm": 45, "background": "white" },
    "vaccinations_required": [],
    "insurance_required": { "required": false },
    "overstay_penalty": { "fine_per_day": "Variable + deportation", "ban_days": 365, "criminal": true },
    "entry_by_mode": { "air": 90, "land": 90, "sea": 90 },
    "safety": { "level": 1, "advisory": "Exercise normal precautions", "source": "diplomatie.gouv.fr" },
    "health_requirements": { "covid_test": false, "quarantine_days": 0 },
    "embassy": {
      "your_embassy_at_destination": { "name": "Ambassade de France au Japon", "city": "Tokyo", "phone": "+81 3 5798 6000" },
      "visa_application_embassy": { "name": "Ambassade du Japon en France", "city": "Paris" }
    }
  },
  "meta": { "lang": "en", "api_version": "1.1", "coverage": "199 passports x 232 destinations", "languages": 15, "data_points": 30 }
}
Codes d'erreur
400passport/destination manquant ou non ISO3, lang non supportée401clé API manquante403clé invalide/inactive, ou langue non-en sur le plan gratuit404pas de données pour cette paire429quota mensuel dépassé
noteEnvoyez Accept: text/markdown pour recevoir un rendu Markdown lisible au lieu du JSON. Incrémente requests_month et requests_total.
GET/api/v1/visa/checkclé api · tout plan

Vérification visa rapide

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.

Parametres
ParametreTypeRequisDescription
passportstringOuiISO 3166-1 alpha-3.
destinationstringOuiISO 3166-1 alpha-3.
exemple
curl "https://visa.orizn.app/api/v1/visa/check?passport=FRA&destination=JPN" \
  -H "x-api-key: YOUR_API_KEY"
Reponse · 200 OK
{
  "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"
  }
}
Codes d'erreur
400paramètres manquants ou non ISO3401pas de clé API et appel hors d'un Referer/Origin autorisé403clé API invalide404paire introuvable429quota mensuel dépassé
noteLes appels sans clé ne sont acceptés que si le Referer contient visa.orizn.app, localhost, ou si l'Origin commence par chrome-extension:// — c'est ce qui alimente la démo de la landing publique et l'extension navigateur. Supporte Accept: text/markdown.
GET/api/v1/visa/bulkclé api · hobby+

Destinations en masse pour un passeport

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).

Parametres
ParametreTypeRequisDescription
passportstringOuiISO 3166-1 alpha-3.
destinationstringNonListe ISO3 séparée par des virgules, ex. JPN,THA,BRA. Omettez pour renvoyer toutes les destinations.
langstringNonDéfaut : en. L'un des 15 codes supportés.
exemple
curl "https://visa.orizn.app/api/v1/visa/bulk?passport=FRA" \
  -H "x-api-key: YOUR_API_KEY"
Reponse · 200 OK
{
  "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 }
    }
  ]
}
Codes d'erreur
400passport manquant/invalide, liste destination malformée, lang non supportée401clé API manquante403plan inférieur à Hobby404pas de données pour ce passeport429quota mensuel dépassé
noteLa méthode est GET (pas POST). Un appel bulk compte toujours pour 1 dans votre quota.
GET/api/v1/visa/groupclé api · hobby+

Voyage de groupe — intersection multi-passeports

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.

Parametres
ParametreTypeRequisDescription
passportsstringOuiListe ISO3 séparée par des virgules, 2 à 10 codes distincts. Exemple : USA,FRA,IND.
allowstringNonTypes d'exigence acceptés, séparés par des virgules. Défaut : visa_free,eta,visa_on_arrival,e_visa.
exemple
curl "https://visa.orizn.app/api/v1/visa/group?passports=USA,FRA,IND" \
  -H "x-api-key: YOUR_API_KEY"
Reponse · 200 OK
{
  "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 }
      }
    }
  ]
}
Codes d'erreur
400moins de 2 ou plus de 10 passeports, code non ISO3, exigence inconnue dans allow401clé API manquante403plan inférieur à Hobby404pas de données pour l'un des passeports429quota mensuel dépassé
noteParfait pour les retraites et les voyages de groupe : un seul appel répond à « où tout le monde peut-il aller ? ». Un appel group compte toujours pour 1 dans votre quota.
GET/api/v1/visa/changesclé api · starter+hors quota

Flux des changements de politique

Time-ordered stream of policy changes detected by the Orizn scraper — visa requirement flips, day-count updates, fee changes, suspensions, restorations, new policies. Filter by passport, destination, change type, severity, or a wishlist of destinations. Cursor with limit + offset.

Parametres
ParametreTypeRequisDescription
passportstringNonISO3, filtre par pays du passeport.
destinationstringNonISO3, filtre par pays de destination.
sincestringNonTimestamp ISO 8601 ou YYYY-MM-DD. Renvoie les événements à partir de cette date.
typestringNonL'un de : requirement_changed, days_changed, new_policy, suspended, restored, fee_changed, process_changed.
severitystringNonminor | major.
wishliststringNonListe ISO3 séparée par des virgules, ex. THA,JPN,BRA — renvoie les changements qui touchent l'un d'eux.
limitintNonDéfaut 50, max 200.
offsetintNonDéfaut 0, pour la pagination.
exemple
curl "https://visa.orizn.app/api/v1/visa/changes" \
  -H "x-api-key: YOUR_API_KEY"
Reponse · 200 OK
{
  "data": [
    {
      "id": 14283,
      "passport_iso3": "BRA",
      "destination_iso3": "USA",
      "change_type": "requirement_changed",
      "severity": "major",
      "old_requirement": "visa_required",
      "new_requirement": "e_visa",
      "old_days": null,
      "new_days": 90,
      "summary": "US introduces e-Visa pilot for Brazilian passport holders.",
      "source_url": "https://travel.state.gov/...",
      "source_name": "travel.state.gov",
      "effective_date": "2026-06-01",
      "detected_at": "2026-05-22T11: 04: 00Z",
      "verified": true
    }
  ],
  "pagination": { "total": 1238, "limit": 50, "offset": 0, "has_more": true },
  "filters": { "passport": null, "destination": null, "since": null, "type": null, "severity": null, "wishlist": null },
  "change_types": [
    "requirement_changed", "days_changed", "new_policy",
    "suspended", "restored", "fee_changed", "process_changed"
  ]
}
Codes d'erreur
401clé API manquante403clé invalide ou plan inférieur à Starter
noteGratuit vis-à-vis de votre quota — cet endpoint n'incrémente pas les compteurs mensuels.
GET/api/v1/visa/statspublic — sans authhors quota

Statistiques de couverture

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.

exemple
curl "https://visa.orizn.app/api/v1/visa/stats"
Reponse · 200 OK
{
  "coverage": {
    "visa_details": 45987,
    "passports": 199,
    "destinations": 232,
    "passport_index_pairs": 39601,
    "translations": 643818,
    "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"
}
noteCache-Control: public, max-age=3600. Appelable sans risque depuis un frontend statique.
Score de passeport

Scores de mobilité publics — passeport seul ou comparaison côte à côte.

GET/api/v1/visa/scorepublic — sans authhors quota

Score de mobilité d'un passeport

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.

Parametres
ParametreTypeRequisDescription
passportstringOuiISO 3166-1 alpha-3.
exemple
curl "https://visa.orizn.app/api/v1/visa/score?passport=FRA"
Reponse · 200 OK
{
  "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
}
Codes d'erreur
400paramètre passport manquant ou malformé404passeport absent de l'index500erreur interne
noteStructure renvoyée par computePassportScore(). Les noms de champs peuvent évoluer — appuyez-vous sur les clés documentées, pas sur l'ordre des champs.
GET/api/v1/visa/score/comparepublic — sans authhors quota

Comparer deux passeports

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 199 → 1000 points). Powers dual-citizenship calculators and second-passport landing pages.

Parametres
ParametreTypeRequisDescription
passport1stringOuiPremier passeport, ISO 3166-1 alpha-3.
passport2stringOuiSecond passeport, ISO 3166-1 alpha-3. Doit différer de passport1.
exemple
curl "https://visa.orizn.app/api/v1/visa/score/compare?passport1=FRA&passport2=MAR"
Reponse · 200 OK
{
  "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/232 destinations — share your dual-passport score on https://visa.orizn.app"
}
Codes d'erreur
400paramètres manquants ou passeports identiques404l'un des passeports est absent de l'index500erreur interne
Activité en direct

Flux SSE temps réel + instantané récent pour les widgets de preuve sociale.

GET/api/v1/visa/livepublic — sans authhors quota

Flux d'activité en direct (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.

exemple
curl "https://visa.orizn.app/api/v1/visa/live"
Reponse · 200 OK
// 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
noteCache-Control: no-store, Connection: keep-alive. Les clients EventSource se reconnectent automatiquement en cas de coupure réseau.
GET/api/v1/visa/live/recentpublic — sans authhors quota

Instantané d'activité récente

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.

exemple
curl "https://visa.orizn.app/api/v1/visa/live/recent"
Reponse · 200 OK
{
  "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 }
  ]
}
noteCache-Control: public, max-age=5.
Notifications push

Abonnez des appareils (iOS / Android) aux alertes de changement de politique.

POST/api/v1/visa/devicesclé api · tout planhors quota

Enregistrer un appareil pour le 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).

corps de requête
{
  "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
  }
}
exemple
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 } }'
Reponse · 200 OK
{ "device_id": 42 }
Codes d'erreur
400device_token manquant, passport_iso3 invalide, ou wishlist_iso3 n'est pas un tableau401clé API manquante403clé API invalide500erreur interne
noteUpsert sur device_token — re-poster le même token met à jour l'abonnement existant.
PATCH/api/v1/visa/devices/{id}clé api · tout planhors quota

Mettre à jour un abonnement d'appareil

Update any subset of the subscription fields — passport, wishlist, locale, timezone, premium flag, preferences. At least one field is required.

corps de requête
{
  "wishlist_iso3": ["THA", "JPN", "BRA", "PRT"],
  "preferences": { "only_wishlist": true }
}
exemple
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 } }'
Reponse · 200 OK
{ "updated": true, "device_id": 42 }
Codes d'erreur
400body invalide, aucun champ à mettre à jour, passport ou wishlist malformé401clé API manquante403clé API invalide404appareil introuvable
DELETE/api/v1/visa/devices/{id}clé api · tout planhors quota

Désabonner un appareil

Permanently delete the device subscription. Use this when the user revokes notifications or uninstalls.

exemple
curl -X DELETE "https://visa.orizn.app/api/v1/visa/devices/42" \
  -H "x-api-key: YOUR_API_KEY"
Reponse · 200 OK
{ "deleted": true, "device_id": 42 }
Codes d'erreur
401clé API manquante403clé API invalide404appareil introuvable
Webhooks

Livraison serveur à serveur des changements de politique. Payloads signés HMAC.

GET/api/v1/visa/webhooksclé api · business+hors quota

Lister vos webhooks

Returns every webhook subscription owned by your account, including its filters, last trigger time, and failure counter.

exemple
curl "https://visa.orizn.app/api/v1/visa/webhooks" \
  -H "x-api-key: YOUR_API_KEY"
Reponse · 200 OK
{
  "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
    }
  ]
}
Codes d'erreur
401clé API manquante403clé invalide ou plan inférieur à Business
POST/api/v1/visa/webhooksclé api · business+hors quota

Créer 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.

corps de requête
{
  "url": "https://your-app.com/orizn-hook",
  "passport_filter": ["FRA"],
  "destination_filter": ["THA", "JPN"]
}
exemple
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"] }'
Reponse · 200 OK
{
  "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."
}
Codes d'erreur
400body ou url invalide401clé API manquante403clé invalide ou plan inférieur à Business
noteRenvoie 201 Created.
DELETE/api/v1/visa/webhooks?id={id}clé api · business+hors quota

Supprimer un webhook

Permanently delete a webhook subscription you own.

Parametres
ParametreTypeRequisDescription
idintOuiId du webhook, obtenu via list/create.
exemple
curl -X DELETE "https://visa.orizn.app/api/v1/visa/webhooks?id=42?id=42" \
  -H "x-api-key: YOUR_API_KEY"
Reponse · 200 OK
{ "deleted": true, "id": 17 }
Codes d'erreur
400paramètre id manquant401clé API manquante403clé invalide ou plan inférieur à Business404webhook introuvable ou ne vous appartenant pas
Clés d'équipe

Des sous-clés par environnement qui partagent le quota du compte propriétaire.

GET/api/v1/visa/team-keysclé api · business+hors quota

Lister les clés d'équipe

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.

exemple
curl "https://visa.orizn.app/api/v1/visa/team-keys" \
  -H "x-api-key: YOUR_API_KEY"
Reponse · 200 OK
{
  "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"
    }
  ]
}
Codes d'erreur
401clé API manquante403clé invalide ou plan inférieur à Business
POST/api/v1/visa/team-keysclé api · business+hors quota

Créer une clé d'équipe

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.

corps de requête
{ "name": "ci-staging" }
exemple
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" }'
Reponse · 200 OK
{
  "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."
}
Codes d'erreur
400name manquant/vide401clé API manquante403clé invalide ou plan inférieur à Business
noteRenvoie 201 Created.
DELETE/api/v1/visa/team-keys?id={id}clé api · business+hors quota

Désactiver une clé d'équipe

Soft delete — flips active to false. Existing requests with the key start returning 403 immediately.

Parametres
ParametreTypeRequisDescription
idintOuiId de la clé d'équipe.
exemple
curl -X DELETE "https://visa.orizn.app/api/v1/visa/team-keys?id=42?id=42" \
  -H "x-api-key: YOUR_API_KEY"
Reponse · 200 OK
{ "deactivated": true, "team_key": { "id": 7, "name": "ci-staging" } }
Codes d'erreur
400paramètre id manquant401clé API manquante403clé invalide ou plan inférieur à Business404introuvable, ne vous appartenant pas, ou déjà inactive
Compte & facturation

Inscription en self-service, rotation de clé et facturation hébergée par Stripe.

POST/api/v1/visa/registerpublic — sans authhors quota

Inscription (obtenez une clé API gratuite)

Self-serve signup. Returns a free-plan API key (50 req/month). Idempotent on email — re-registering returns the existing key instead of creating a duplicate.

corps de requête
{ "name": "Ada Lovelace", "email": "[email protected]" }
exemple
curl -X POST "https://visa.orizn.app/api/v1/visa/register" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Ada Lovelace", "email": "[email protected]" }'
Reponse · 200 OK
{
  "api_key": "orizn_visa_a06113a2e4f0...",
  "plan": "free",
  "message": "API key created successfully."
}
Codes d'erreur
400JSON invalide, name/email manquant, email malformé500erreur base de données
GET/api/v1/visa/auth/ensure-keycookie de sessionhors quota

Récupérer la clé API de l'utilisateur connecté

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.

exemple
curl "https://visa.orizn.app/api/v1/visa/auth/ensure-key" \
  --cookie "orizn_token=YOUR_SESSION"
Reponse · 200 OK
{
  "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"
  }
}
Codes d'erreur
400identité utilisateur introuvable depuis la session401cookie orizn_token manquant ou invalide
POST/api/v1/visa/auth/regenerate-keycookie de sessionhors quota

Régénérer la clé 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.

exemple
curl -X POST "https://visa.orizn.app/api/v1/visa/auth/regenerate-key" \
  --cookie "orizn_token=YOUR_SESSION" \
  -H "Content-Type: application/json" \
  -d '{}'
Reponse · 200 OK
{
  "api_key": "orizn_visa_b71224...",
  "message": "API key rotated. Update your clients."
}
Codes d'erreur
400identité utilisateur introuvable401session manquante ou invalide404aucun compte API actif pour cet utilisateur
POST/api/v1/visa/stripe/checkoutcookie de sessionhors quota

Démarrer un checkout de plan payant

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.

corps de requête
{
  "plan": "pro",
  "billing": "monthly",
  "affiliate_id": "aff_4f2a91c8"
}
exemple
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" }'
Reponse · 200 OK
{ "url": "https://checkout.stripe.com/c/pay/cs_test_..." }
Codes d'erreur
400plan invalide, annuel non supporté pour ce plan, email introuvable401session manquante ou invalide
noteplan : l'un de hobby, starter, pro, business. billing : monthly | annual.
POST/api/v1/visa/stripe/portalcookie de sessionhors quota

Ouvrir le portail de facturation Stripe

Returns a one-time URL into Stripe's customer portal — invoices, payment method, plan changes, cancellation.

exemple
curl -X POST "https://visa.orizn.app/api/v1/visa/stripe/portal" \
  --cookie "orizn_token=YOUR_SESSION" \
  -H "Content-Type: application/json" \
  -d '{}'
Reponse · 200 OK
{ "url": "https://billing.stripe.com/p/session/..." }
Codes d'erreur
400email introuvable401session manquante ou invalide404pas de client Stripe (probablement encore sur le plan gratuit)
Programme d'affiliation

Gagnez 15 % de commission sur les abonnements parrainés — web + iOS.

POST/api/v1/visa/affiliate/registerpublic — sans authhors quota

Devenir affilié

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.

corps de requête
{
  "name": "Ada Lovelace",
  "email": "[email protected]",
  "website": "https://travelblog.example",
  "payment_method": "paypal",
  "payment_info": "[email protected]",
  "source": "web"
}
exemple
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" }'
Reponse · 200 OK
{
  "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."
}
Codes d'erreur
400JSON invalide, champs manquants, email/website/payment_method malformé409course sur contrainte d'unicité — réessayez500erreur interne
notewebsite peut être la chaîne littérale ios-app pour les affiliés app-store. Renvoie 201 à la première inscription, 200 si l'affilié existe déjà.
POST/api/v1/visa/affiliate/track-clickpublic — sans authhors quota

Enregistrer un clic d'affiliation

Increment the click counter for an affiliate_id. Fire-and-forget from your landing pages and ad creatives.

corps de requête
{ "affiliate_id": "aff_4f2a91c8" }
exemple
curl -X POST "https://visa.orizn.app/api/v1/visa/affiliate/track-click" \
  -H "Content-Type: application/json" \
  -d '{ "affiliate_id": "aff_4f2a91c8" }'
Reponse · 200 OK
{ "ok": true }
Codes d'erreur
400affiliate_id manquant ou malformé404affilié introuvable ou inactif500erreur interne
POST/api/v1/visa/affiliate/apply-referralpublic — sans authhors quota

Attacher un parrainage à un utilisateur

Bind an existing user to a referrer after sign-up — typical use is the iOS app collecting a referral code post-registration. Sets referred_by; the referrer earns 15% on the user's future subscriptions.

corps de requête
{ "referral_code": "aff_4f2a91c8", "email": "[email protected]" }
exemple
curl -X POST "https://visa.orizn.app/api/v1/visa/affiliate/apply-referral" \
  -H "Content-Type: application/json" \
  -d '{ "referral_code": "aff_4f2a91c8", "email": "[email protected]" }'
Reponse · 200 OK
{
  "ok": true,
  "message": "Referral applied successfully. The referrer will earn 15% commission on your future subscriptions.",
  "referred_by": "aff_4f2a91c8"
}
Codes d'erreur
400champs manquants, mauvais format, ou tentative d'auto-parrainage404code de parrainage invalide/inactif, ou utilisateur non inscrit500erreur interne
GET/api/v1/visa/affiliate/statspublic — sans authhors quota

Données du dashboard affilié

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.

Parametres
ParametreTypeRequisDescription
affiliate_idstringNonRequis sans cookie de session. Format aff_<8 hex>.
emailstringNonRequis sans cookie de session. Doit correspondre à l'email de l'affilié.
exemple
curl "https://visa.orizn.app/api/v1/visa/affiliate/stats"
Reponse · 200 OK
{
  "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"
  }
}
Codes d'erreur
401ni cookie ni requête affiliate_id + email404affilié introuvable500erreur interne
ce que renvoie l'endpoint /visa

30 points de données

Chaque réponse GET /api/v1/visa comporte jusqu'à 32 champs. Les champs sans objet pour une paire donnée valent null, un tableau vide, ou sont omis — fiez-vous à la forme, pas à la présence.

Cœur (toujours présent)
champTypeDescription
passportstringISO 3166-1 alpha-3 (ex. FRA)
destinationstringISO 3166-1 alpha-3 (ex. JPN)
requirementenumvisa_free | visa_required | e_visa | visa_on_arrival | eta | no_admission
visa_free_daysint | nullNombre de jours autorises sans visa (null si visa requis)
visa_requiredbooltrue si une formalité visa quelconque est nécessaire
descriptionstringRésumé lisible et localisé
documents_requiredstring[]Documents à apporter/soumettre
processstring[]Processus de demande étape par étape
tipsstring[]Conseils de voyage
country_infoobjectDevise, langue, fuseau horaire, capitale
verifiedboolIndique si ces donnees ont ete verifiees aupres de sources officielles
Intelligence étendue (optionnelle, seulement si pertinente)
champTypece que ça vous apprend
transit_visaobjectRègles de visa de transit et heures de transit libre dans les grands hubs
passport_validity_monthsintValidité minimale du passeport exigée à l'entrée
visa_feeobjectCoût du visa entrée simple et entrées multiples, avec devise
processing_daysobjectDélais de traitement standard / express / urgent
photo_specsobjectDimensions photo (mm), fond, règles lunettes & couvre-chef
vaccinations_requiredstring[]Vaccins obligatoires (ex. yellow_fever)
insurance_requiredobjectCouverture minimale d'assurance voyage exigée
dual_nationality_warningsstring[]Avertissements pour les binationaux (ex. service militaire)
stamp_warningsstring[]Tampons de passeport pouvant bloquer l'entrée
minor_rulesobjectRègles pour les voyageurs de moins de 18 ans
overstay_penaltyobjectAmende par jour, durée d'interdiction, responsabilité pénale
entry_by_modeobjectDurées de séjour différentes selon l'arrivée air / terre / mer
remote_work_visaobjectDisponibilité du visa nomade numérique, durée, frais
extension_rulesobjectSi le séjour peut être prolongé, jours max, frais, où
reciprocity_historyobject[]Historique des changements de politique entre les deux pays
safetyobjectNiveau d'avis aux voyageurs (1–4) avec source et dernière mise à jour
best_apply_periodstringFenêtre de demande recommandée
health_requirementsobjectTest COVID, preuve vaccinale, quarantaine, dépistages
embassy.your_embassy_at_destinationobjectL'ambassade de votre pays à destination — urgences
embassy.visa_application_embassyobjectL'ambassade de la destination dans votre pays — où faire la demande
ce que chaque palier débloque

Matrice des plans

fonctionnalitéGratuithobby $9starter $49pro $199business $699
Requêtes mensuelles5010,00030,000250,0001,000,000
Débit en rafale (req/s)102550100200
/visa, /visa/check✓ (en uniquement)✓ (15 langues)✓ (15 langues)
/visa — champs étendusstubsstubstout sauf remote-work, reciprocityles 32les 32
/visa/changes (policy feed — rebuilding)
/visa/bulk (toutes les destinations)
/visa/group (multi-passeports)
Abonnements push des appareils
Webhooks (serveur à serveur)
Sous-clés d'équipe
Score, compare, stats, live✓ (public)

Les plans Enterprise ajoutent requêtes illimitées, débits sur mesure, déploiement on-prem, IP dédiées et un SLA de 99,95 %. Parlez-nous.

quotas, rafale, réinitialisation

5. Limites

Les quotas se réinitialisent le 1er de chaque mois calendaire (UTC). Seuls les quatre endpoints comptés — /visa, /visa/check, /visa/bulk et /visa/group — incrémentent votre compteur mensuel. Score, stats, live, changes, appareils, webhooks et gestion des clés d'équipe sont gratuits vis-à-vis de votre quota.

PlanPrixLimite mensuelleDebitpoints clés
Gratuit$05010 req/s/check + /visa (en uniquement) + endpoints publics
Starter49 $/mois30,00050 req/s+ all 15 languages, /changes, extended fields
Pro199 $/mois250,000100 req/s+ /bulk, remote-work-visa, historique de réciprocité
Business699 $/mois1,000,000200 req/s+ webhooks, sous-clés d'équipe, SLA
EnterpriseSur mesureIllimiteSur mesure+ on-prem, IP dédiée, SLA 99,95 %

Au-delà de votre quota vous recevez un HTTP 429 avec X-RateLimit-Reset indiquant quand la prochaine fenêtre s'ouvre.

de l'observabilité sans parser le body

Headers de réponse

headervaleur
X-RateLimit-LimitQuota mensuel de votre plan/visa, /visa/check, /visa/bulk
X-RateLimit-RemainingAppels restants ce mois-ci/visa, /visa/check, /visa/bulk
X-RateLimit-ResetTimestamp ISO de la prochaine réinitialisation (envoyé uniquement sur 429)/visa, /visa/check, /visa/bulk
X-PlanVotre plan actuel (free, starter, pro, business, enterprise)/visa, /visa/check, /visa/bulk
X-Powered-Byorizn Visa API v1Tous les endpoints authentifiés
X-Orizn-UpgradeURL de la page d'upgrade (uniquement sur free)/visa, /visa/check
VaryAccept (posé quand la négociation Markdown est disponible)/visa, /visa/check
Cache-Controlpublic, max-age=3600 (stats) · max-age=5 (live/recent) · no-store (live)Endpoints publics
des échecs prévisibles

6. Codes d'erreur

Les erreurs renvoient un body JSON à la forme stable. Utilisez le statut HTTP pour le routage, le body pour le diagnostic, et les pastilles d'erreur par endpoint ci-dessus pour savoir exactement quel code 4xx vient de quelle condition.

CodeSignificationcause typique
400Requete invalideParamètre manquant ou malformé — code non ISO3, lang non supportée, body invalide
401Non autoriseHeader x-api-key / paramètre api_key / cookie orizn_token manquant
403InterditClé invalide ou inactive, ou votre plan n'inclut pas cet endpoint
404Non trouvePas de données pour cette paire / ressource ne vous appartenant pas
409ConflitCourse sur contrainte d'unicité (inscription affilié) — réessai sans risque
429Trop de requetesQuota mensuel ou débit en rafale dépassé
500Erreur interneProblème backend transitoire — réessayez avec backoff exponentiel
{
  "error": "Monthly limit exceeded (50 req/month on free plan). Upgrade at https://visa.orizn.app",
  "plan": "free",
  "limit": 50,
  "upgrade_url": "https://visa.orizn.app/visa-api/pricing"
}
15 langues, un paramètre de requête

7. Langues supportees

Passez lang en paramètre de requête (ou dans le body JSON pour les POST). Défaut : en. Les langues autres que l'anglais demandent le plan Starter ou supérieur.

enEnglish
frFrançais
esEspañol
ptPortuguês
deDeutsch
itItaliano
ja日本語
ko한국어
zh中文
ruРусский
arالعربية
hiहिन्दी
thไทย
viTiếng Việt
tlTagalog
typés, avec retries, batteries incluses

SDK officiels

Des wrappers écrits à la main — entièrement typés, avec retries, backoff sur rate-limit et un type d'erreur structuré. Les mêmes 30 points de données partout.

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
quoi de neuf

8. Changelog

v1.1Mai 2026

30 points de données + référence complète des endpoints

  • 21 nouveaux champs optionnels sur /visa : transit, frais, specs photo, vaccinations, assurance, ambassades, sécurité, pénalités de dépassement de séjour, historique de réciprocité, visa remote-work, règles d'extension.
  • Nouvel outil MCP check_transit_visa ; descriptions enrichies pour que les agents choisissent le bon outil.
  • La page docs couvre désormais les 28 endpoints publics — données visa, scoring, live, appareils, webhooks, clés d'équipe, compte, affiliation.
  • SDK v1.1: [email protected] (npm), orizn==1.1.0 (PyPI), [email protected].
  • Rétrocompatible — les anciens clients continuent de fonctionner, les nouveaux champs sont additifs.
v1.0Mai 2026

Lancement

  • 40 027 paires passeport/destination couvertes
  • 15 langues supportees (en, fr, es, pt, de, it, ja, ko, zh, ru, ar, hi, th, vi, tl)
  • Endpoints : check, visa, bulk, changes, stats, register
  • Plans : Gratuit (50/mois), Starter (49$), Pro (199$), Business (699$), Enterprise
  • Dashboard avec analytics d'utilisation, facturation et documentation interactive