Bindinglaw

Authentication

One header, one scope, three ceilings.

Every metered call carries Authorization: Bearer and a key you issue for yourself. Coverage, quality and the health checks need no key at all — they are public so that “do you have this?” never costs anything.

Getting a key

Keys are issued from your account and shown exactly once — we store only a SHA-256 hash of the key and the first sixteen characters for display, so a lost key is replaced, never recovered. Sign up to issue one.

Production keys begin with lf_live_; test keys begin with lf_test_. Treat a key as a password: put it in an environment variable, never in client-side code or a repository. The API is meant to be called from your server — it does not send permissive CORS headers, so a browser cannot reach it from an arbitrary origin anyway.

Sending it

The header is the standard bearer form. The check is case-insensitive on the Bearer prefix; the key itself is not.

curl "https://api.binding.law/v1/law/text?jurisdiction=us&citation=15-45" \
  -H "Authorization: Bearer $BINDING_API_KEY"

What a failure looks like

Every error on this API has the same envelope: an error object with a stable machine-readable code and a human message. Switch on the code, never on the message text.

401 · no Authorization header
{
  "error": {
    "code": "missing_bearer",
    "message": "Bearer token required"
  }
}

Also returned when the header is present but the token after Bearer is empty.

401 · unknown or revoked key
{
  "error": {
    "code": "invalid_key",
    "message": "Invalid API key"
  }
}

The key did not match any active record. Revoked keys answer the same way.

A key that is valid but lacks the scope an endpoint needs returns 403 with missing_scope, naming the scope it wanted.

Scopes

Every law endpoint requires one scope: lookup. Self-service keys are issued with it and it is the only scope a customer can grant themselves — anything broader is staff-issued. In practice this means a key either works across the whole law surface or it is not a law key.

Limits

Three ceilings apply to a key, and each has its own code and its own Retry-After, because telling a client to wait sixty seconds against a daily quota just produces 1,440 failed retries a day.

rate_limited429 · per minuteRetry-After: 60 seconds
The key's per-minute request ceiling. A coarse 120/minute limit also applies per key at the edge, before the key is even looked up.
daily_limit_exceeded429 · per UTC dayRetry-After: seconds until 00:00 UTC
The key's daily billable-unit cap. Windows are UTC, matching how usage is bucketed.
monthly_limit_exceeded429 · per UTC monthRetry-After: seconds until the 1st
The key's monthly billable-unit cap.

Metered calls bill one unit each; a citation-resolution request bills one unit per citation in the batch. The public endpoints bill zero. What each plan allows is on the pricing page.

Endpoints that need no key

GET /v1/law/coverageThe coverage matrix. Also accepts POST with the same fields in a JSON body.
GET /v1/law/qualityOur own audit of the corpus — where our data is thinner or coarser than it should be.
GET /v1/healthIs the process alive. Never touches the corpus.
GET /v1/health/corpusCan law actually be served. 503 when the corpus store is unreachable.
GET /v1/openapi.yamlThe OpenAPI spec. Served as .json at the same path.

Coverage accepts an Authorization header if you send one — it is recorded as a zero-unit call and changes nothing about the answer.

Bindinglaw

Point-in-time US law with the receipt attached. Source URL, retrieval time, content hash, and validity dates on every answer.

curl api.binding.law/v1/law/coverage

© 2026 binding.law · a Jubal, Inc. productAttorneys and firms never pay. Ever.