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.

Receipt number format: All USCIS receipt numbers consist of 3 uppercase letters followed by 10 digits. Examples: WAC2190123456, MSC2190012345, EAC2390054321.
Download Postman Collection

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()
Keep your API key secret. Do not expose it in client-side code, public repositories, or URLs. If you suspect your key has been compromised, revoke it immediately from the dashboard and generate a new one.

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.

PlanRequests/SecondDaily LimitTracked Cases
Free1505
Starter250050
Pro52,000500
Enterprise1010,0005,000

Error Handling

The API uses standard HTTP status codes. All error responses include a JSON body with an error field describing the problem.

CodeMeaningDescription
200OKRequest succeeded
201CreatedResource created successfully
400Bad RequestMissing or invalid parameters
401UnauthorizedInvalid or missing API key
403ForbiddenPlan limit reached or feature not available
404Not FoundResource does not exist
405Method Not AllowedWrong HTTP method (e.g., GET instead of POST)
409ConflictResource already exists (e.g., duplicate email)
422Unprocessable EntityValidation error (e.g., invalid receipt format)
429Too Many RequestsDaily query limit reached
500Server ErrorInternal server error
502Bad GatewayUSCIS upstream service unavailable
Error Response Example
{
  "error": "Daily query limit reached",
  "limit": 50
}

Query Single Case

GET ?action=case&receipt={receipt_number}

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

NameTypeRequiredDescription
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'])
Response
{
  "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

GET ?action=cases&receipts={receipt1},{receipt2},...

Query the status of multiple USCIS cases in a single request. Maximum of 20 receipt numbers per request.

Parameters

NameTypeRequiredDescription
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'])
Response
{
  "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

POST ?action=track

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

NameTypeRequiredDescription
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()
Response (201 Created)
{
  "success": true,
  "id": 42,
  "receipt": "MSC2190012345",
  "status": "Case Was Approved",
  "form": "I-485"
}

List Tracked Cases

GET ?action=tracked

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']
Response
{
  "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

GET ?action=history&id={tracked_case_id}

Retrieve the full status change history for a tracked case. Each entry represents a detected status change with a timestamp.

Parameters

NameTypeRequiredDescription
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']
Response
{
  "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

POST ?action=untrack

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

NameTypeRequiredDescription
id integer Optional* The tracked case ID
receipt string Optional* The receipt number to untrack
* Either 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}
)
Response
{
  "success": true,
  "removed": 1
}

Refresh All Cases

POST ?action=refresh

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.

Each case checked counts toward your daily query limit. If the limit is reached mid-refresh, remaining cases are skipped.

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'])}")
Response
{
  "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

GET ?action=me

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']
Response
{
  "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

GET ?action=usage

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()
Response
{
  "success": true,
  "plan": "pro",
  "today": {
    "queries": 147,
    "daily_limit": 2000
  },
  "month": {
    "queries": 3842,
    "cost": 18.42
  }
}