State APItravel.state.gov ↗
Get current U.S. National Visa Center processing timeframes via API: case file creation, case review, and Public Inquiry Form response times, updated weekly.
What is the State API?
The travel.state.gov NVC Timeframes API exposes 1 endpoint — get_nvc_timeframes — returning 3 structured processing-time objects from the U.S. Department of State National Visa Center. Each object includes an as_of_date, an activity_date indicating which cases are currently being processed, and a full_text field matching the official published wording. Data reflects the State Department's weekly updates to the NVC Timeframes page.
No input parameters required.
curl -X GET 'https://api.parse.bot/scraper/98633553-78ac-4f4b-83e9-e03dc403acca/get_nvc_timeframes' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace travel-state-gov-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""
NVC Timeframes API Client
Get your API key from: https://parse.bot/settings
"""
import os
import requests
from datetime import datetime
from typing import Optional
class ParseClient:
"""Client for interacting with the Parse API."""
def __init__(self, api_key: Optional[str] = None):
"""
Initialize the Parse API client.
Args:
api_key: API key for authentication. Defaults to PARSE_API_KEY env var.
"""
self.base_url = "https://api.parse.bot"
self.scraper_id = "98633553-78ac-4f4b-83e9-e03dc403acca"
self.api_key = api_key or os.getenv("PARSE_API_KEY")
if not self.api_key:
raise ValueError(
"API key not provided. Set PARSE_API_KEY environment variable or pass api_key parameter."
)
def _call(self, endpoint: str, method: str = "POST", **params) -> dict:
"""
Make a request to the Parse API.
Args:
endpoint: The endpoint name (e.g., 'get_nvc_timeframes')
method: HTTP method ('GET' or 'POST')
**params: Additional parameters for the request
Returns:
Response JSON as dictionary
Raises:
requests.RequestException: If the API request fails
"""
url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
try:
if method.upper() == "GET":
response = requests.get(url, headers=headers, params=params)
elif method.upper() == "POST":
payload = params if params else {}
response = requests.post(url, headers=headers, json=payload)
else:
raise ValueError(f"Unsupported HTTP method: {method}")
response.raise_for_status()
return response.json()
except requests.RequestException as e:
print(f"API Error: {e}")
raise
def get_nvc_timeframes(self) -> dict:
"""
Retrieve current NVC processing timeframes.
Returns:
Dictionary containing:
- case_file_creation_time: Case creation processing timeframe
- case_review_time: Case review processing timeframe
- public_inquiry_form_response_time: Inquiry response timeframe
Each timeframe contains:
- full_text: Human-readable description
- as_of_date: Date the information was last updated
- activity_date: Date of cases/documents currently being processed
"""
return self._call("get_nvc_timeframes", method="GET")
def parse_date(date_str: str) -> datetime:
"""
Parse date string in format 'D-Mon-YY' to datetime object.
Args:
date_str: Date string (e.g., '8-Jun-26')
Returns:
datetime object
"""
return datetime.strptime(date_str, "%d-%b-%y")
def calculate_processing_days(as_of_date: str, activity_date: str) -> int:
"""
Calculate the number of days between as_of_date and activity_date.
Args:
as_of_date: Current date (when data was updated)
activity_date: Date of cases being processed
Returns:
Number of days difference
"""
as_of = parse_date(as_of_date)
activity = parse_date(activity_date)
return (as_of - activity).days
def main():
"""Main workflow demonstrating practical usage of NVC Timeframes API."""
# Initialize client
client = ParseClient()
print("=" * 70)
print("NVC VISA CENTER - PROCESSING TIMEFRAMES MONITOR")
print("=" * 70)
# Fetch current NVC timeframes
print("\nFetching current NVC processing timeframes...")
timeframes = client.get_nvc_timeframes()
# Extract individual timeframe data
case_creation = timeframes.get("case_file_creation_time", {})
case_review = timeframes.get("case_review_time", {})
inquiry_response = timeframes.get("public_inquiry_form_response_time", {})
# Process and display case file creation timeframe
print("\n" + "-" * 70)
print("📋 CASE FILE CREATION TIMEFRAME")
print("-" * 70)
print(f"Status: {case_creation.get('full_text', 'N/A')}")
as_of_date = case_creation.get("as_of_date")
activity_date = case_creation.get("activity_date")
if as_of_date and activity_date:
days = calculate_processing_days(as_of_date, activity_date)
print(f"Last Updated: {as_of_date}")
print(f"Currently Processing Cases From: {activity_date}")
print(f"Approximate Processing Time: {days} days")
# Process and display case review timeframe
print("\n" + "-" * 70)
print("📊 CASE REVIEW TIMEFRAME")
print("-" * 70)
print(f"Status: {case_review.get('full_text', 'N/A')}")
as_of_date = case_review.get("as_of_date")
activity_date = case_review.get("activity_date")
if as_of_date and activity_date:
days = calculate_processing_days(as_of_date, activity_date)
print(f"Last Updated: {as_of_date}")
print(f"Currently Processing Documents From: {activity_date}")
print(f"Approximate Processing Time: {days} days")
# Process and display inquiry response timeframe
print("\n" + "-" * 70)
print("❓ PUBLIC INQUIRY FORM RESPONSE TIMEFRAME")
print("-" * 70)
print(f"Status: {inquiry_response.get('full_text', 'N/A')}")
as_of_date = inquiry_response.get("as_of_date")
activity_date = inquiry_response.get("activity_date")
if as_of_date and activity_date:
days = calculate_processing_days(as_of_date, activity_date)
print(f"Last Updated: {as_of_date}")
print(f"Currently Responding to Inquiries From: {activity_date}")
print(f"Approximate Response Time: {days} days")
# Summary analysis
print("\n" + "-" * 70)
print("📈 PROCESSING TIME SUMMARY")
print("-" * 70)
timeframes_list = [
("Case Creation", case_creation),
("Case Review", case_review),
("Inquiry Response", inquiry_response),
]
max_days = 0
slowest_process = ""
for process_name, process_data in timeframes_list:
as_of = process_data.get("as_of_date")
activity = process_data.get("activity_date")
if as_of and activity:
days = calculate_processing_days(as_of, activity)
print(f" • {process_name}: {days} days")
if days > max_days:
max_days = days
slowest_process = process_name
if slowest_process:
print(f"\n⚠️ Slowest Process: {slowest_process} (~{max_days} days)")
print("✅ Data updated weekly by the U.S. Department of State")
print("\n" + "=" * 70)
if __name__ == "__main__":
main()Returns the current NVC processing timeframes: case file creation time, case review time, and Public Inquiry Form response time. Each timeframe includes the 'as of' date and the date of cases/documents/inquiries currently being processed. Data is updated weekly by the State Department.
No input parameters required.
{
"type": "object",
"fields": {
"case_review_time": "object containing full_text, as_of_date, and activity_date for case review",
"case_file_creation_time": "object containing full_text, as_of_date, and activity_date for case creation",
"public_inquiry_form_response_time": "object containing full_text, as_of_date, and activity_date for inquiry responses"
},
"sample": {
"case_review_time": {
"full_text": "Current case review time: As of 8-Jun-26, we are reviewing documents submitted to us on 11-May-26.",
"as_of_date": "8-Jun-26",
"activity_date": "11-May-26"
},
"case_file_creation_time": {
"full_text": "Current case creation time frame: As of 8-Jun-26, we are working on cases that were received from USCIS on 18-May-26.",
"as_of_date": "8-Jun-26",
"activity_date": "18-May-26"
},
"public_inquiry_form_response_time": {
"full_text": "Current Public Inquiry Form response time: As of 8-Jun-26, we are responding to inquiries received on 31-May-26.",
"as_of_date": "8-Jun-26",
"activity_date": "31-May-26"
}
}
}About the State API
What the API Returns
The single get_nvc_timeframes endpoint takes no input parameters and returns three objects: case_file_creation_time, case_review_time, and public_inquiry_form_response_time. Each object carries the same three fields: full_text (the verbatim text published by the NVC), as_of_date (when that timeframe was last updated), and activity_date (the date of cases or inquiries currently being worked).
Field Details
case_file_creation_time reflects how long the NVC is currently taking to open a new immigrant visa case after it receives an approved petition. case_review_time shows the date of documents currently under review for completeness. public_inquiry_form_response_time shows how old submitted inquiries are when the NVC responds to them. The activity_date in each object is the most actionable field — it tells you concretely how far behind the NVC is at the moment of the weekly update.
Update Cadence and Coverage
The State Department updates the NVC Timeframes page weekly. Because this API reflects that published data, the maximum freshness of any response is approximately seven days. The endpoint covers only NVC processing stages; it does not include post-NVC steps such as consular interview scheduling or visa issuance timelines at individual embassies.
The State API is a managed, monitored endpoint for travel.state.gov — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when travel.state.gov changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official travel.state.gov API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Alert immigration attorneys when
activity_datefor case review falls behind a client's submission date - Track weekly changes in
case_file_creation_timeto build a historical backlog trend chart - Notify petitioners automatically when
public_inquiry_form_response_timeexceeds a threshold they set - Display current NVC wait times inside an immigration case management dashboard
- Compare
as_of_datevalues across weeks to detect when the State Department skips or delays its update - Feed NVC timeframe data into a visa timeline estimator alongside priority date bulletin data
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does the U.S. Department of State offer an official developer API for NVC timeframe data?+
What exactly does the `activity_date` field represent versus `as_of_date`?+
as_of_date is the date the NVC last updated that particular timeframe — i.e., when the published figure was current. activity_date is the date of the cases, documents, or inquiries the NVC is actively processing at that moment. For most practical uses, activity_date is the figure to compare against a petitioner's own submission date.How fresh is the data returned by `get_nvc_timeframes`?+
as_of_date field in each object tells you exactly when the last update occurred, so you can determine the age of the data at the time of your API call. There is no intra-week refresh.