Docs menu
Get started
Quickstart Install: Claude Code Install: Codex Install: other clients API keysConcepts
How a run works The app profile The severity model What a run does not sayTools
check_access claim_trial_key set_profile run_lint get_law resolve_domain_jurisdiction submit_feedback upload_lint_runGuides
A whole run, end to end Console TestPack in CIReference
Endpoint and transport lexlint.yml schema Errors ChangelogHelp
Support and feedbackTools
run_lint
The findings, each with its citation and the date it was last checked.
What it does
Step 2, and the one that returns findings. Pass the activities and jurisdictions
set_profile validated.
It costs three upstream requests for any number of declared jurisdictions: the manifest of the LexLint law library and its two published NDJSON files, filtered to your declaration in memory once all three have arrived, rather than fetched one jurisdiction at a time. On a key whose law library has not moved since an earlier lint, the manifest request revalidates as an unmetered 304 and the other two are served from that key's own cache, so a repeat lint against an unchanged law library can cost as few as zero metered requests.
Put together, one full lint from a cold cache, check_access, set_profile, run_lint, costs five upstream requests, however many jurisdictions you declare: at the free tier's 50 requests a day, that is ten full lints a day even before a warm cache makes some of them cheaper.
Not sure which slug to use? Search by name at https://ungovr.org/atlas and read the slug off the entity's URL. The page at https://ungovr.org/urn translates between a URN, a slug, and other government identifiers.
Each finding carries severity, jurisdiction, summary,
citation, as_of_date, stale, and confidence.
Where LexLint holds a page on the instrument, the finding also carries
note_url: show the citation as a link to it. It is null when there is no such
page, and it is never something to construct, since the address is a stored code rather than
a form of the citation.
A finding about a specific instrument also carries lifecycle: what its status
and dates mean read as of now, as one of new, recent,
in_force, imminent, proposed, blocked or
unknown, with a detail line such as in force in 47 days. It is
computed per call, not stored, so a countdown is correct on the day you read it. An
instrument that has been repealed, superseded or withdrawn carries no band, because it is
not reported at all: it binds nobody, and there is nothing for your code to do about it.
Unknown argument names and unknown activity values are refused with an error rather than
silently ignored, so a typo cannot produce a falsely clean run.
Parameters
| Name | Type | Required | What it takes |
|---|---|---|---|
activities | string[] | yes | What the app does, from the profile set_profile returned. Allowed: crawls_web, trains_models, generates_content, deploys_chatbot, automated_outreach, high_risk_decisions, processes_voice, processes_biometrics, publishes_adult_content, operates_social_platform, serves_minors, operates_app_store, ships_mobile_app, aggregates_content, distributes_software_product, handles_health_records, provides_financial_services, operates_essential_service, is_listed_company, provides_telecom_services, statutory_requests, records_conversations, tracks_devices |
jurisdictions | string[] | yes | Jurisdiction slugs from the profile set_profile returned, lowercase, "/"-separated (e.g. "us", "us/ca", "eu", "kr"). A slug is the jurisdiction's UnGovr Atlas path: California is https://ungovr.org/us/ca and its Atlas ID is urn:ungovr:us/ca. Its ISO 3166 code, US-CA, is accepted too. A deeper or unresearched path resolves to the nearest jurisdiction with law, and the jurisdictions whose law is researched are listed at https://lexlint.io/law for the developer to check; name every jurisdiction the app operates in: one left off is unlinted, not passed. |
public_sector | string[] | no | Is this software run by a public body (body), sold to or run for public bodies (supplier), both, or neither (none)? Ask the developer every time the profile is declared; never infer it from the code. Omitted, duties binding only public bodies are reported as the caller's, and run_lint counts them in a coverage line. |
client_version | string | no | The LexLint plugin version you are running, from your SKILL.md, exactly as check_access takes it. Send it on every lint: a run that skips the preflight otherwise learns nothing about its own staleness. Omitted, update_available comes back null, which means LexLint learned nothing, never that you are current. |
brief | boolean | no | Send true when you will show these findings to a person and have no LexLint procedure loaded. Each finding then comes back as one line to print: its summary and first duty clipped to 160 characters, with the citation, note_url, in_force, owed and kind; the full text of any law is one get_law call away. Leave it out when you write lexlint.yml: brief findings drop fields the manifest keeps. |
Result fields
| Field | Type | What it carries |
|---|---|---|
lint | string | One-line verdict: counts by severity, then the verdict itself. The passing state is "no basic issues found", never "compliant". |
activities | string[] | The declared activities this run was evaluated against, de-duplicated. |
jurisdictions | string[] | The declared jurisdiction slugs this run was evaluated against, normalized. |
findings | object[] | Every finding, one per instrument per jurisdiction. Group these into work items before showing them; eight jurisdictions produce a list nobody reads. |
notice | string | The standing disclaimer. Not legal advice, not a certification, not authorization to access any system. |
docs | string | Where the full documentation lives. |
corpus_built_at | string or null | When the bulk export this run read was built. Null on the per-slug request path, which reads no manifest and so has no build stamp: null means "not reported here", never "not built". |
run_at | string | The instant this run was judged at, ISO 8601. Not the same question as corpus_built_at: a finding's kind, severity, staleness and certainty rung move with the clock as well as with the law library, so an instrument becomes a live obligation the moment its effective_date passes, against a law library that has not moved. Send it back on upload_lint_run's compact form, which rebuilds this run at this instant. |
freshness_window_days | integer or null | The law library's re-read cadence in days, as the export publishes it. Not a staleness threshold: no finding is judged or marked against it. Null when the law library states none. |
brief | boolean | Present, and true, when the call sent brief: each instrument finding is then one line, and fields it would otherwise carry (detail, why, matched_by, basis, lifecycle, the rest of requires) are not sent. Absent there means not sent, never empty. |
replay | string | Quote this when you report a problem with a run, and LexLint can reproduce it exactly: the bundle, the law library build, the instant the run was judged at, and a digest of the declaration. Nothing about the run is stored to make it work. |
declaration_sensitivity | object | The finding ids that rest on exactly one declared activity, keyed by that activity in declared order: strike a value the developer doubts and these are the findings that go with it. Show it grouped by activity after the findings. A declared activity nothing rests on alone is absent, and {} means no finding rests on one value. Posture findings rest on crawls_web, which is what draws them; the untagged-activity coverage finding rests on the activity it names; other coverage findings rest on no single value. |
client_version | string or null | The client_version this call sent back, normalized. Null when none was sent. |
latest_version | string | The newest published LexLint bundle, as the server knows it. |
update_available | boolean or null | Three-valued, and only true is an instruction. Null means LexLint learned nothing about your version, which is NOT the same as being current. |
update_command | string or null | The command to run, present only when update_available is true. |
lint_procedure_url | string or null | Where the written LexLint procedure for the lint loop is, set only when no bundle version reached this call; null when the session runs a bundle, which already holds it. Not setup.no_account.procedure_url, which is the keyless first-run document. |
lint_procedure_notice | string or null | Why lint_procedure_url is set and what that procedure holds. Null with it. |
tested_model_families | string[] | Which model families LexLint's procedure is exercised against. Lowercase what you were told about which model you are, the product name included (Codex is told only "Codex, an agent based on GPT-5", or GPT-6), and split it into words on every character that is not a letter; if none of those words is exactly a token from this list, show the developer model_notice and let them decide. Match whole words, never substrings: solar-pro is not sol. Nothing about your model is sent to LexLint: the comparison is yours to make. |
model_notice | string | What to show the developer when their model is not in tested_model_families. An advisory, not a gate: run the lint either way. |