Look up a federal tax-refund's current stage at IRS Where's My Refund, given SSN/ITIN, filing status, refund amount, and tax year. Returns the stage (Return Received / Refund Approved / Refund Sent), deposit/mail date when surfaced, Tax Topic codes (152/151/203), and the canonical status-page URL. Read-only and PII-sensitive — never logs or persists the TIN.
Works with
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versioncheck-refund-statusExecute the skills CLI command in your project's root directory to begin installation:
Fetches check-refund-status from irs.gov/check-refund-status-89r6ko 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-refund-status. Access via /check-refund-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-refund-status |
| title | IRS Where's My Refund Status Check |
| description | >- Look up a federal tax-refund's current stage at IRS Where's My Refund, given SSN/ITIN, filing status, refund amount, and tax year. Returns the stage (Return Received / Refund Approved / Refund Sent), deposit/mail date when surfaced, Tax Topic codes (152/151/203), and the canonical status-page URL. Read-only and PII-sensitive — never logs or persists the TIN. |
| website | irs.gov |
| category | tax |
| tags | - tax - irs - refund - government - pii-sensitive - akamai - read-only |
| source | 'browserbase: agent-runtime 2026-05-18' |
| updated | '2026-05-18' |
| recommended_method | browser |
| alternative_methods | [] |
| verified | true |
| proxies | true |
Given a taxpayer's Social Security Number or ITIN, filing status, and exact whole-dollar refund amount, query the IRS "Where's My Refund?" tool at https://sa.www4.irs.gov/wmr/ and return the current refund stage (Return Received / Refund Approved / Refund Sent), the estimated or confirmed deposit/mail date when surfaced, any IRS message codes shown (Tax Topic 152, 151, 203, math-error codes), and the canonical status-page URL the user can visit themselves.
Read-only. This skill handles deeply sensitive PII (the TIN is a US national identifier). The caller MUST pass inputs over a secure channel; the skill MUST NOT log, persist, screenshot-as-text, or transcribe the SSN/ITIN anywhere — including trace files, browser-trace exports, sandbox stdout, or screenshot OCR layers. Treat the SSN like a session-only memory write that gets zeroed when the task ends.
sa.www4.irs.gov/wmar/), or stimulus/EIP lookups.The recommended method is browser driving the public form. The internal API endpoint exists at POST https://sa.www4.irs.gov/api/taxpayers/accounts/wmr/1.0/refundSummary and the request shape is fully known (see "Direct API path — confirmed-fragile, do not use" below), but cookieless POSTs from a non-warmed session are gated by Akamai bot management and require a per-session X-IRS-Session-Id shared-secret hashed from a client-side randomUUID. The browser flow is shorter, more honest, and surfaces all of the same response data through window.__REDUX_STORE__.refundResult.refundSummary.
sid=$(browse cloud sessions create --keep-alive --verified --proxies | jq -r .id)
export BROWSE_SESSION="$sid"
Both --verified (Verified browsers: residential-class fingerprint, plausible WebGL/canvas/UA stack) and --proxies (residential IP) are mandatory. A bare or datacenter-proxy session gets either an Akamai 403 / Access-Denied HTML page, or the SPA loads but the first form-submit POST returns HTTP 400/401 because the Akamai sensor fingerprint is missing.
browse open "https://sa.www4.irs.gov/wmr/" --remote
browse wait load --remote
browse wait timeout 3000 --remote # SPA mounts + Akamai sensor script POSTs
browse snapshot --remote
The HTML shell is a 1.6-KB Create-React-App template; all form markup is injected by /wmr/assets/index-kzMzosx0.js (about 572 KB, may version-rotate — confirm by reading the <script type="module" src="/wmr/assets/index-*.js"> tag). The first 1–3 seconds after load are the Akamai sensor handshake; if you submit before it completes, the next POST returns 400.
The form is a two-step wizard. Step 1 collects all four inputs and is submitted by the button-continueToStepTwo button (DOM id — also visible as a snapshot ref labelled "Continue" / "Submit"). Fields:
| Input | Form field name | Format |
|---|---|---|
| SSN or ITIN | ssnInput | 9 digits, dashes allowed; client regex /^[0-9-_*]{0,21}$/ (it accepts asterisks because the input masks digits as you type) |
| Tax year | taxYearInput2 (radio group) | 4-digit year, typically <current_year-1> or <current_year-2> |
| Filing status | filingStatusInput (radio group) | enum below |
| Refund amount | refundAmountInput | Whole dollars; client regex /^[$]?[\d,]{0,13}$/; on blur the SPA strips the $ and commas |
Filing-status enum — this is the IRS-internal mapping read off the React bundle. Note that value 4 is intentionally absent (legacy 1040 line):
| User-facing label | API value |
|---|---|
| Single | "1" |
| Married Filing Jointly | "2" |
| Married Filing Separately | "3" |
| Head of Household | "5" |
| Qualifying Surviving Spouse (a.k.a. Qualifying Widow(er)) | "6" |
If the caller hands you the user-facing label, map it to the API value before filling. If they hand you a digit "4", reject with a validation error — the form will silently coerce to a wrong status if you let it through.
browse fill input[name=ssnInput] "$SSN" --remote # never echo $SSN to stdout
browse click "radio: 2024" --remote # tax year (verify against snapshot)
browse click "radio: Single" --remote # filing status label
browse fill input[name=refundAmountInput] "1234" --remote
browse click "button-continueToStepTwo" --remote
browse wait timeout 4000 --remote # API round-trip + nav
On a successful submit the SPA navigates to /wmr/results (or /wmr/es/results for Spanish). The result data is fully present in the Redux store. Read it once, do not poll:
RESULT_JSON=$(browse eval --remote 'JSON.stringify(window.__REDUX_STORE__?.getState?.().refundResult ?? null)')
If window.__REDUX_STORE__ is undefined (the SPA does not always expose its store on window), fall back to reading the DOM:
browse snapshot --remote
# Look for these texts in the rendered page:
# "Return Received" (stage 1)
# "Refund Approved" (stage 2)
# "Refund Sent" (stage 3)
# and any of:
# "Tax Topic 152" (normal processing, generic information)
# "Tax Topic 151" (under review — refund may be reduced or held)
# "Tax Topic 203" (offset for past-due federal/state debts, child support, etc.)
# "Mailing date:" / "Direct deposit date:" / "Sent by mail:" / a "Get refund status" date string
The Redux store keys (extracted from the bundle):
refundResult: {
sharedSecretToken: "<random-uuid>", // session-only — DROP, never log
sessionId: "<hashed token>", // session-only — DROP, never log
httpStatusCode: "",
refundSummary: {
tin: "<echoed back, last 4 only on display>",
filingStatus: "1"|"2"|"3"|"5"|"6",
refundAmount: "1234",
adjustedRefundAmount: "", // populated if IRS recalculated
mailingDate: "", // populated when stage = Refund Sent
statusCode: "C..."|"H..."|"R..."|...,
conditionCode: "",
mathErrorCodes: null,
balanceDueAmount: "",
taxPeriod: "<YYYY>12", // taxYear + "12"
totalBfsOffsetAmount: "",
noticeDate: "",
dueByDate: "",
traceSummary: null | { status: "F3911_ELIGIBLE"|"EXISTING_CLAIM_LT_45_DAYS"|"EXISTING_CLAIM_GTE_45_DAYS"|"CHKCL_ELIGIBLE"|"INELIGIBLE", ... }
}
}
Map refundSummary.statusCode.charAt(0) to the user-facing stage:
| First char | Stage |
|---|---|
C | Refund Approved (Check issued / Credit posted) |
H | Refund Held (Tax Topic 151 / 203 territory — flag for review) |
R | Refund Sent / Return Received family — disambiguate via the SPA's translation file txp__wmr__<statusCode> or simply read the page banner |
| any other | Use the page-rendered banner text directly; do not guess |
https://sa.www4.irs.gov/wmr/refund_status is the canonical landing-page URL the user should visit. The results URL (/wmr/results) is not linkable by a third party — it only renders after a fresh form submission inside the same browser session. Return the landing-page URL to the caller along with the data; instruct them they will need to re-enter the same three inputs to see the live page themselves.
browse cloud sessions update "$sid" --status REQUEST_RELEASE
# Wipe in-memory copies of the SSN before returning
unset SSN
Do not leave the session in RUNNING state; the next agent run might reuse it and inherit the Akamai cookies tied to this lookup.
For completeness, the API call the SPA makes under the hood is:
POST https://sa.www4.irs.gov/api/taxpayers/accounts/wmr/1.0/refundSummary
Content-Type: application/json
X-IRS-Session-Id: <sha-256(crypto.randomUUID() + Date.now() + tin) — see ty() in the bundle>
X-IRS-System-Id: WMR-UI
{"tin":"123456789","taxYear":"2024","filingStatus":"1","refundAmount":"1234"}
Direct GET to the same path returns 405 Method Not Allowed with an <Exception> body that reveals the API-gateway service name and operation — confirming the path is correct. POSTing the body directly from a cookieless client returns either 400 (Akamai sensor headers absent) or, sporadically, a 401. Reproducing the SPA's full Akamai-blessed POST out-of-band is brittle and worth no engineering effort over the browser flow. Don't waste time on it.
***-**-1234). Do not commit a test SSN to a repo. Do not ship a screenshot showing the form fields populated.Access Denied HTML on first navigation, or — if the shell loads — a 400/401 on the first form submit. Verified: the response shell ships an Akamai sensor script (bazadebezolkohpepadr=, /akam/13/..., the obfuscated /1ytYJb/... script) and three Akamai cookies (_abck, bm_sz, ak_bmsc).4 is not used. The IRS 1040 codes are 1, 2, 3, 5, 6 with 4 absent. If the caller passes a 4, refuse rather than coerce.taxYearInput2) with two or three years (typically last filing year and the prior one). If the caller didn't supply a year, ask before submitting — IRS responds 204 ("no records match") if you guess wrong, and the no-match is indistinguishable from a wrong-SSN error.refundSummary means the (tin, filingStatus, refundAmount, taxYear) tuple did not match IRS records. The SPA renders "We cannot provide any information about your refund." This is the same UI as a real-but-not-yet-posted return; surface both possibilities to the caller. Do not retry — repeated 204s on the same IP trigger Akamai rate-limiting (429)./wmr/results with an empty refundSummary and shows a generic "system error, try again later" banner. Do not treat as auth failure./wmr/results only renders after an in-session form submission. The link you give back to the user is the landing page /wmr/refund_status (or /wmr/); they will need to re-enter the three inputs to see it themselves.r6 = ["C", "H", "R"]. These are the first letters of refundSummary.statusCode for "normal" stage banners. Any other prefix (B*, D*, K*, WB, WM, WP, WS, TPNC, etc.) maps to a specific message-code translation file txp__wmr__<code>; read the page banner text rather than trying to decode the prefix yourself.refundSummary. Topic 152 (normal processing — appears for ~99% of in-progress refunds), Topic 151 (return under further review — possible reduction or audit), Topic 203 (refund offset for child support, federal student loans, state income tax, etc.) appear as anchor links in the banner. Extract them by grepping the page text after the stage banner; don't assume they are in the API JSON (they aren't).refundSummary.traceSummary.status is F3911_ELIGIBLE or CHKCL_ELIGIBLE, the SPA renders a "Start a refund trace" button that navigates to /wmr/claim. Do not click it — that initiates an IRS workflow. Just surface the eligibility flag to the caller as trace_eligible: true./wmr/assets/index-kzMzosx0.js is the bundle hash as of 2026-05-18; it rotates on every IRS deploy. Read the <script type="module" src> from the shell at runtime rather than hardcoding. The field names, enum values, and API path inside the bundle have been stable across IRS releases for the past 2 years./wmr/es/refund_status and /wmr/es/results are the Spanish-language equivalents. Field names and API shape are identical. Only switch domains/paths if the caller explicitly requests Spanish output; the IRS lookup itself is language-agnostic./api/taxpayers/accounts/wmr/1.0/refundSummary is confirmed gated by Akamai sensor headers — even with the correct X-IRS-Session-Id token, a cookieless POST is rejected as 400 or 401. Page-warm a real browser session, fill the form, let the SPA make the request inside its sensor-blessed context. The browser path is the supported path.browse cloud fetch of the WMR landing page. The skill was not driven end-to-end against a real refund because (a) doing so requires a live SSN, which is unacceptable PII to inject into an eval harness, and (b) the generator sandbox does not have outbound network access to connect.usw2.browserbase.com (CDP/WebSocket required for browse open --remote). The first agent to invoke this skill on a real user query and a CDP-reachable sandbox should verify the snapshot ref names in Workflow step 3, then promote from candidate to launched.Five distinct outcome shapes. All shapes echo back the last 4 digits of the TIN only, never the full TIN.
// Stage 1 — Return Received
{
"success": true,
"stage": "Return Received",
"stage_code": "R...",
"tin_last4": "1234",
"filing_status": "Single",
"refund_amount_dollars": 1234,
"tax_year": "2024",
"estimated_completion": null,
"tax_topics": ["152"],
"math_error_codes": [],
"trace_eligible": false,
"status_page_url": "https://sa.www4.irs.gov/wmr/refund_status"
}
// Stage 2 — Refund Approved (deposit date surfaced)
{
"success": true,
"stage": "Refund Approved",
"stage_code": "C...",
"tin_last4": "1234",
"filing_status": "Married Filing Jointly",
"refund_amount_dollars": 4567,
"adjusted_refund_amount_dollars": null,
"tax_year": "2024",
"expected_deposit_date": "2026-05-22",
"delivery_method": "direct_deposit",
"tax_topics": ["152"],
"trace_eligible": false,
"status_page_url": "https://sa.www4.irs.gov/wmr/refund_status"
}
// Stage 3 — Refund Sent
{
"success": true,
"stage": "Refund Sent",
"stage_code": "C...",
"tin_last4": "1234",
"filing_status": "Head of Household",
"refund_amount_dollars": 2890,
"adjusted_refund_amount_dollars": 2890,
"tax_year": "2024",
"sent_date": "2026-05-15",
"delivery_method": "mailed_check",
"tax_topics": ["152"],
"trace_eligible": true,
"trace_status": "F3911_ELIGIBLE",
"status_page_url": "https://sa.www4.irs.gov/wmr/refund_status"
}
// Held / under review — Topic 151 or 203 surfaced
{
"success": true,
"stage": "Refund Held",
"stage_code": "H...",
"tin_last4": "1234",
"filing_status": "Single",
"refund_amount_dollars": 3210,
"adjusted_refund_amount_dollars": 1850,
"tax_year": "2024",
"tax_topics": ["151", "203"],
"balance_due_amount_dollars": 0,
"total_bfs_offset_amount_dollars": 1360,
"math_error_codes": ["08", "12"],
"notice_date": "2026-05-10",
"trace_eligible": false,
"status_page_url": "https://sa.www4.irs.gov/wmr/refund_status"
}
// Soft-fail outcomes — no-match, rate-limited, system error, anti-bot block
{
"success": false,
"reason": "no_match" | "rate_limited" | "system_error" | "anti_bot_block" | "validation_error",
"http_status": 204 | 400 | 401 | 422 | 429 | 500 | 503 | null,
"user_message": "We cannot provide any information about your refund. Verify the SSN, filing status, refund amount, and tax year, then try again later.",
"tin_last4": "1234",
"status_page_url": "https://sa.www4.irs.gov/wmr/refund_status"
}
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.
apps.ilsos.gov/business-search-wk944z
cis.scc.virginia.gov/business-search-pg5zpn
amazon.com/search-products-5170mf
bizfileonline.sos.ca.gov/find-california-business-izbvm2
apartments.com/search-rentals-33icwz
dior.com/find-all-products-qxm8lj
Keeps context tight: check-refund-status is the kind of skill you can hand to a new teammate without a long onboarding doc.
Registry listing for check-refund-status matched our evaluation — installs cleanly and behaves as described in the markdown.
check-refund-status has been reliable in day-to-day use. Documentation quality is above average for community skills.
Useful defaults in check-refund-status — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
Solid pick for teams standardizing on skills: check-refund-status is focused, and the summary matches what you get after install.
I recommend check-refund-status for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
check-refund-status reduced setup friction for our internal harness; good balance of opinion and flexibility.
check-refund-status reduced setup friction for our internal harness; good balance of opinion and flexibility.
We added check-refund-status from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
Keeps context tight: check-refund-status is the kind of skill you can hand to a new teammate without a long onboarding doc.
showing 1-10 of 73