NY Attorney Bar Registration Status Delta avatar

NY Attorney Bar Registration Status Delta

Pricing

$10.00 / 1,000 bar status changeds

Go to Apify Store
NY Attorney Bar Registration Status Delta

NY Attorney Bar Registration Status Delta

Watches named New York attorneys in the official NY bar registration registry and alerts only on a genuine license status change (Suspended, Disbarred, Resigned - disciplinary, Delinquent, Deceased). For law firms, HR screening, insurers, compliance/due-diligence. Free when nothing changes.

Pricing

$10.00 / 1,000 bar status changeds

Rating

0.0

(0)

Developer

Radu Furtuna

Radu Furtuna

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 days ago

Last modified

Share

Durable monitor for the official NYS Attorney Registrations registry (New York Unified Court System / Office of Court Administration), published as open data on data.ny.gov. Watch specific attorneys by their registration number and get notified only when their bar registration status genuinely changes. No API key needed, no login, no captcha.

Source

https://data.ny.gov/resource/eqw2-r5nb.json — the Socrata Open Data API for "NYS Attorney Registrations" (dataset id eqw2-r5nb). Confirmed live 13.09.2026: 433,545 rows, updated on an ongoing basis by NY OCA. registration_number is the dataset's unique, permanent identifier for one attorney's registration — not their name, which is never unique. The status field observed live (13.09.2026) takes at least these values: Currently registered, Suspended, currently registered, Suspended, delinquent, Delinquent, Due to reregister within 30 days of birthday, Resigned, Resigned from bar - disciplinary reason, Disbarred, Deceased, Incapacitated, Suspended, due to reregister.

How it works

  1. Each watch names exactly one attorney by registrationNumber (their NYS Attorney Registration Number — look it up at iapps.courts.state.ny.us/attorneyservices/search if you only have a name). One watch = one point query ($where=registration_number=<N>) = one HTTP request per run.
  2. The first check of a new watch establishes a baseline (no charge). Every later check compares the current status against the durable record of what it was last time.
  3. Billing is tied only to the status field — not to name, address, phone, or the routine next_registration renewal date that shifts every two years for every actively registered attorney. A status that changes and later reverts (e.g. suspended, then reinstated, then suspended again) bills every genuine transition, not just the first one — never silently deduplicated against an earlier occurrence of the same status value.
  4. Genuinely new (first found) or status-changed records are pushed to the dataset and billed once each (bar-status-changed); a check that finds nothing new costs nothing beyond the fixed platform run cost.

Input

{
"monitorId": "my-attorney-watch",
"watches": [
{ "watchId": "new-hire-smith", "registrationNumber": "1234567" }
],
"notifyOn": "new_alerts",
"webhookUrl": "https://example.com/webhook"
}

Add more attorneys later under the same monitorId — each watch keeps its own independent history. A watchId is permanently bound to the registrationNumber it first saw; pointing the same watchId at a different registration number later fails the run instead of silently mixing histories.

socrataAppToken is optional — data.ny.gov does not require a key for this dataset, but a free Socrata app token from your own account raises the anonymous request-rate ceiling if you run many watches across many monitors.

Output row (per change)

watchId, registrationNumber, changeType ("new"|"status_changed"), status, previousStatus, firstName, middleName, lastName, suffix, companyName, street1, street2, city, state, zipCode, zipPlusFour, country, county, phoneNumber, yearAdmitted, judicialDepartmentOfAdmission, lawSchool, nextRegistration, monitorId, runId, discoveredAt, eventId, billed

Billing

Pay-per-event: bar-status-changed — charged only for a watch's first found record (baseline is free) or a genuine status transition since the previous check. Failed/blocked checks are never charged.

Delivery/billing guarantee: at-most-once, not exactly-once

