# US Visa Interview Wait Time Monitor (`nerolabs/us-visa-wait-time-monitor`) Actor

Returns US visa interview wait times per embassy or consulate from the State Department table (B1/B2, F/M/J, H/L/O/P/Q, crew), and in monitor mode reports changes in days. Inputs: post names, visa category, monitorMode. Agent-ready: pay per event (x402 and MCP), no charge for unmatched posts.

- **URL**: https://apify.com/nerolabs/us-visa-wait-time-monitor.md
- **Developed by:** [Adam Pearce](https://apify.com/nerolabs) (community)
- **Categories:** Travel, Automation, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 post looked ups

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## US Visa Interview Wait Time Monitor

Waiting for a US visa interview and wondering whether the queue at your embassy has moved? Or able to interview in more than one country and want to know which consulate is fastest right now? This Actor reads the US State Department's official **Global Visa Wait Times** table and gives you, per embassy or consulate:

- the **next available interview appointment** for B1/B2 visitor visas, student/exchange visas (F, M, J), petition-based work visas (H, L, O, P, Q) and crew/transit visas (C, D, C1/D),
- the **B1/B2 average wait last month**, where the State Department publishes it,
- in **monitor mode**, only what actually moved since your last check, with the number of days shorter or longer,
- and, when you check several posts at once, a **ranking of which post has the shortest wait** per category.

The source is the State Department's own page, which it updates monthly. The numbers are theirs, not an estimate: this Actor just makes them scheduleable, comparable and diffable.

### Who this is for

- **Applicants** waiting months for a B1/B2, F-1 or H-1B interview who want to know the moment their post's wait drops, without refreshing the page every day.
- **Third-country applicants** who can interview at more than one consulate (for example anyone in Canada choosing between Toronto, Vancouver and Ottawa, or someone who can travel) and want the fastest option, ranked.
- **Immigration attorneys, travel agencies, universities and HR teams** tracking wait times across many posts for many clients, every month, on a schedule.
- **AI agents and workflows** that need current US visa wait times as structured JSON.

### What you get

One row per post you asked for, for example:

| post | b1b2 | b1b2Days | student | petition | crew | changeSummary |
|---|---|---|---|---|---|---|
| London | 1.5 Months | 45 | < 0.5 Month | < 0.5 Month | < 0.5 Month | B1/B2 visitor, next available appointment: shorter by about 45 days (3 Months to 1.5 Months). |
| Toronto | 24 Months | 720 | 1 Month | 1 Month | < 0.5 Month | No change since the last check. |

Every wait is given both as the State Department's published text (`"1.5 Months"`, `"< 0.5 Month"`, `"NA"`) and as a day count using the page's own stated rule (a month is 30 days, a half month 15, weekends and holidays included). `"< 0.5 Month"` is flagged `isUpperBound: true` because the real wait is under that figure, not equal to it. `"NA"` means the State Department did not publish a figure for that post and category; the Actor never invents a number.

When you check more than one post, a final `comparison` row (never charged) ranks them shortest-wait first for each category and names the shortest for each, e.g. `"shortestWait": { "b1b2": "London (1.5 Months)" }`.

### Monitor mode

Turn on **Monitor mode** and schedule the Actor. The first run records a baseline for each post. Every later run compares against it and reports only real movement:

- `B1/B2 visitor, next available appointment: shorter by about 135 days (6 Months to 1.5 Months).`
- `Petition-based (H, L, O, P, Q), next available appointment: longer by about 15 days (< 0.5 Month to 1 Month).`
- `Student/exchange (F, M, J), next available appointment: now published at 2 Months (was NA).`
- `The State Department republished the table (2026-07-15 to 2026-08-17) with no change for this post.`

The State Department updates the table monthly. A **weekly** schedule catches each update within days while keeping the cost near zero; a daily schedule works but mostly confirms no change. Use a different **Watchlist ID** per client list so baselines don't overwrite each other.

### Input

| Field | What to enter |
|---|---|
| **Embassies / consulates** | City names as on the table, one per line: `London`, `Toronto`, `Mexico City`, `New Delhi`, `Lagos`. Unambiguous partial names work (`Juarez` finds Ciudad Juarez). An ambiguous name is reported with the candidates rather than guessed. |
| **Visa category** | `all` (default), `b1b2`, `student`, `petition` or `crew`. Controls which columns are reported and, in monitor mode, which are watched. |
| **Monitor mode** | Off = one-time lookup. On = report only what moved since the last run. |
| **Watchlist ID** | Keeps separate monitor histories apart. |
| **Reference mode** | Turn on `listAvailablePosts` to get all 240+ post names and the category keys. Never charged. |

### Pricing

Pay per event, no subscription:

- **$0.02 per post looked up** (one-time lookup mode)
- **$0.05 per change detected** (monitor mode, only when something actually moved)
- **$0.005 per unchanged post confirmed** (monitor mode)
- a small run-start fee that covers opening a real browser session to the State Department site ($0.04 per run at the default memory)

Posts that don't match anything, ambiguous names, the comparison row and reference mode are never charged.

**What it actually costs in practice:** watching 10 posts on a weekly schedule is 4 runs a month: about $0.16 in run fees, $0.20 for 40 unchanged checks, and $0.05 for each real change (a typical month sees a handful). Call it under $1 a month to watch 10 consulates. A one-off comparison of 5 posts is $0.14.

### FAQ

**Is this the same as the appointment booking system?** No. This reads the State Department's public, published wait-times table. It does not log in to, scrape or interact with the appointment scheduling system (usvisa-info / ais), and it cannot book, move or find individual appointment slots. For that, use the official scheduling site for your country.

**Why does the B1/B2 average column say NA for most posts?** The State Department only publishes last month's average wait for B1/B2 when the next available appointment is more than three months away. NA there means "not published", not "no wait".

**How accurate is the day count?** It is a direct conversion of the State Department's own published figure using the rule stated on their page (30 days per month, 15 per half month). It is not a prediction. The State Department itself notes new appointments are released regularly, so real applicants can often move earlier than the published figure.

**Why does it need a browser and a proxy?** travel.state.gov sits behind a bot challenge. The Actor uses a real browser through a US residential proxy, which is why there is a small run-start fee. One session reads the whole table, so checking 30 posts costs almost the same as checking one.

**Is this legal?** The data is a US Government work, in the public domain (17 U.S.C. §105). The State Department's own copyright notice states Consular Affairs information "may be copied and distributed without permission." No State Department seal or trademark is used.

**Found a post name that doesn't match, or a value that looks wrong?** Open an issue on the Actor page. Unrecognised values are reported verbatim with no day count rather than guessed, so you will always see exactly what the State Department published.

If this saved you from refreshing the State Department page by hand, a review on the Actor page genuinely helps other applicants find it.

# Actor input Schema

## `posts` (type: `array`):

City names as they appear on the State Department table, one per line, for example London, Toronto, Mexico City, New Delhi, Lagos. Partial names work when unambiguous ("Juarez" finds Ciudad Juarez). Turn on listAvailablePosts below to see all 240+ valid names.

## `category` (type: `string`):

Which wait-time columns to report and (in monitor mode) watch. all = every column. b1b2 = visitor visas (next available appointment plus last month's average wait where published). student = F, M, J. petition = H, L, O, P, Q. crew = C, D, C1/D.

## `monitorMode` (type: `boolean`):

Compare each post against the values seen on the previous run and report only real movement: a wait getting shorter or longer (with the number of days, using the State Department's own 30-days-per-month rule), or a category appearing or disappearing. The State Department updates the table monthly, so a weekly schedule catches each update promptly. The first run records a baseline.

## `watchlistId` (type: `string`):

Keeps separate monitor histories apart. Use a different ID per client list or per schedule so their baselines don't overwrite each other.

## `listAvailablePosts` (type: `boolean`):

Turn this on to get the full list of embassy/consulate names on the table and the category keys. This mode is never charged. Use it first if you're not sure how a city is spelled on the table.

## `proxyConfiguration` (type: `object`):

travel.state.gov sits behind Cloudflare. The default (US residential) is the setting confirmed to work; change it only if you have a reason to.

## Actor input object example

```json
{
  "posts": [
    "London",
    "Toronto",
    "Mexico City"
  ],
  "category": "all",
  "monitorMode": false,
  "watchlistId": "default",
  "listAvailablePosts": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "posts": [
        "London",
        "Toronto",
        "Mexico City"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nerolabs/us-visa-wait-time-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "posts": [
        "London",
        "Toronto",
        "Mexico City",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("nerolabs/us-visa-wait-time-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "posts": [
    "London",
    "Toronto",
    "Mexico City"
  ]
}' |
apify call nerolabs/us-visa-wait-time-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nerolabs/us-visa-wait-time-monitor"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/CX5Iyly520YWNvQuc/builds/j8t2ERz5C68X9ckKA/openapi.json
