✈
    TravelmodeDevelopers
    🔎/
    🔑Manage API Keys
    Feature
    🌦️Weather🛂Visa🧩Platform🧭Trips🤖Agent Runs📅Events

    Visa Intelligence API · v1

    📖Overview🧪API Reference (Try It)
    Guides
    🚀Getting Started🔐Authentication & Scopes⏱️Rate Limits🔔Changes & Webhooks⚠️Errors
    ⬇️Download openapi.yaml
    Developers / Visa / Errors

    Errors

    Last verified: 2026-06-20 (Task #389 — Visa Intelligence API docs).

    Every Visa Intelligence endpoint returns the same flat error envelope. There is no nested error object — error is the message and code is a stable machine token at the top level.

    {
      "error": "API key is missing required scope: visa:check",
      "code": "visa_api_key_insufficient_scope",
      "requiredScope": "visa:check"
    }
    
    FieldAlways presentNotes
    erroryesHuman-readable message. Don't match on this — it can change.
    codeyesStable token to branch on.
    detailsnoStructured context (varies by error).
    requiredScopenoThe scope you were missing (on scope 403s).
    retryAfternoSeconds to wait (on 429s).

    Treat code as the contract. The error text is for humans and may be reworded.

    Authentication & authorization

    CodeHTTPMeaning
    visa_api_key_unconfigured503No key presented and no key configured on this deployment.
    visa_api_key_invalid401Missing key, or the key doesn't resolve.
    visa_api_key_revoked401Key was revoked.
    visa_api_key_expired401Key's expires_at has passed.
    visa_api_customer_inactive403The tenant behind the key is disabled.
    visa_api_key_insufficient_scope403Key valid but missing the endpoint's scope (see requiredScope).

    Rate limiting

    CodeHTTPMeaning
    visa_api_rate_limited429Per-key hourly quota exceeded. retryAfter + Retry-After tell you when to retry. See rate-limits.md.

    Request validation

    CodeHTTPMeaning
    invalid_json400Body wasn't valid JSON.
    invalid_request400Body/params failed schema validation. details may carry field-level issues.
    visa_changes_bad_query400A /v1/visa/changes query parameter was malformed (e.g. an unknown severity).
    not_found404Resource not found, or not visible to your key (e.g. document download).

    Webhooks

    CodeHTTPMeaning
    visa_webhook_master_key_forbidden403The development master key tried to manage webhooks. Use a customer key.
    visa_webhook_url_blocked400The target URL isn't https:// or resolves to a private/loopback/disallowed address (details.reason).
    visa_webhook_not_found404No webhook with that id belongs to your tenant.

    Server

    CodeHTTPMeaning
    internal_error500Unhandled server error. Safe to retry with backoff.

    Handling errors in code

    Branch on code, not HTTP status alone or message text:

    const res = await fetch("https://api.travelmode.ai/v1/visa/check", {
      method: "POST",
      headers: {
        "X-Visa-Intel-Key": process.env.VISA_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ nationalityCode: "US", destinationCountryCode: "FR" }),
    });
    
    if (!res.ok) {
      const body = await res.json().catch(() => ({}));
      switch (body.code) {
        case "visa_api_rate_limited":
          // wait body.retryAfter seconds, then retry
          break;
        case "visa_api_key_insufficient_scope":
          throw new Error(`key needs scope: ${body.requiredScope}`);
        case "visa_api_key_invalid":
        case "visa_api_key_expired":
        case "visa_api_key_revoked":
          throw new Error("re-issue your API key");
        default:
          throw new Error(`visa API error ${res.status}: ${body.code ?? "unknown"}`);
      }
    }
    
    Previous
    ← Changes & Webhooks