The right to perform an irreversible action (dataset write + PPE charge) is granted by the only atomic primitive Apify offers — RequestQueue.addRequest(uniqueKey) → wasAlreadyPresent — in a separate named queue that acts as a permanent journal (<prefix>-<monitorId>-claims). The Apify Key-Value Store has no CAS, no conditional write and no ETag, so it can only ever be a diagnostic state machine, never the source of at-most-once.

Concretely: for one computed event, delivery and charging each happen no more than once. If the run dies after taking the claim, the event may be lost (it stays dataset_unknown/charge_unknown and is never re-delivered) — but you will never be billed twice. That is a deliberate trade: "never overcharge" beats "never lose a row".

Boundaries of the guarantee, stated honestly:

  • Between the internal lease check and the dataset write/charge there is an unavoidable TOCTOU gap; what actually protects your money is the claim gate, not the lease.
  • The guarantee holds for as long as the named claims queue exists. Anyone with account access can delete or recreate it via Console/API, which starts the journal from zero. This is a boundary of any durable storage, not a defect of the protocol.
  • The guarantee applies from the build in which the claim gate was introduced onward. Older builds must not keep running against the same monitorId.

Important — read before relying on this for any hiring/compliance/legal decision

This registry is a publication of registration status, not a certification of good standing or a complete disciplinary record. New York courts and grievance committees maintain their own authoritative records; the public dataset reflects what NY OCA has published, which can lag real-world events. This actor is an informational monitor of CHANGES to that public publication — it is NOT a current "license to practice" certification, NOT a disciplinary-history lookup, and NOT legal advice. Always confirm directly at iapps.courts.state.ny.us/attorneyservices/search (or with the relevant Appellate Division) before acting on any single entry — especially for hiring, insurance underwriting, or engagement decisions.

Honest limits

  • The durable dataset is a delivery-attempt log, not a guaranteed mirror of the default dataset. Each row is written to the durable dataset first, then mirrored to the run's default dataset before billing proceeds for that row. If the durable write succeeds but the default-dataset mirror write fails (e.g. transient Apify storage error), the item is marked dataset_unknown, billing for it is permanently blocked (fail-closed — we never charge for a row we can't confirm was delivered), and the run is not retried into re-creating that exact row. The durable dataset can therefore end up with a small number of orphan rows that were never mirrored and never billed. The default dataset is the canonical log of rows successfully written to this run's output (see its run_summary row) — but a default-dataset row does not by itself prove the row was billed: the row is written before Actor.charge() runs, so if charging then fails or comes back charge_unknown, the row is present but not confirmably paid. run_summary.eventsBilled and Apify's own billing ledger are the source of truth for confirmed payment, not the presence of a row in either dataset.
  • One watch = one attorney, one request. There is no bulk/roster mode — to track a firm's associates, add one watch per attorney (up to 30 per run). This keeps the network cost fixed and predictable regardless of the registry's total size (433k+ rows), and keeps each attorney's history independently auditable.
  • A "not found" result on the very first check of a watch is reported honestly, not as an error — coverage.watches[].matched: false. The registry does not delete records (confirmed live: even Deceased/Disbarred attorneys remain listed), so a typo'd registrationNumber will simply never match; it costs nothing and is safe to correct and retry under the same watchId.
  • A registration number that WAS found on a previous check but is NOT found on a later one is treated as source_access_limited for that watch this run — no baseline/history update, no billing. Since the registry doesn't delete rows, this should never happen from a genuine data change; it's the honest fallback if the source ever answers unexpectedly.
  • Billing tracks only the status field, deliberately excluding next_registration (which shifts routinely for every actively registered attorney every two years) and address/contact fields (which can change administratively without any change to registration status). Those fields are still delivered in every row for context.
  • We don't invent data: if the API ever returns something other than a bare JSON array, more than one row for a single registration_number (violating the dataset's own uniqueness contract), or a row missing registration_number/status, the run reports it honestly (source_access_limited) instead of guessing.

Author: OmniCoder (https://t.me/OmniCoder)