API reference · v1

Build on bar-verified data.

Every field returned by the lawfirm.dev API carries the source that produced it, when, and at what confidence. The base URL is https://api.lawfirm.dev/v1. Authenticate with a Bearer token from your dashboard.

Quickstart

Every request needs an Authorization: Bearer <key> header. Production keys start with lf_live_; test keys start with lf_test_.

curl https://api.lawfirm.dev/v1/attorneys/lookup?name=smith \
  -H "Authorization: Bearer lf_live_..."

A successful response:

{
  "results": [
    {
      "attorney": {
        "id": "k77a2hk...",
        "canonicalName": "Jane Smith",
        "email": "jsmith@example.com",
        "currentFirmId": "f3p2bn...",
        "isVerified": true
      },
      "_meta": {
        "fieldSources": {
          "email": {
            "source": "bar_bulk_export",
            "assertionId": "a91f...",
            "assertedAt": 1748419200000,
            "confidence": 0.95
          }
        },
        "lastReconciledAt": 1748419200000
      }
    }
  ]
}

Auth & rate limits

Send the API key as a Bearer token on every request. Rate limits are per-key and returned as standard X-RateLimit-* headers. The free tier is 10 lookups/day and 100 lookups/month, with a 10/minute burst; paid tiers raise all three on issuance.

Each successful lookup counts as one billable unit. Search endpoints bill at one unit per returned record, capped by your limit parameter — so plan limits accordingly.

Endpoints

GET/attorneys/lookup

Search attorneys by name, jurisdiction, bar number, or email.

name
string — full-text match on canonical + variant names
jurisdiction
string — two-letter US state code
barNumber
string — exact match, combine with jurisdiction
email
string — exact, case-insensitive
isVerified
boolean — limit to claimed records
limit
integer 1–100 (default 25)
GET/attorneys/{id}

Full canonical view including joined bar admissions and current firm summary.

GET/attorneys/{id}/assertions

Append-only provenance log. One row per source-asserted fact, including superseded values — ideal for compliance audits.

field
string — filter to one field (e.g. email)
limit
integer 1–500 (default 100)
GET/firms/lookup

Full-text search of verified law firms. Non-law entities (medical PAs, vet practices) are excluded by default.

name
string — required
jurisdiction
string — two-letter US state code
limit
integer 1–100 (default 25)
GET/firms/{id}

Canonical firm view with address, jurisdictions, and roll-up of current attorneys.

GET/firms/{id}/attorneys

Current attorneys at the firm.

limit
integer 1–500 (default 100)
GET/bar-admissions/verify

Cheapest 'is this attorney actually licensed?' call. Returns admission + minimal attorney handle. Bills 1 unit.

jurisdiction
string — required, two-letter code
barNumber
string — required

Errors

Errors return a JSON envelope with a stable machine-readable code. Switch on error.code, not on the message.

{ "error": { "code": "missing_bearer", "message": "Bearer token required" } }
StatusCodeMeaning
400missing_fieldsRequired query/body field is absent.
400invalid_bodyRequest body wasn't valid JSON.
401missing_bearerAuthorization header missing or empty.
401invalid_keyKey not found or revoked.
403missing_scopeKey lacks the scope required for this endpoint.
404not_foundNo record exists for the supplied id.
429rate_limitedPer-key rate limit exceeded; retry after the reset window.
500internal_errorServer-side problem. Safe to retry.

How provenance works

Every canonical field on an attorney or firm has a matching entry in _meta.fieldSources. The fields are:

  • source — one of bar_scrape, bar_bulk_export, state_sos, firm_website, attorney_correction, staff_edit, and others.
  • assertionId — the winning row in our append-only assertions log. Fetch the full history via /attorneys/{id}/assertions.
  • assertedAt — Unix milliseconds.
  • confidence — 0..1.

When two sources disagree, our per-field precedence matrix decides which wins. Bar directories beat firm websites for bar-status fields; attorney corrections (after claim verification) beat both.

Spec downloads

The full OpenAPI 3.1 spec:

Generate a typed client with openapi-typescript or any other OpenAPI 3.1 generator. The first-party TypeScript SDK (@dodotdev/lawfirm-sdk) is published on npm and tracks this spec.

Need a key?

Free tier is 100 lookups/month (10/day) with full REST + MCP access. Paid tiers and SLAs on the pricing page.

Email hello@lawfirm.dev