Reference

Auth, errors & spec

Everything request-plumbing: how keys work, what the limits are, how errors come back, and where the machine-readable spec lives. Base URL: https://api.lawfirm.dev/v1.

Authentication & scopes

Send your API key as a Bearer token on every request. Production keys start with lf_live_; test keys with lf_test_.

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

Keys carry scopes — all read endpoints require the lookup scope, which every key has by default. A key without the needed scope receives 403 missing_scope. Keys are revocable instantly from the dashboard; treat them like passwords and keep them server-side.

Rate limits & billing units

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 — statute lookups included. Search endpoints bill at one unit per returned record, capped by your limit parameter — so plan limits accordingly.

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.
400bad_as_ofasOf must be YYYY-MM-DD.
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.
404no_edition_on_fileNo statute version in force on the requested asOf date (coverage floor). Never resolved to a nearest edition.
429rate_limitedPer-key rate limit exceeded; retry after the reset window.
500internal_errorServer-side problem. Safe to retry.
503statutes_unavailableStatute corpus not configured on this deployment.

OpenAPI spec

The full OpenAPI 3.1 spec, served by the API itself:

Generate a typed client with openapi-typescript or any other OpenAPI 3.1 generator — or use the first-party SDK.