Search a jurisdiction's laws
https://api.granska.cloud/v1/lawsSearches a jurisdiction's catalogue of laws, and says which of them this corpus holds.
What this answers that a public register does not
You can find an SFS number on riksdagen.se. What you cannot find there is whether a citation to it will resolve here — and that is the one thing a profile needs to be accepted.
That is the held field on every hit. true means the law is in the library and
POST /v1/profiles will accept a reference to it. false means it is
not, yet.
Searching is free. It spends no analysis quota and counts against no floor, so you may call it as often as your integration needs. That is deliberate: a caller who cannot search cheaply guesses citations instead, against a metered write endpoint, and that is worse for everyone.
curl -G https://api.granska.cloud/v1/laws \
--data-urlencode "jurisdiction=SE" \
--data-urlencode "query=föräldrabalk" \
-H "Authorization: Bearer $TOKEN"{
"jurisdiction": "SE",
"fetchable": true,
"attribution": null,
"unavailableSources": [],
"laws": [
{
"jurisdiction": "SE",
"work": "1949:381",
"title": "Föräldrabalk (1949:381)",
"displayLabel": "Föräldrabalk (1949:381)",
"pinpoint": null,
"issuingBody": "Justitiedepartementet L2",
"repealedAt": null,
"held": true
},
{
"jurisdiction": "SE",
"work": "1981:1292",
"title": "Förordning (1981:1292) om vårdnadsutredningar",
"displayLabel": "Förordning (1981:1292) om vårdnadsutredningar",
"pinpoint": null,
"issuingBody": "Justitiedepartementet",
"repealedAt": null,
"held": false
}
]
}The parameters
jurisdiction says which legal order to search. SE, NO, DK and US_FED resolve today. Any
other value is refused with a 400 that names what is available — never an empty list, because an
empty list would say that law does not exist when the truth is we have not integrated that
country.
US_FED is answered by two sources at once, and the answer takes one hit from each in turn —
regulations first — so a small limit narrows both halves rather than cutting one of them away.
Federal regulations come from the Office of the Federal Register's own full-text search of the
Code of Federal Regulations, live on every request, so a regulation is searchable from the first
day; a hit is a CFR part, such as 45 CFR 1355. Federal statutes come from a catalogue of the
United States Code that is rebuilt nightly from the release point the Office of the Law Revision
Counsel publishes, so that half of the answer is empty until the first corpus night after the
integration has run, and a section Congress adds appears the night after the release point carrying
it does.
query is matched against each law's number and its title. Two characters minimum. A shorter query
is a 400 rather than a list of everything.
unavailableSources names, by source id, a law source that did not answer while another did. It is
[] on the ordinary day. US_FED is the case it exists for: the regulations half is a live call to
the Office of the Federal Register, and when that service refuses under load the statutes half,
which reads our own copy, still answers — the response then carries "unavailableSources": ["us-ecfr"] beside the hits it has, so an absent CFR hit can be told from a CFR that was not asked.
The two ids US_FED can name are us-ecfr for the regulations and us-uscode for the statutes;
compare against those exact strings. Retry for the full list. A search that every source fails is a
500, never an empty list.
| Parameter | Description |
|---|---|
jurisdictionstring·query·required | Which legal order to search, as a code such as SE. Only a legal order with an integrated law source can be searched — SE, NO, DK and US_FED resolve today; anything else is refused by name. |
querystring·query·required | Free text matched against each law's number and title. At least two characters. |
limitinteger·query | How many hits to return, between 1 and 50. Defaults to 50. |
{
"jurisdiction": "SE",
"fetchable": true,
"attribution": null,
"unavailableSources": [],
"laws": [
{
"jurisdiction": "SE",
"work": "1949:381",
"displayLabel": "Föräldrabalk (1949:381)",
"pinpoint": null,
"held": true
}
]
}
pinpoint — when a hit names a provision rather than a law
Most catalogues are catalogues of laws. Search Sweden, Norway or Denmark and a hit is an act, and
pinpoint is null because there is no provision in the row to name.
Search the Code of Federal Regulations and a hit is a part, such as 45 CFR 1355, and pinpoint is
null there for a different reason: eCFR searches at section level, and we fold those hits to their
parts because a part is what an agency amends as a piece. The section exists in the hit; we do not
offer it. Read null as "this hit names no provision", not as a promise that a catalogue never
will.
The United States Code is the other shape. Its catalogue is built one section at a time, so
42 U.S.C. 1983 answers with § 1983 itself rather than with the 8 481-section title it sits in.
That hit carries the section as data:
{
"jurisdiction": "US_FED",
"work": "42 U.S.C.",
"pinpoint": "§ 1983",
"displayLabel": "42 U.S.C. § 1983 — Civil action for deprivation of rights",
"held": true
}
work and pinpoint are exactly the two fields
POST /v1/profiles wants in a reference, in exactly the spelling it
wants them. Send them back as they arrived — searching for a section and citing it is two calls, and
nothing in between is composed or taken apart.
Do not parse a pinpoint out of displayLabel. The label is prose formatted for a reader, and the
§ 1983 inside it is there to be read, not to be extracted. Where pinpoint is null and you need
a provision, read the law itself with GET /v1/laws/:jurisdiction/:work, which
carries the pinpoint of every provision it returns.
Two title fields, and which one to show
displayLabel is the one to put in front of a person. It is a single clean line, formatted for that
purpose.
title is the register's own text, untouched — which means hard line breaks inside it, the law's
number repeated within it, and several lines of it on older acts. It is published because it is the
authentic wording and some integrations need exactly that. It is not published because it is
presentable.
We do not publish an instrument type — whether something is a lag, a förordning or a
författning — as a separate field, and we will not add one. The Swedish register does not state it:
every row of it is labelled SFS, which names the register rather than the kind of instrument. The
only way to produce that field would be to guess it from the first word of a Swedish title, and a
legal fact inferred from a text string is not a legal fact. A reader still sees it, because
displayLabel reads "Förordning (1982:47) om…". We show it; we never assert it.
repealedAt is a date when the law has been repealed and null when it has not. A repealed law is
still returned and still citable — that is a judgment for you to make, not one for a search endpoint.
attribution is a licence condition, not a courtesy
Some registers are licensed data, and the licence requires that the source be named wherever the data
is shown. attribution carries the exact line that register demands, and it is null where no such
duty exists.
Norway's catalogue is published by Stiftelsen Lovdata under NLOD 2.0, so a Norwegian search answers:
{
"jurisdiction": "NO",
"fetchable": true,
"attribution": "Inneholder data under Norsk lisens for offentlige data (NLOD) tilgjengeliggjort av Stiftelsen Lovdata.",
"unavailableSources": [],
"laws": []
}
Sweden's register carries no such condition and always answers null.
Show the line wherever you show the data. The duty travels with the text: it reaches your product the moment you display a Norwegian title or provision to a user, and passing the data on without it is a breach of the licence we hold. Read the field rather than hardcoding the sentence — a register's required wording is theirs to change, and a hardcoded copy is one that silently stops being correct.
held: false means one of two things, and fetchable says which
fetchable sits on the response, not on each hit, because it is a fact about the jurisdiction's
source rather than about any one law.
fetchable: true— ask for the law withGET /v1/laws/:jurisdiction/:workand it will be fetched, parsed and stored on the spot.held: falsehere means not yet. Sweden, Norway, Denmark and the United States all work this way.fetchable: false— that jurisdiction's corpus arrives as whole bulk archives with no way to request a single law.held: falsehere means asking will not change it. What is absent stays absent until the next bulk refresh.
Errors
Every refusal here is a 400, and every one of them names what was wrong with the request. There is
no 404: a search that matches nothing is a successful search with an empty laws array. A search
that could not be performed at all is an error, and the two are never confused.
| Error | When |
|---|---|
400BAD_REQUEST | jurisdiction is missing or names no legal order with an integrated law source — being open is not enough, and the message names the ones that resolve — or query is missing or shorter than two characters, or limit is not a whole number between 1 and 50. |
401UNAUTHORIZED | The Authorization header is missing, is not a readable bearer token, or names no tenant. |
401TOKEN_EXPIRED | The access token was issued by this gateway and has since expired. Not probed: it needs a token older than its own lifetime. |
500INTERNAL_ERROR | An unexpected server-side failure. Not probable from outside — reaching it means something is wrong. |
Send it without writing a client
If your organisation already has an account, an administrator can call this from the API tester at
/admin/api-tester without spending any quota.