NY UCS eCourts — Search Cases
Purpose
Given a case identifier, party name, or attorney name, search the New York State Unified Court System's public docket and return matching cases as structured JSON: index/docket number, court (type + county + part), caption, nature of action, filing & disposition dates, status, assigned judge, attorneys, parties, appearance/motion history, NYSCEF case ID + document-list URL (when present), and the canonical case-detail URL on iapps.courts.state.ny.us. Read-only — never files, pays, or submits anything.
The UCS docket sits across six distinct sub-systems, each with its own form schema, court ID space, and (in some cases) anti-bot regime. The skill must pick the right sub-system from the input shape and supplied filters before constructing a search.
When to Use
- "Look up index
123456/2024" (direct lookup, WebCivil Supreme or Local). - "Find every active case where {Party} is plaintiff in Bronx Supreme Court."
- "All cases filed by attorney {Name} between {date} and {date} in Kings County Civil Court."
- Direct lookup of a WebCriminal docket like
CR-12345-24NY. - Resolving a NYSCEF case ID into its document-list URL.
- Surfacing Surrogate's Court file proceedings by party name + date of death.
- Anywhere you'd otherwise hand-scrape
iapps.courts.state.ny.usorwebsurrogates.nycourts.gov.
Workflow
The skill is browser-driven end-to-end — the public docket APIs are not exposed, every submit form is hCaptcha-gated (data-sitekey="6c824b97-caeb-4a2a-9144-db4f1c9f86d0", the same key across WebCivil Supreme, WebCivil Local, and WebCriminal), and the result pages use ASP.NET WebForms postback patterns that depend on __VIEWSTATE / session cookies. There is no GET-query shortcut: GET /webcivil/FCASCaseInfo?index=12345/2024 returns HTTP 400 — case-detail URLs are reachable only through the search-results anchors. Use a Browserbase session with stealth + residential proxy (--verified --proxies) plus an hCaptcha solver hook.
1. Pick the right sub-system from the input
| Input shape | Sub-system | Entry URL |
|---|---|---|
Index N/YYYY + court type = Supreme/County Civil | WebCivil Supreme | /webcivil/FCASMain |
Index N/YYYY + court is City/County Civil/District/NYC Civil/Housing | WebCivil Local | /webcivilLocal/LCMain |
Docket like CR-12345-24NY or any criminal case # / summons # | WebCriminal | /webcrim_attorney/AttorneyWelcome |
Family docket (4-part: F-12345-24/01A) or family party search | WebFamily | /fcasfamily/main |
| NYSCEF doc-id, civil index needing eFile docs, or "what's on NYSCEF" | NYSCEF Case Search | /nyscef/CaseSearch |
| Surrogate's Court estate / probate by party name | WebSurrogate | https://websurrogates.nycourts.gov/ (separate React app on its own domain) |
If the prompt gives an explicit URL on iapps.courts.state.ny.us or websurrogates.nycourts.gov, use it as-is and skip selection logic.
2. Open a stealth + proxy session
sid=$(browse cloud sessions create --keep-alive --verified --proxies | jq -r .id)
export BROWSE_SESSION="$sid"
--verified --proxies is mandatory on every form submit — without proxies the hCaptcha challenge escalates to "always interactive" (no headless solver path) and the result pages rate-limit aggressively (observed: 30 req/min hard wall per IP).
3. Resolve enums for the chosen sub-system
Every sub-system has its own court-ID enum that does not match anywhere else. Fetch the search form once, parse its <select> options into a local map, and resolve human-readable inputs (county, court type) into numeric/coded IDs before submit:
- WebCivil Supreme
cboCourt— 164 entries, integer IDs. Bronx Supreme =124, Albany Supreme =2, Kings Supreme =47(county courts on the same enum, e.g. Albany County =1). One<select>mixes Supreme and County courts for the same county — pick the right one. - WebCivil Local
cboCourt— 124 entries, integer IDs. Bronx County Civil =42, Kings County Civil =21, New York County Civil = (look up), Queens County Civil = (look up), Richmond County Civil = (look up). Includes city courts (Albany City =143, Buffalo City =283), Nassau District (4 districts:989-992), Harlem Community Justice Center (1209), Redhook Community Justice Center. - WebCriminal
cboCounty— 178 entries, ORI codes in the formU:NY{countyCode}{courtCode}J(e.g.U:NY062033J= Bronx Criminal Court,U:NY062015J= Bronx Supreme Criminal Court) plusC:{numericId}for summons sub-units (Bronx Summons =C:62) and the all-courts sentinelC:0. - WebFamily
optionCourt— 119 entries, mostly small integers (Albany-Family =99, Bronx-Family =105) with two-segment names likeBronx-Supreme, Criminalfor combined courts (note: Bronx-Supreme, Criminal carries the unusual ID12810166). - NYSCEF
txtCounty— 62 county entries, different numeric IDs (Albany =1, Bronx =62, plus Appellate Division departments95–98and a UI/WC sentinel93). NYSCEF civil case-type values are tokenized server-side — each option'svalueis a per-request base64 token likesWHk4cQE2DWkSsfNFnJ1xw==forCV. Never hardcode these. Re-fetch the form, read the live<option value=...>for the case-type label you want, and replay the token on submit.
4. Construct the search
Each sub-system has its own POST endpoint and hidden-field discipline. Use these field maps verbatim — the forms are ASP.NET WebForms, so extra/wrong field names silently degrade to an empty result page.
WebCivil Supreme — POST /webcivil/FCASSearch
form action: FCASSearch (relative to /webcivil/)
hidden: hWhichPage = I | P | A | J # which search variant
hCourtType = Supreme # always literal "Supreme" on Supreme entry
hPageNumber = 1
hSearchKey = ""
inputs: txtIndex # for I (Index Search): "12345/2024"
txtPlaintiffLname # for P (Party Search) — actually the party-name input on Supreme; first-name not exposed
txtAttorneyLname # for A
txtJudgeLname # for J
cboCourt # numeric, see §3
cboYearOfFiling # year integer, or 0 for "any" (Supreme only — populated on I/A/J)
rdRepresents # Plaintiff | Defendant | OtherRoles | AllRoles (P search only)
rbStatus # open | all
rbFutureCases # Y | N
rbOutputFormat # HTML | PDF # always HTML for scraping
btnFindCase # "Find Case(s)" — submit (carries h-captcha challenge)
Index-number direct lookup: set hWhichPage=I, txtIndex=12345/2024, and cboCourt=<the court ID>. Year-of-filing is implied by the slash suffix.
WebCivil Local — POST /webcivilLocal/LCSearch
hidden: hWhichPage = I | P | A | J
hCourtType = Local
inputs: txtIndexNumber # integer sequence portion of the index
txtIndexYear # 4-digit year — Local splits the index into 2 inputs
txtPartyName # P: unified single-field party search
txtAttorneyLname # A
txtJudgeLname # J
cboCourt # numeric, see §3 (Local enum)
cboIndexCourtIndicator # 2-letter court abbreviation (AL=Albany City, BX=Bronx Civil,
# KN=Kings Civil, NY=New York Civil, QU=Queens Civil, RI=Richmond Civil,
# AM=Amsterdam, AU=Auburn, BA=Batavia, BE=Beacon, BI=Binghamton,
# BU=Buffalo, CA=Canandaigua, CO=Cohoes, … 81 codes total)
cboCaseType # blank or 2-letter category
cboCaseType1 # category dropdown: CC=Commercial Claims, CV=Civil, LT=Landlord/Tenant,
# MI=Misc., NC=Name Change, RE=Real Property, SC=Small Claims, TS=Transit Summons
cboYearOfFiling # year or 0
cboSort # result sort order
rdRepresents, rbStatus, rbFutureCases, rbOutputFormat
Index format quirk — WebCivil Local splits the index across txtIndexNumber (sequence) + txtIndexYear (4-digit). Supreme uses a single txtIndex field with 12345/2024 format. Do not cross-mix.
WebCriminal — POST /webcrim_attorney/CaseIdentifierSearch or DefendantSearch
CaseIdentifierSearch:
cboCounty # ORI code, see §3
txtCaseNumber # docket like "CR-12345-24NY" or NYSID
txtSummonsNumber # alternate identifier
rbOutputFormat # HTML | PDF
btnSubmit # h-captcha challenge
DefendantSearch:
cboCounty # ORI code
txtLastName, txtFirstName, txtCorpName # one of (last,first) or corpName populated
rbOutputFormat
btnSubmit
No filing-date range on WebCriminal. Attorney-name search is not exposed on the public criminal interface — use DefendantSearch only.
WebFamily — POST /fcasfamily/File or /fcasfamily/Attorney
File (docket / file-number search):
textDocket, textDocket1, textDocket2, textDocket3 # 4-part docket: prefix + sequence + check + year-suffix
# e.g. F-12345-24/01A → F | 12345 | 24 | 01A
textFileNumber # alternate when no docket
optionCourt # see §3 (Family enum, 119 options)
optionSortOrder
Submit # btn
Attorney (firm/attorney search):
textAttyLastName, textAttyFirstName, textAttyMiddleIni, textAttyFirmName
hButtonClicked # hidden, set by JS based on Submit1/Submit2
Submit1 | Submit2 # both submit buttons present; Submit1 = attorney, Submit2 = firm
Family records are partially restricted. The Family File search returns results only for cases the public has access to per 22 NYCRR 205.5. Records sealed for juveniles, adoption, or PINS surface a notice instead of case data — capture and pass through verbatim, do not invent.
NYSCEF Case Search — POST /nyscef/CaseSearch
rbCaseIdentifierNumberType # indexNumber | fileNumber | thirdPartyNumber
txtCaseIdentifierNumber # generic identifier
txtCivilIndexNumber + txtCivilYear # split civil index
txtIndexNumber + txtYear # alternate split index
txtCounty # numeric, NYSCEF enum (§3)
txtCaseType # tokenized base64 value from live form — never hardcode
selCivilCourts, selCivilCaseTypes # additional filters, tokenized values
txtFilingDateFrom, txtFilingDateTo # MM/DD/YYYY (the only sub-system that exposes a filing-date range directly)
Filing-date range search exists only on NYSCEF. For attorney-name + date-range searches on civil cases, the public path is WebCivil Supreme/Local Attorney Search (no date filter, then client-side filter by filing_date on the result set) — there is no server-side filing-date filter on WebCivil itself.
WebSurrogate — https://websurrogates.nycourts.gov/
Separate React-SPA on its own domain. Click through Start (POST /Home/Welcome, WelcomePageButton=Start) to reach the search picker, then one of: Name Search, File Search, Old Index Search, Index Book Pages, Will Search. Not all counties expose all 5 surfaces (the page footnotes *Not all Surrogate's Courts have these records available online). Document images are gated by 22 NYCRR 207.64 (CPI) — WebSurrogate prevents access to files and documents that are restricted per 207.64, but does not redact documents. … WebSurrogate ONLY provide links to document images that were filed on or after 02/19/2014.
5. Submit and solve the captcha
Every Find/Search button carries class="… h-captcha" and data-sitekey="6c824b97-caeb-4a2a-9144-db4f1c9f86d0". The h-captcha widget is bound via data-callback="onSubmit" — clicking the button programmatically does not bypass it. Either:
- Use Browserbase's
--verifiedflag (passive solver — passes most low-friction interactions). - Or call out to an hCaptcha-solving service mid-flow and inject the token into
h-captcha-responsebefore clicking submit.
Pure HTTP-form replay (curl / fetch) is not viable — verified empirically: the FCASCaseInfo direct-URL trick returns HTTP 400, and the search POST without a valid h-captcha token returns the search form unchanged.
6. Parse the result table
Result pages are classic <table> markup. Each row maps to a case:
<tr>
<td><a href="FCASCaseInfo?…">154321/2024</a></td> <!-- index -->
<td>Bronx Supreme Court</td> <!-- court -->
<td>SMITH, JOHN v ACME CORP</td> <!-- caption -->
<td>Tort - Motor Vehicle</td> <!-- nature -->
<td>03/15/2024</td> <!-- filed -->
<td>Active</td> <!-- status -->
</tr>
Click each index-number anchor to load the case-detail page. The detail URL has the shape:
/webcivil/FCASCaseInfo?index=<base64-or-blob> # Supreme
/webcivilLocal/LCCaseInfo?index=… # Local
/webcrim_attorney/CaseDetail?… # Criminal
/fcasfamily/FileDetail?… # Family
The index= query value is opaque (URL-encoded blob, not the plain 12345/2024). Always pull the href from the result row — do not construct case-detail URLs yourself.
7. Parse the case-detail page
The detail page presents three named regions:
- Case Info — caption, filed date, RJI date, status, disposition date, current judge, court part.
- Attorney / Party — table of parties with role, attorney(s) of record, firm, bar #, address.
- Appearance / Motion / Disposition — chronological appearance list, motion history with motion-sequence numbers, disposition lines.
NYSCEF link (when present) appears as a footer anchor: <a href="https://iapps.courts.state.ny.us/nyscef/DocumentList?docketId=…">View Documents on NYSCEF</a>. Capture the docketId query param — that's the canonical NYSCEF case ID.
8. Release the session
browse cloud sessions update "$sid" --status REQUEST_RELEASE
Site-Specific Gotchas
- hCaptcha sitekey
6c824b97-caeb-4a2a-9144-db4f1c9f86d0is shared across WebCivil Supreme, WebCivil Local, and WebCriminal. Solving it once per session reuses the token across all three sub-systems (verified by sitekey identity across forms — does not need re-solve per submit). WebFamily and WebSurrogate do not currently carry the widget on their entry forms but may rate-limit aggressively without a proxy. - Browserbase sandbox limitation discovered during generation: The CDP
wss://connect.usw2.browserbase.com/…endpoint is not always egressable from every sandbox environment. This skill's interactive verification was unable to complete inside the host's generation sandbox — all flow design is HTTP-evidence-based from the search-form HTML (165+ search-form fields, all option enums, hCaptcha sitekey, ASP.NET WebForms shapes). Re-validate in a normal Browserbase sandbox before treating as launched. - Court ID enums do not interchange. Albany Supreme is
2on WebCivil Supreme,60on WebFamily,U:NY001035Jon WebCriminal, and1on NYSCEF. Fetch each sub-system's form and parse its own select before submitting. - NYSCEF case-type values are per-request tokens. Each
<option value="…">underselCivilCaseTypesandtxtCaseTypeis a per-session base64 blob (sWHk4cQE2DWkSsfNFnJ1xw==, etc.). Re-read the form's option DOM after each session create — hardcoded tokens are rejected silently (empty result). - Index format differs by sub-system. WebCivil Supreme = single
txtIndexfield"12345/2024". WebCivil Local = splittxtIndexNumber+txtIndexYear. WebFamily docket = 4 split inputstextDocket{,1,2,3}. WebCriminal = singletxtCaseNumberwith prefix (CR-…). hCourtTypehidden field is sticky. On Supreme entry it'sSupreme, on Local it'sLocal. JavaScript on the page rewrites field visibility based on this — but the server also gates whichcboCourtenum is valid. Setting Supreme hidden + Local court ID returns "Invalid Court Selection".GET /webcivil/FCASCaseInfo?index=12345/2024returns HTTP 400. Detail URLs are reachable only via the search-results table — theindex=query param is an opaque blob, not the plain index string. Always follow the anchor from the result page.- WebCivil Supreme Party Search has no first-name field. Only
txtPlaintiffLname(single party-name input that matches against last-name or business name). For first-name discrimination, paginate result list and filter client-side. WebCivil Local DOES expose a unifiedtxtPartyName(last + first concatenated in one field). rdRepresentsis Party-search-only. Setting it on Index/Attorney/Judge searches is silently ignored.- WebCriminal has no filing-date range or attorney search. Only Case-Identifier and Defendant searches. To cross-reference an attorney across criminal cases, you must enumerate via WebCivil Supreme/Local Attorney Search and filter to court-type=Criminal in post-processing.
- Filing-date range search exists only on NYSCEF. For WebCivil filing-date-windowed queries, the supported pattern is: WebCivil Attorney Search → result list (no date filter server-side) → client-side filter on
filing_datecolumn. - WebFamily Family-court records are 22 NYCRR 205.5-restricted. Many family case types (juvenile delinquency, PINS, adoption, neglect) return an access-restriction message instead of case data. Surface the message text verbatim — never fabricate.
- WebSurrogate is a separate React SPA on
websurrogates.nycourts.gov, not part ofiapps.courts.state.ny.us. Document-image links gated by 22 NYCRR 207.64 (CPI) — only documents filed ≥ 02/19/2014 are linked online. Pre-2014 docs require in-person inspection at the courthouse. - No public housing-court (NYC Housing Part / L&T) docket on WebCivil Local for tenant search by name. Housing Part appears in
cboCourtfor index-number lookup only — party-name search is restricted to maintain tenant privacy. Surface "Housing Part party search not publicly available" rather than returning empty. rbOutputFormat=PDFreturns a multi-page printable PDF, not the table HTML. AlwaysHTMLfor scraping.- Result pagination uses
hPageNumberpostbacks, not query params. To page through > 25 results, replay the same form withhPageNumber=2,3,…and the samehSearchKeythat the first response set.hSearchKeyis a one-time server token — capture it from the first result page's hidden input. - Town & Village Justice Courts (~1,200 courts statewide) are NOT in eCourts. The WebCivil Local
cboCourtenum covers city + county civil + district + community justice centers. Town & Village dockets are paper-only at the local courthouse. Report "not available online" rather than failing silently. - Rate limit: ~30 req/min sustained per IP without proxy → 429-equivalent (form re-renders with no result). With
--proxiesthe limit is per-egress-IP, effectively lifted but Browserbase proxy bytes are billed.
Expected Output
{
"query": {
"kind": "index | party | attorney | docket | url",
"court_type": "Supreme Civil | Supreme Criminal | County Civil | County Criminal | Surrogate | Family | NYC Civil | NYC Criminal | Housing | Town & Village",
"county": "Bronx",
"filters": {
"party_role": "plaintiff | defendant | petitioner | respondent | both",
"case_status": "active | disposed | both",
"filing_date_from": "2024-01-01",
"filing_date_to": "2024-12-31",
"nature_of_action": "Tort - Motor Vehicle"
}
},
"results": [
{
"index_number": "154321/2024",
"docket_number": null,
"court": {
"type": "Supreme Civil",
"name": "Bronx Supreme Court",
"county": "Bronx",
"part": "Part 12"
},
"caption": "SMITH, JOHN v ACME CORP",
"parties": [
{ "name": "SMITH, JOHN", "role": "Plaintiff", "representation": [{ "attorney": "DOE, JANE", "firm": "Doe & Roe LLP", "bar_number": "1234567" }] },
{ "name": "ACME CORP", "role": "Defendant", "representation": [] }
],
"nature_of_action": "Tort - Motor Vehicle",
"filing_date": "2024-03-15",
"disposition_date": null,
"status": "Active",
"assigned_judge": "HON. SMITH, ALICE",
"attorneys": [
{ "name": "DOE, JANE", "firm": "Doe & Roe LLP", "role": "Attorney for Plaintiff", "bar_number": "1234567" }
],
"most_recent_event": {
"date": "2024-09-12",
"type": "Motion",
"description": "Motion Seq 003 — to dismiss — submitted"
},
"appearance_history": [
{ "date": "2024-09-12", "type": "Motion submitted", "outcome": "Submitted" },
{ "date": "2024-06-04", "type": "Preliminary Conference", "outcome": "Held" }
],
"motion_history": [
{ "seq": "003", "filed": "2024-08-01", "type": "to dismiss", "status": "submitted", "decision_date": null }
],
"nyscef": {
"case_id": "2024-CV-0154321",
"document_list_url": "https://iapps.courts.state.ny.us/nyscef/DocumentList?docketId=2024-CV-0154321"
},
"detail_url": "https://iapps.courts.state.ny.us/webcivil/FCASCaseInfo?index=<opaque-blob>",
"source_subsystem": "WebCivil Supreme"
}
],
"pagination": {
"page": 1,
"page_size": 25,
"total_results": 1,
"has_more": false,
"next_page_token": null
},
"warnings": [
"Housing Part party-name search not publicly available — index-number lookup only.",
"Family records for case types sealed under 22 NYCRR 205.5 surface an access-restriction message instead of case data — passed through verbatim under results[].access_restricted."
]
}
For not-found / access-restricted / sub-system-unavailable cases, return a sentinel result row instead of omitting silently:
// Access-restricted (WebFamily juvenile / adoption / PINS, WebSurrogate 207.64)
{ "index_number": "F-12345-24NA", "access_restricted": true, "restriction_notice": "Case sealed per 22 NYCRR 205.5", "court": { … }, "detail_url": null }
// Sub-system unavailable for this court (Town & Village)
{ "court_requested": "Town of Brookhaven Justice Court", "available_online": false, "notice": "Town & Village Justice Courts are not in eCourts. Contact the courthouse directly." }
// Direct lookup miss
{ "query": "12345/2024", "found": false, "reason": "no_match_in_court_id_124" }