Look up a USCIS case by 13-character receipt number (e.g. MSC2190012345, EAC2290098765, IOE0123456789) on the modern egov.uscis.gov Next.js portal and return status heading, next-step paragraph, form type (I-130/I-485/N-400/I-765/...), service-center code, last-updated date, and the canonical caseId URL. Read-only.
Works with
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versioncheck-case-statusExecute the skills CLI command in your project's root directory to begin installation:
Fetches check-case-status from uscis.gov/check-case-status-or94c8 and configures it for Cursor.
The CLI shows a list of agents. Use arrow keys and space to select Cursor:
Confirm successful installation by checking the skill directory location:
Restart Cursor to activate check-case-status. Access via /check-case-status in your agent's command palette.
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your environment. Always review source, verify the publisher, and test in isolation before production.
Submit your Claude Code skill and start earning
Automate repetitive workflows and reduce manual effort
Example
Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Learn new skills, understand complex topics, get expert guidance
Example
Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Enhance output quality through reviews, suggestions, and refinements
Example
Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
0
total installs
0
this week
0
upvotes
Run in your terminal
0
installs
0
this week
—
stars
| name | check-case-status |
| title | USCIS Case Status Lookup |
| description | >- Look up a USCIS case by 13-character receipt number (e.g. MSC2190012345, EAC2290098765, IOE0123456789) on the modern egov.uscis.gov Next.js portal and return status heading, next-step paragraph, form type (I-130/I-485/N-400/I-765/...), service-center code, last-updated date, and the canonical caseId URL. Read-only. |
| website | uscis.gov |
| category | government |
| tags | - uscis - immigration - case-status - read-only - cloudflare - Verified-required |
| source | 'browserbase: agent-runtime 2026-05-16' |
| updated | '2026-05-16' |
| recommended_method | browser |
| alternative_methods | - method: api rationale: >- No public unauthenticated USCIS case-status API exists. The internal `csol-api/case/{receipt}` endpoint that the SPA XHRs to is Cloudflare-blocked from any non-browser caller (verified 403 with --proxies). The legacy `casestatus/displayMyCaseStatus.do?appReceiptNum=...` action endpoint returns 404 — it was removed in the Next.js migration. USCIS does publish a developer Case Status API but it requires an authenticated developer account and is not suitable for ad-hoc lookups. - method: url-param rationale: >- `https://egov.uscis.gov/?caseId={receipt}&localeLang=en` is a valid bookmarkable URL but `caseId` is read CLIENT-SIDE by the SPA — a server-side GET returns the generic landing-form HTML with no status. Useful only for handing the resolved URL to a user. |
| verified | false |
| proxies | true |
Given a 13-character USCIS receipt number (e.g. MSC2190012345, EAC2290098765, IOE0123456789), look it up on the official Case Status Online portal and return: the current case-status heading, the next-step / status-description paragraph, the form type when surfaced (I-130, I-485, N-400, I-765, etc.), the service-center code (derived from the first three letters of the receipt — no scraping needed), the last-updated date when shown, and the canonical case-status URL. Read-only — never logs in, never updates anything, never subscribes.
MSC2190012345", "my receipt is EAC22...") and wants the current status..do flow or the modern Next.js portal (this skill always uses the modern path).The portal moved to a Next.js SPA at the root of egov.uscis.gov. The legacy /casestatus/landing.do form action endpoints (displayMyCaseStatus.do, mycasestatus.do) are either gone (404) or Cloudflare-blocked from any non-Verified client (403, Cf-Mitigated: challenge). Use the modern URL https://egov.uscis.gov/?localeLang=en and drive the SPA — there is no public unauthenticated JSON API, and the internal csol-api/case/{receipt} backing endpoint that the SPA XHRs to is Cloudflare-blocked from any out-of-browser caller (verified 403 from browse cloud fetch --proxies).
SID=$(browse cloud sessions create \
--keep-alive \
--verified \
--proxies \
--solve-captchas \
| jq -r '.id')
All three flags are required:
--verified — Cloudflare's managed-challenge engine fingerprints headless Chrome aggressively on this domain. Without it, the SPA shell may load but the moment its client-side JS XHRs to csol-api/..., Cf responds with a 403 challenge page that breaks the SPA state silently (the form just spins).--proxies — USCIS is unusually aggressive about data-center IP ranges. Bare AWS/GCP/Azure egress trips an immediate 403.--solve-captchas — if Cloudflare elevates to a Turnstile checkbox (rare on the SPA root, common when retrying after a failed lookup), Browserbase's solver handles it. If it elevates to hCaptcha (very rare; observed historically on the legacy .do flow), the same flag handles it.Format: ^([A-Z]{3})(\d{10})$ (exactly 13 chars)
Parse the prefix into service_center_code immediately — no scraping needed:
| Prefix | Service center |
|---|---|
EAC | Vermont Service Center (Eastern Adjudication Center, St. Albans VT) |
WAC | California Service Center (Western Adjudication Center, Laguna Niguel CA) |
LIN | Nebraska Service Center (Lincoln NE) |
SRC | Texas Service Center (Southern Regional Center, Dallas TX) |
MSC | National Benefits Center (Missouri Service Center, Lee's Summit MO) |
NBC | National Benefits Center (modern label) |
NSC | Nebraska Service Center (modern label, used alongside LIN) |
YSC | Potomac Service Center (Arlington VA) |
IOE | USCIS Electronic Immigration System (ELIS) — online-filed cases, no physical center |
The next two digits are the federal-fiscal-year (21 = FY2021, runs Oct 1 2020 → Sep 30 2021). The next three are a workday index. The last five are the case sequence. Surface these as opaque integers if needed; the FY mapping is the only one worth deriving without extra work.
Reject early any input that doesn't match ^[A-Z]{3}\d{10}$ — emit { "success": false, "error_reasoning": "Invalid receipt format" } without spinning up a session. The submit button on the SPA stays disabled for non-13-char input anyway, so a malformed receipt will hang the click step forever.
browse cloud browse --connect "$SID" open "https://egov.uscis.gov/?localeLang=en"
browse cloud browse --connect "$SID" wait load
browse cloud browse --connect "$SID" wait timeout 2500 # Next.js hydration; the input is in the DOM
# at load time but its React event handlers
# are not attached until hydration completes.
browse cloud browse --connect "$SID" snapshot
The snapshot must show a textbox ref labelled "Enter Another Receipt Number" with placeholder EAC1234567890, and a button ref labelled "Check Status". If the snapshot instead shows a "Just a moment…" body or only a Cloudflare challenge widget, the Verified+proxy combination is failing — see "Cloudflare wall" branch below.
browse cloud browse --connect "$SID" fill @receipt_number "$RECEIPT"
browse cloud browse --connect "$SID" wait timeout 500
browse cloud browse --connect "$SID" snapshot
After 13 valid characters land in the input, the initCaseSearch button transitions out of disabled. Verify the snapshot shows it un-disabled before clicking. If it's still disabled after typing, the React controlled-input event didn't fire — re-snapshot, get the latest ref, and re-fill (do not type per-character; the spinner-styling masking in the input's CSS class can drop keystrokes when typed too fast).
browse cloud browse --connect "$SID" click @initCaseSearch
browse cloud browse --connect "$SID" wait timeout 4000 # XHR to csol-api/case/{receipt} round-trip
browse cloud browse --connect "$SID" snapshot
The page does not navigate — the URL stays at https://egov.uscis.gov/?localeLang=en (it may pick up &caseId={receipt} via history.replaceState, but the path doesn't change). The <div class="caseStatus-container"> block re-renders in place. Don't poll the URL; poll the snapshot for either the status heading or a known not-found / error string.
h1/h2 in the container) and the paragraph beneath it. The paragraph almost always opens with "On <Month Day, Year>, we <verb> your Form <type>…" — regex that for form_type and last_updated:
form_type: /\bForm (I-\d{3}[A-Z]?|N-\d{3}|G-\d{3}|FOIA|EOIR-\d+)\b/last_updated: /^On ([A-Z][a-z]+ \d{1,2}, \d{4}),/m{ success: true, status: "Not Found", status_description: <verbatim site text>, form_type: null, last_updated: null }. This is a legitimate outcome, not an error.{ success: false, error_reasoning: "USCIS-side validation rejected receipt" }.cf-mitigated body, or the result container never updates after 15s → emit { success: false, error_reasoning: "Cloudflare challenge — not bypassed" }. Recreate the session with --solve-captchas if not already set, optionally --region us-east-1 to swap the proxy egress region, and retry once. After two consecutive Cf walls, give up and surface the error — do not loop.case_status_url = "https://egov.uscis.gov/?caseId=" + receipt + "&localeLang=en"
This is the link a user can paste into a fresh browser to reproduce the lookup. The caseId param is read client-side by the SPA on load.
browse cloud sessions update "$SID" --status REQUEST_RELEASE
https://egov.uscis.gov/?localeLang=en, NOT /casestatus/landing.do. The legacy .do URL still exists but every request to it returns 403 Cf-Mitigated: challenge regardless of Verified/proxy flags — Cloudflare treats it as a deprecated honeypot path. The modern Next.js SPA at the root is the only working entry. Confirmed 2026-05-16: legacy landing.do 403 even with --proxies --allow-redirects; modern /?localeLang=en 200 from the same fetcher.Server: cloudflare, Cf-Mitigated: challenge, JS-challenge body with __cf_chl_tk + __cf_chl_rt_tk tokens. hCaptcha may appear as a Cloudflare escalation on retries — --solve-captchas covers both. Don't waste time looking for an hCaptcha sitekey at first contact.csol-api/case/{receipt} backing endpoint is Cf-blocked. Verified 403 from browse cloud fetch --proxies --allow-redirects on both csol-api/case/{receipt} and csol-api/cases/{receipt} (plural). The 403 status (vs 404) confirms the path exists but is firewalled — do not try to hit it directly even with a Browserbase Function or curl. The SPA is the only way in. Also tested-blocked: egov/api/casestatus/{receipt} (403). Definitely-non-existent: casestatus/displayMyCaseStatus.do?appReceiptNum=... (404), api/casestatus?receiptNumber=... (404). Don't probe further.?caseId=... is read client-side only. GETting https://egov.uscis.gov/?caseId=MSC2190012345&localeLang=en returns the same generic landing-form HTML as /?localeLang=en with no server-rendered status. The SPA reads caseId from window.location.search after hydration and then fires the XHR. Server-side scraping by URL won't work.disabled until exactly 13 chars are typed. The receipt input has maxLength="13". The button's enabled state is React-controlled — fill will fire the input event correctly; per-character type can race the spinner-styling masking class. Always snapshot-verify the button is un-disabled before clicking, otherwise the click is a no-op./?localeLang=en (possibly with &caseId= appended via history.replaceState). Wait for the .caseStatus-container DOM mutation, not a page load. ~3–5s wall after click is typical; budget 8s before declaring failure.form_type and last_updated. USCIS does NOT expose form type as a structured field on the result page — it's embedded in the paragraph: "On January 15, 2024, we received your Form I-130, Petition for Alien Relative…". Regex it out. Same for the date. If the form type isn't in the paragraph (rare — happens on some IOE ELIS cases that pre-date the form-name templating), emit form_type: null rather than guessing from the receipt prefix.IOE (ELIS) receipts may be longer than 13 characters in some historical exports (sometimes seen as 13–15). The modern SPA's input is hard-capped at maxLength="13", so anything longer will be truncated client-side. If your input is a 14- or 15-char IOE string, drop trailing chars to fit 13 only if the trailing chars are zeros; otherwise reject as malformed.--region us-east-1 / us-west-2 / eu-central-1 round-robin) and add a 5–8s sleep between receipts.__cf_bm, __cflb) that eventually trip the challenge engine when their fingerprint drifts from the proxy fingerprint.localeLang=es is the Spanish UI. Same SPA, same csol-api backing endpoint, but all status text comes back translated (e.g. "Caso fue recibido" instead of "Case Was Received"). Always pin localeLang=en for consistent text extraction.Five distinct outcome shapes.
// 1. Found — status retrieved successfully
{
"success": true,
"receipt_number": "MSC2190012345",
"service_center_code": "MSC",
"service_center_name": "National Benefits Center",
"status": "Case Was Received",
"status_description": "On January 15, 2024, we received your Form I-130, Petition for Alien Relative, Receipt Number MSC2190012345, and mailed you a receipt notice that describes how we will process your case. Please follow any instructions in the notice. If you do not receive your receipt notice by February 15, 2024, please call Customer Service at 1-800-375-5283.",
"form_type": "I-130",
"last_updated": "January 15, 2024",
"case_status_url": "https://egov.uscis.gov/?caseId=MSC2190012345&localeLang=en",
"error_reasoning": null
}
// 2. Not found — receipt is well-formed but USCIS has no record
{
"success": true,
"receipt_number": "EAC9999999999",
"service_center_code": "EAC",
"service_center_name": "Vermont Service Center",
"status": "Not Found",
"status_description": "Validation Error: This receipt number does not exist in our database, or it has not been updated recently. Please re-check that you have entered the correct receipt number from your USCIS receipt notice and try again.",
"form_type": null,
"last_updated": null,
"case_status_url": "https://egov.uscis.gov/?caseId=EAC9999999999&localeLang=en",
"error_reasoning": null
}
// 3. Invalid format — rejected pre-session (no Browserbase cost)
{
"success": false,
"receipt_number": "ABC123",
"service_center_code": null,
"service_center_name": null,
"status": null,
"status_description": null,
"form_type": null,
"last_updated": null,
"case_status_url": null,
"error_reasoning": "Invalid receipt format — expected 3 uppercase letters followed by 10 digits (e.g. EAC1234567890)."
}
// 4. Cloudflare wall — anti-bot not bypassed even with Verified + proxies + captcha solver
{
"success": false,
"receipt_number": "MSC2190012345",
"service_center_code": "MSC",
"service_center_name": "National Benefits Center",
"status": null,
"status_description": null,
"form_type": null,
"last_updated": null,
"case_status_url": "https://egov.uscis.gov/?caseId=MSC2190012345&localeLang=en",
"error_reasoning": "Cloudflare challenge — not bypassed. Tried --verified + --proxies + --solve-captchas across 2 sessions; result container never populated within 15s of submit and snapshot showed Turnstile widget."
}
// 5. Approved / other state — same shape as #1, just different status heading + paragraph
{
"success": true,
"receipt_number": "LIN2090012345",
"service_center_code": "LIN",
"service_center_name": "Nebraska Service Center",
"status": "Case Was Approved",
"status_description": "On March 3, 2024, we approved your Form I-765, Application for Employment Authorization, Receipt Number LIN2090012345. We will mail your approval notice. Please follow any instructions in the notice. If you move, go to www.uscis.gov/addresschange to give us your new mailing address.",
"form_type": "I-765",
"last_updated": "March 3, 2024",
"case_status_url": "https://egov.uscis.gov/?caseId=LIN2090012345&localeLang=en",
"error_reasoning": null
}
Prerequisites
Time Estimate
15-45 minutes depending on use case complexity
Steps
Common Pitfalls
✓ Do
✗ Don't
💡 Pro Tips
✓ Use when
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid when
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
cis.scc.virginia.gov/business-search-pg5zpn
bizfileonline.sos.ca.gov/find-california-business-izbvm2
booking.com/search-hotels-asq6cc
aliexpress.com/search-product-p0h8a7
nav.com/get-smb-funding-2s1rpm
jezweb/claude-skills
Useful defaults in check-case-status — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
Solid pick for teams standardizing on skills: check-case-status is focused, and the summary matches what you get after install.
Registry listing for check-case-status matched our evaluation — installs cleanly and behaves as described in the markdown.
check-case-status has been reliable in day-to-day use. Documentation quality is above average for community skills.
We added check-case-status from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
check-case-status reduced setup friction for our internal harness; good balance of opinion and flexibility.
Keeps context tight: check-case-status is the kind of skill you can hand to a new teammate without a long onboarding doc.
Registry listing for check-case-status matched our evaluation — installs cleanly and behaves as described in the markdown.
check-case-status has been reliable in day-to-day use. Documentation quality is above average for community skills.
check-case-status is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
showing 1-10 of 69