Introduction
The Immigration API provides a simple, RESTful interface for querying USCIS (United States Citizenship and Immigration Services) case statuses in real time. Instead of manually checking the USCIS website or scraping HTML, you get structured JSON responses with parsed status data.
Use the API to build immigration case dashboards, client portals for law firms, case management tools, or any application that needs programmatic access to USCIS case data. Track cases over time and receive instant webhook notifications when statuses change.
WAC2190123456, MSC2190012345, EAC2390054321.
Authentication
All authenticated endpoints require an API key. Include your key in the Authorization header as a Bearer token. You can also use the X-API-Key header as an alternative.
# Using Authorization header (recommended) curl https://immigrationapi.com/api.php?action=me \ -H "Authorization: Bearer imm_live_abc123def456..." # Using X-API-Key header (alternative) curl https://immigrationapi.com/api.php?action=me \ -H "X-API-Key: imm_live_abc123def456..."
const response = await fetch( 'https://immigrationapi.com/api.php?action=me', { headers: { 'Authorization': 'Bearer imm_live_abc123def456...' } } ); const data = await response.json();
$ch = curl_init('https://immigrationapi.com/api.php?action=me'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer imm_live_abc123def456...' ] ]); $response = json_decode(curl_exec($ch), true); curl_close($ch);
import requests response = requests.get( 'https://immigrationapi.com/api.php', params={'action': 'me'}, headers={'Authorization': 'Bearer imm_live_abc123def456...'} ) data = response.json()
Base URL
All API requests should be made to the following base URL:
https://immigrationapi.com/api.php
Endpoints are accessed via the action query parameter. For example, to query a case status: ?action=case&receipt=WAC2190123456.
The API supports both GET and POST methods. JSON request bodies should be sent with Content-Type: application/json. CORS is enabled for all origins.
Rate Limits
Rate limits depend on your plan tier. If you exceed the limit, the API returns a 429 status code. The daily query counter resets at midnight UTC.
| Plan | Requests/Second | Daily Limit | Tracked Cases |
|---|---|---|---|
| Free | 1 | 50 | 5 |
| Starter | 2 | 500 | 50 |
| Pro | 5 | 2,000 | 500 |
| Enterprise | 10 | 10,000 | 5,000 |
Error Handling
The API uses standard HTTP status codes. All error responses include a JSON body with an error field describing the problem.
| Code | Meaning | Description |
|---|---|---|
| 200 | OK | Request succeeded |
| 201 | Created | Resource created successfully |
| 400 | Bad Request | Missing or invalid parameters |
| 401 | Unauthorized | Invalid or missing API key |
| 403 | Forbidden | Plan limit reached or feature not available |
| 404 | Not Found | Resource does not exist |
| 405 | Method Not Allowed | Wrong HTTP method (e.g., GET instead of POST) |
| 409 | Conflict | Resource already exists (e.g., duplicate email) |
| 422 | Unprocessable Entity | Validation error (e.g., invalid receipt format) |
| 429 | Too Many Requests | Daily query limit reached |
| 500 | Server Error | Internal server error |
| 502 | Bad Gateway | USCIS upstream service unavailable |
{
"error": "Daily query limit reached",
"limit": 50
}
Query Single Case
Query the current status of a single USCIS case by its receipt number. Returns the form type, current status text, and a detailed description.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| receipt | string | Required | USCIS receipt number (3 letters + 10 digits, e.g., WAC2190123456) |
Code Examples
curl "https://immigrationapi.com/api.php?action=case&receipt=WAC2190123456" \ -H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch( 'https://immigrationapi.com/api.php?action=case&receipt=WAC2190123456', { headers: { 'Authorization': `Bearer ${apiKey}` } } ); const data = await res.json(); console.log(data.case_status.current_case_status_text_en);
$ch = curl_init('https://immigrationapi.com/api.php?action=case&receipt=WAC2190123456'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey] ]); $data = json_decode(curl_exec($ch), true); curl_close($ch); echo $data['case_status']['current_case_status_text_en'];
import requests res = requests.get( 'https://immigrationapi.com/api.php', params={'action': 'case', 'receipt': 'WAC2190123456'}, headers={'Authorization': f'Bearer {api_key}'} ) data = res.json() print(data['case_status']['current_case_status_text_en'])
{
"success": true,
"case_status": {
"receiptNumber": "WAC2190123456",
"formType": "I-765",
"current_case_status_text_en": "Card Was Delivered To Me By The Post Office",
"current_case_status_desc_en": "On June 15, 2026, the Post Office delivered your new card for your Form I-765, Application for Employment Authorization, to the address we have on file. If you did not receive your card, please contact the Post Office to locate it."
}
}
Query Multiple Cases
Query the status of multiple USCIS cases in a single request. Maximum of 20 receipt numbers per request.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| receipts | string | Required | Comma-separated receipt numbers (max 20) |
Code Examples
curl "https://immigrationapi.com/api.php?action=cases&receipts=WAC2190123456,MSC2190012345,EAC2390054321" \ -H "Authorization: Bearer YOUR_API_KEY"
const receipts = ['WAC2190123456', 'MSC2190012345', 'EAC2390054321']; const res = await fetch( `https://immigrationapi.com/api.php?action=cases&receipts=${receipts.join(',')}`, { headers: { 'Authorization': `Bearer ${apiKey}` } } ); const data = await res.json(); data.results.forEach(r => console.log(r.receiptNumber, r.case_status?.current_case_status_text_en));
$receipts = 'WAC2190123456,MSC2190012345,EAC2390054321'; $ch = curl_init("https://immigrationapi.com/api.php?action=cases&receipts={$receipts}"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey] ]); $data = json_decode(curl_exec($ch), true); curl_close($ch); foreach ($data['results'] as $case) { echo $case['case_status']['current_case_status_text_en'] . "\n"; }
import requests res = requests.get( 'https://immigrationapi.com/api.php', params={'action': 'cases', 'receipts': 'WAC2190123456,MSC2190012345,EAC2390054321'}, headers={'Authorization': f'Bearer {api_key}'} ) for case in res.json()['results']: print(case['case_status']['current_case_status_text_en'])
{
"success": true,
"count": 3,
"results": [
{
"success": true,
"case_status": {
"receiptNumber": "WAC2190123456",
"formType": "I-765",
"current_case_status_text_en": "Card Was Delivered To Me By The Post Office",
"current_case_status_desc_en": "On June 15, 2026, the Post Office delivered your new card..."
}
},
{
"success": true,
"case_status": {
"receiptNumber": "MSC2190012345",
"formType": "I-485",
"current_case_status_text_en": "Case Was Approved",
"current_case_status_desc_en": "On July 5, 2026, we approved your Form I-485..."
}
},
{
"receiptNumber": "EAC2390054321",
"success": false,
"error": "Invalid format"
}
]
}
Track a Case
Start tracking a USCIS case. The API will fetch the current status immediately and store it. If the case is already being tracked, returns the existing tracking ID.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| receipt | string | Required | USCIS receipt number (3 letters + 10 digits) |
| label | string | Optional | A human-friendly label for this case (e.g., "John's EAD") |
Code Examples
curl -X POST "https://immigrationapi.com/api.php?action=track" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"receipt": "MSC2190012345", "label": "Maria - Green Card"}'
const res = await fetch('https://immigrationapi.com/api.php?action=track', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ receipt: 'MSC2190012345', label: 'Maria - Green Card' }) }); const data = await res.json();
$ch = curl_init('https://immigrationapi.com/api.php?action=track'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . $apiKey, 'Content-Type: application/json' ], CURLOPT_POSTFIELDS => json_encode([ 'receipt' => 'MSC2190012345', 'label' => 'Maria - Green Card' ]) ]); $data = json_decode(curl_exec($ch), true); curl_close($ch);
import requests res = requests.post( 'https://immigrationapi.com/api.php?action=track', headers={'Authorization': f'Bearer {api_key}'}, json={'receipt': 'MSC2190012345', 'label': 'Maria - Green Card'} ) data = res.json()
{
"success": true,
"id": 42,
"receipt": "MSC2190012345",
"status": "Case Was Approved",
"form": "I-485"
}
List Tracked Cases
Retrieve all cases you are currently tracking. Returns an array sorted by creation date (newest first).
Code Examples
curl "https://immigrationapi.com/api.php?action=tracked" \ -H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch('https://immigrationapi.com/api.php?action=tracked', { headers: { 'Authorization': `Bearer ${apiKey}` } }); const { cases } = await res.json();
$ch = curl_init('https://immigrationapi.com/api.php?action=tracked'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey] ]); $data = json_decode(curl_exec($ch), true); curl_close($ch);
import requests res = requests.get( 'https://immigrationapi.com/api.php', params={'action': 'tracked'}, headers={'Authorization': f'Bearer {api_key}'} ) cases = res.json()['cases']
{
"success": true,
"count": 2,
"cases": [
{
"id": 42,
"receipt_number": "MSC2190012345",
"label": "Maria - Green Card",
"form_type": "I-485",
"current_status": "Case Was Approved",
"status_description": "On July 5, 2026, we approved your Form I-485...",
"last_checked_at": "2026-07-08 14:30:00",
"created_at": "2026-06-01 09:15:00",
"notify_on_change": 1
},
{
"id": 38,
"receipt_number": "WAC2190123456",
"label": "John - EAD Card",
"form_type": "I-765",
"current_status": "New Card Is Being Produced",
"status_description": "On July 1, 2026, we ordered your new card...",
"last_checked_at": "2026-07-08 14:30:00",
"created_at": "2026-05-20 11:00:00",
"notify_on_change": 1
}
]
}
Case History
Retrieve the full status change history for a tracked case. Each entry represents a detected status change with a timestamp.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | integer | Required | The tracked case ID (returned when you track a case) |
Code Examples
curl "https://immigrationapi.com/api.php?action=history&id=42" \ -H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch('https://immigrationapi.com/api.php?action=history&id=42', { headers: { 'Authorization': `Bearer ${apiKey}` } }); const { history } = await res.json();
$ch = curl_init('https://immigrationapi.com/api.php?action=history&id=42'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey] ]); $data = json_decode(curl_exec($ch), true); curl_close($ch);
import requests res = requests.get( 'https://immigrationapi.com/api.php', params={'action': 'history', 'id': 42}, headers={'Authorization': f'Bearer {api_key}'} ) history = res.json()['history']
{
"success": true,
"history": [
{
"status_text": "Case Was Approved",
"status_description": "On July 5, 2026, we approved your Form I-485...",
"checked_at": "2026-07-05 09:45:00"
},
{
"status_text": "Interview Was Completed And My Case Must Be Reviewed",
"status_description": "On June 20, 2026, your interview for Form I-485 was completed...",
"checked_at": "2026-06-20 16:20:00"
},
{
"status_text": "Interview Was Scheduled",
"status_description": "On June 1, 2026, we scheduled an interview for Form I-485...",
"checked_at": "2026-06-01 09:15:00"
}
]
}
Remove from Tracking
Stop tracking a case. You can identify the case by its tracking ID or receipt number. The case history is preserved but the case will no longer be monitored.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | integer | Optional* | The tracked case ID |
| receipt | string | Optional* | The receipt number to untrack |
id or receipt must be provided. If both are provided, id takes precedence.Code Examples
# By tracking ID curl -X POST "https://immigrationapi.com/api.php?action=untrack" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"id": 42}' # By receipt number curl -X POST "https://immigrationapi.com/api.php?action=untrack" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"receipt": "MSC2190012345"}'
const res = await fetch('https://immigrationapi.com/api.php?action=untrack', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ id: 42 }) });
$ch = curl_init('https://immigrationapi.com/api.php?action=untrack'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Authorization: Bearer ' . $apiKey, 'Content-Type: application/json' ], CURLOPT_POSTFIELDS => json_encode(['id' => 42]) ]); $data = json_decode(curl_exec($ch), true); curl_close($ch);
import requests res = requests.post( 'https://immigrationapi.com/api.php?action=untrack', headers={'Authorization': f'Bearer {api_key}'}, json={'id': 42} )
{
"success": true,
"removed": 1
}
Refresh All Cases
Re-check the status of all your tracked cases. Each case is queried sequentially, and any status changes are recorded in the case history. If webhooks are configured, a case.status_changed event is fired for each change.
Code Examples
curl -X POST "https://immigrationapi.com/api.php?action=refresh" \ -H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch('https://immigrationapi.com/api.php?action=refresh', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}` } }); const data = await res.json(); console.log(`Checked: ${data.checked}, Changes: ${data.changes.length}`);
$ch = curl_init('https://immigrationapi.com/api.php?action=refresh'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey] ]); $data = json_decode(curl_exec($ch), true); curl_close($ch);
import requests res = requests.post( 'https://immigrationapi.com/api.php?action=refresh', headers={'Authorization': f'Bearer {api_key}'} ) data = res.json() print(f"Checked: {data['checked']}, Changes: {len(data['changes'])}")
{
"success": true,
"checked": 5,
"changes": [
{
"id": 42,
"receipt": "MSC2190012345",
"old": "Interview Was Completed And My Case Must Be Reviewed",
"new": "Case Was Approved"
}
]
}
Account Info
Retrieve your account details including plan information, limits, and usage counts.
Code Examples
curl "https://immigrationapi.com/api.php?action=me" \ -H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch('https://immigrationapi.com/api.php?action=me', { headers: { 'Authorization': `Bearer ${apiKey}` } }); const { account } = await res.json();
$ch = curl_init('https://immigrationapi.com/api.php?action=me'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey] ]); $data = json_decode(curl_exec($ch), true); curl_close($ch);
import requests res = requests.get( 'https://immigrationapi.com/api.php', params={'action': 'me'}, headers={'Authorization': f'Bearer {api_key}'} ) account = res.json()['account']
{
"success": true,
"account": {
"id": 15,
"name": "Maria Santos",
"email": "[email protected]",
"company": "Santos Immigration Law",
"created_at": "2026-01-15 10:00:00",
"plan": "pro",
"plan_name": "Pro",
"price_monthly": "99.00",
"queries_included": "2000",
"daily_limit": "2000",
"max_tracked_cases": "500",
"tracked_cases": 23
}
}
Usage Statistics
View your API usage statistics for today and the current billing month.
Code Examples
curl "https://immigrationapi.com/api.php?action=usage" \ -H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch('https://immigrationapi.com/api.php?action=usage', { headers: { 'Authorization': `Bearer ${apiKey}` } }); const data = await res.json();
$ch = curl_init('https://immigrationapi.com/api.php?action=usage'); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey] ]); $data = json_decode(curl_exec($ch), true); curl_close($ch);
import requests res = requests.get( 'https://immigrationapi.com/api.php', params={'action': 'usage'}, headers={'Authorization': f'Bearer {api_key}'} ) data = res.json()
{
"success": true,
"plan": "pro",
"today": {
"queries": 147,
"daily_limit": 2000
},
"month": {
"queries": 3842,
"cost": 18.42
}
}