API

Podmínky použití a uvedení zdroje

Provozovatelem API Platné znění je Internet 1 CZ s.r.o., Šumberova 345/26, 162 00 Praha 6, Česká republika, IČO 26473003. Kontakt: api@zneni.cz.

Zdrojem dat jsou otevřená data e-Sbírky Ministerstva vnitra. Konsolidované znění je informativní. Závazné je pouze znění vyhlášené ve Sbírce zákonů. Zobrazit v e-Sbírce.

Pokud text zobrazujete lidem, ponechte u něj viditelný odkaz z pole esbirka_url nebo source_url. Text nesmíte vydávat za závazný a nesmíte odstranit údaj data_date.

Přístup bez klíče je zdarma a má limit 200 datových volání za den na IP adresu. IPv6 adresy se počítají podle prefixu /64. Požadavky bez klíče ze sdíleného rozsahu adres AI asistentů (například claude.ai) mají společný limit 5 000 datových volání za den. Denní limity se obnovují v 00:00 UTC.

Klíč zdarma má limit 2 000 datových volání za den, placený klíč 50 000. Klíč zdarma si vytvoříte po přihlášení na https://zneni.cz/ucet/klice. API a MCP čerpají stejnou kvótu. Hromadné čtení paragrafů počítá jedno volání za každý vrácený paragraf nebo článek.

Kdo se přihlásil za zaváděcí cenu, platí tuto cenu nejméně 24 měsíců od začátku předplatného. Případnou změnu ceny po této době oznámíme e-mailem nejméně 30 dní předem a předplatné lze před jejím účinkem zrušit.

Bez úvazku, zrušit lze kdykoli.

Placený klíč zatím není v nabídce.

Požadavky bez klíče mají limit 120 za minutu na IP adresu, 600 pro sdílený rozsah adres AI asistentů. Klíč zdarma má limit 300 požadavků za minutu, placený 1 000. Všechny požadavky z jedné IP adresy mají navíc společný strop 1 200 za minutu, 6 000 pro sdílený rozsah. Klíče lze při zneužití zrušit.

Služba je poskytována bez záruky dostupnosti a správnosti, nad rámec cíle dostupnosti placeného klíče.

Připojení z claude.ai nebo Claude Desktop s klíčem

Server MCP Platné znění funguje i bez klíče, se společným denním limitem. S vlastním klíčem máte limit klíče, 2 000 volání denně zdarma.

  1. Přihlaste se na https://zneni.cz/ucet a na stránce Klíče API vytvořte klíč.
  2. V claude.ai nebo Claude Desktop otevřete Nastavení, Konektory a zvolte Přidat vlastní konektor.
  3. Jako adresu zadejte https://zneni.cz/mcp.
  4. V Pokročilém nastavení přidejte hlavičku Authorization s hodnotou Bearer a za mezerou váš klíč.
  5. Uložte konektor. Klíč se posílá s každým požadavkem.

Claude Code

Přidejte server příkazem:

claude mcp add --transport http zneni https://zneni.cz/mcp --header "Authorization: Bearer KLÍČ"

Cursor

Do souboru .cursor/mcp.json přidejte:

{
  "mcpServers": {
    "zneni": {
      "url": "https://zneni.cz/mcp",
      "headers": {"Authorization": "Bearer KLÍČ"}
    }
  }
}

Za KLÍČ dosaďte celý klíč, který začíná zneni_. Klíč nikdy nevkládejte do adresy URL ani do sdílených souborů. Uniklý klíč zrušte na stránce Klíče API.

Účet a osobní údaje

Správcem osobních údajů je Internet 1 CZ s.r.o., Šumberova 345/26, 162 00 Praha 6, Česká republika, IČO 26473003. Kontakt: api@zneni.cz.

Účet uchovává e-mail, identifikátor účtu Google při přihlášení přes Google, u placeného účtu identifikátor zákazníka Stripe a stav předplatného, názvy klíčů, datum vytvoření účtu, potvrzení e-mailu, pozastavení a smazání účtu, data vytvoření a platnosti relací, data vytvoření, použití a platnosti přihlašovacích odkazů, data vytvoření, posledního použití a zrušení klíčů, denní počty volání podle klíče za 30 dní a počty volání podle klíče, rozhraní a nástroje za dva dny. Neuchovává žádné údaje o čtení.

Údaje zpracováváme pro vydávání a účtování API klíčů na základě smlouvy a oprávněného zájmu na provozu služby. Údaje uchováváme po dobu existence účtu, denní počty volání 30 dní, počty volání podle rozhraní a nástroje dva dny, přihlašovací odkazy a relace do vypršení jejich platnosti. Stripe uchovává faktury podle vlastních daňových povinností.

Při přihlášení přes Google zpracovává údaje Google, při platbě Stripe a při odeslání odkazů poštovní server. Stripe pro platbu dostává identifikátor zákazníka, identifikátor účtu, zvolenou cenu a platební údaje zadané přímo u Stripe. Nikomu dalšímu je nepředáváme. Nepoužíváme analytiku, profilování ani marketingové e-maily.

Účet smažete na /ucet/smazat potvrzením odkazu v e-mailu. Do jednoho dne odstraníme účet včetně klíčů, relací a počtů volání. Účet může smazat také správce příkazem admin accounts delete. Při smazání se zruší živé předplatné. Záznam zákazníka u Stripe zůstává podle pravidel uchovávání Stripe.

Čtečka nezpracovává osobní údaje a nepoužívá cookies. Účet pod /ucet používá pouze dvě nezbytné cookies pro přihlášení a ochranu formulářů, nastavené po žádosti o přihlášení. Tyto cookies nepotřebují souhlas ani souhlasovou lištu.

Obrázky naskenovaných předpisů jsou uloženy na našem serveru a při jejich zobrazení neodchází žádný požadavek na jiný server.

Přístupové logy Caddy a hostitelského nginx obsahují IP adresy a uchovávají se podle stávajících pravidel na serveru na základě oprávněného zájmu na provozu služby. Počítadla volání podle IP adresy se mažou po dvou dnech.

Dokumentace jako text. OpenAPI.

Platné znění API v1

Base URL: https://zneni.cz/api/v1

The registry lists only answers this release serves. Arguments in path placeholders are required. GET routes accept no request body. POST routes accept JSON up to 32 KiB. Every POST request counts one quota unit. Oversize bodies answer 400 invalid.

export

Operation
export
Method
GET
Route
/api/v1/export/{c}/{y}/{n}/{date}
Required
c,y,n,date
Optional
format
Description
One resolved version attachment, JSON or Markdown, keyed tiers, bounded disk spool, no ETag or MCP tool

change_feed

Operation
change_feed
Method
GET
Route
/api/v1/changes
Required
none
Optional
since,cursor,limit
Description
Immutable loader observations, keyed tiers, Prague observation days

decision

Operation
decision
Method
GET
Route
/api/v1/decisions
Required
ref
Optional
part,cursor
Description
Held Ústavní soud decision, conditional capability

decision_verify

Operation
decision_verify
Method
POST
Route
/api/v1/decisions/verify
Required
ref,quote
Optional
cursor
Description
Verify against a held decision, conditional capability

act_changes

Operation
act_changes
Method
GET
Route
/api/v1/acts/{c}/{y}/{n}/changes
Required
c,y,n
Optional
since,page
Description
Changed sections of an act, since is a calendar day, page defaults to 1, 50 rows a page

cite

Operation
cite
Method
GET
Route
/api/v1/cite
Required
ref
Optional
none
Description
Resolve a Czech citation

check_citations

Operation
check_citations
Method
POST
Route
/api/v1/cite/check
Required
text
Optional
date
Description
Check every citation in JSON text

verify_quote

Operation
verify_quote
Method
POST
Route
/api/v1/versions/{c}/{y}/{n}/{date}/sections/{anchor}/verify
Required
c,y,n,date,anchor,quote
Optional
none
Description
Verify a JSON quote

links

Operation
links
Method
GET
Route
/api/v1/versions/{c}/{y}/{n}/{date}/sections/{anchor}/links
Required
c,y,n,date,anchor
Optional
direction,page
Description
References, 50 entries per direction per page

lookup

Operation
lookup
Method
GET
Route
/api/v1/acts
Required
q
Optional
limit
Description
Ranked act matches, limit is 1 to 10, default 10

search

Operation
search
Method
GET
Route
/api/v1/search
Required
q
Optional
page,collection,year_from,year_to,kind
Description
Search current versions, page defaults to 1

search_in

Operation
search_in
Method
GET
Route
/api/v1/versions/{c}/{y}/{n}/{date}/search
Required
c,y,n,date,q
Optional
none
Description
Search one version

changes

Operation
changes
Method
GET
Route
/api/v1/versions/{c}/{y}/{n}/{date}/sections/{anchor}/changes
Required
c,y,n,date,anchor
Optional
none
Description
Changes to one section

diff

Operation
diff
Method
GET
Route
/api/v1/versions/{c}/{y}/{n}/{date}/diff/{to_date}
Required
c,y,n,date,to_date
Optional
anchor,page
Description
Changes between versions, page defaults to 1

history

Operation
history
Method
GET
Route
/api/v1/acts/{c}/{y}/{n}/sections/{anchor}/history
Required
c,y,n,anchor
Optional
limit,offset
Description
Wording history with texts, limit 1 to 20 defaults to 10, offset from 0 defaults to 0, with span_count and continuation

coverage

Operation
coverage
Method
GET
Route
/api/v1/coverage
Required
none
Optional
none
Description
Corpus coverage

act

Operation
act
Method
GET
Route
/api/v1/acts/{c}/{y}/{n}
Required
c,y,n
Optional
none
Description
Act

versions

Operation
versions
Method
GET
Route
/api/v1/acts/{c}/{y}/{n}/versions
Required
c,y,n
Optional
none
Description
Versions

version_at

Operation
version_at
Method
GET
Route
/api/v1/acts/{c}/{y}/{n}/at/{date}
Required
c,y,n,date
Optional
none
Description
Version at

version

Operation
version
Method
GET
Route
/api/v1/versions/{c}/{y}/{n}/{date}
Required
c,y,n,date
Optional
none
Description
Version

toc

Operation
toc
Method
GET
Route
/api/v1/versions/{c}/{y}/{n}/{date}/toc
Required
c,y,n,date
Optional
depth
Description
Toc

section

Operation
section
Method
GET
Route
/api/v1/versions/{c}/{y}/{n}/{date}/sections/{anchor}
Required
c,y,n,date,anchor
Optional
format,depth,offset
Description
Section

sections

Operation
sections
Method
GET
Route
/api/v1/versions/{c}/{y}/{n}/{date}/sections
Required
c,y,n,date,anchors
Optional
format,depth
Description
Sections

page

Operation
page
Method
GET
Route
/api/v1/versions/{c}/{y}/{n}/{date}/pages/{page}
Required
c,y,n,date,page
Optional
none
Description
Page

codelist

Operation
codelist
Method
GET
Route
/api/v1/codelists/{name}
Required
name
Optional
none
Description
Codelist

Dates mean the date the wording was in force. They resolve without redirects. The change feed since argument instead names a Prague observation day. The value 0000-00-00 selects promulgated text. The value today selects today. An unchanged section in a diff returns no entries. An absent section returns anchor_not_in_version and nearest_version.

Source URLs answer 200 without a redirect. Version-scoped answers use the resolved version's dated reader URL, never the requested date. Section, links and quote answers, batch entries and section citations name the split page and its html_id. Changes names the zmeny page. SearchIn names najit with q. Page names its split page, or the undivided dated URL for whole. The version, TOC and batch documents name the undivided dated version URL. Act and act-only citations name the current dated version through the reader's current cache. A dated ELI citation names that version. CheckCitations with date uses the version effective on that date. Versions and ActChanges name verze, and section history names its history page. Lookup names hledat/akt with q, except a complete held act citation names that act's current dated URL. Search names hledat with q and strana from page 2. Coverage and code lists name o-projektu. CheckCitations names the home page. A diff names the inline reader diff page of the resolved pair at the requested page. An anchor names the page holding that entry, without a fragment until the redesign adds entry ids. Its content region contains the entry's section label. An unchanged anchor names its section in the newer version, or the older if absent there. A one-version diff answers 200 with no entries and zero counts, with its source URL naming that version's dated reader page, or the section when an anchor is set.

Every document is one flat object. The answer fields and the common fields eli, citation, source_url, esbirka_url, data_date, binding, disclaimer and tier are side by side at the top level. There is no result wrapper and no answer field reuses a common field name. Every common key is always present. Public fields use snake_case. Reader envelopes and comparison timings are excluded. Diff and history retain the M9 field names.

On acts lookup, current search and coverage, eli, citation and esbirka_url are null. On other routes eli identifies the version or act, or the newer version on a diff, and citation is its formal citation. esbirka_url is null exactly when eli is null. source_url is never null and carries utm_source=api. data_date is the Prague calendar day YYYY-MM-DD of the finish of the last ok applying load, or null when no such run exists. No date is a timestamp. binding is false and disclaimer states that consolidated text is informative.

Errors use an error object with code, message and optional retry_after or nearest_version. Codes are not_found, invalid, unauthorized, quota, unavailable, no_version_for_date, anchor_not_in_version and not_yet_in_force. Typed refusals answer 404. Invalid arguments answer 400, an invalid, revoked or suspended key answers 401, limits answer 429 and unavailable dependencies answer 503. Errors are no-store. retry_after appears only on quota. nearest_version appears only on anchor_not_in_version and is always present there. It is the ELI of the act version holding the anchor nearest by effective date to the date asked, the to date on a diff, or null when no version holds it. It is never an empty string.

Keyless calls allow 200 per UTC day per IP, IPv6 grouped by /64. Connector ranges share 5,000 calls. Burst limits are 120 per minute per IP and 600 per range. Counters fail closed. Cookies are ignored and responses never set cookies. Valid free and paid bearer keys receive their tier's answers, including bulk pages, with private, no-store and quota headers after validation. Free keys allow 2,000 units a UTC day and 300 requests a minute, paid keys 50,000 and 1,000. API and MCP share these limits. Every IP also has a pre-key burst limit of 1,200 requests a minute, or 6,000 for a connector range. A pre-key refusal has no quota headers.

Every API response, including errors and 304, permits every origin with Access-Control-Allow-Methods: GET, POST and Access-Control-Allow-Headers: Authorization, Content-Type. Access-Control-Expose-Headers lists ETag, Retry-After, X-Quota-Limit, X-Quota-Used, X-Quota-Remaining and X-Quota-Reset. Max-Age is 86400. There are no credentials. OPTIONS on every API path answers 204 without a body before the burst gate or quota, including during a gate outage. Keyless documents cache publicly for an hour, search and lookup for five minutes. Every GET 200 carries a strong ETag, the quoted lowercase hex of the first 16 bytes of SHA-256 over the exact body sent, including its trailing newline. If-None-Match with that tag, its W/ form or * answers 304 with the same ETag and Cache-Control and no body. A changed data_date, amendment label, resolved diff version or any other body byte changes the tag. No response is immutable. No route accepts v. Unknown or repeated arguments answer 400 invalid. Acts lookup accepts only q and limit, search accepts q, page, collection, year_from, year_to and kind. Search filters combine with AND before the candidate cap. Collection is sb, sm, ul0 or ul1. Years are four digit strings on act.year, inclusive. Kind is a code matching ^[A-Za-z][A-Za-z0-9_]*$, compared without regard to case. A well-formed unknown kind returns no hits. A malformed filter or year_from after year_to answers 400 invalid with the standard error object. The MCP search tool uses the same filters. The lookup answer for limit n is the first n rows of the reader's ten-row answer, from the same lookup cache entry. A limit above 10 answers 400 invalid.

Consolidated text is informative. Only promulgated text is binding. Keep source_url or esbirka_url visible when displaying text and retain data_date.

Version answers carry applied_date, version_effective_from, version_effective_to, is_current and next_change. Ties list also_effective. TOC nodes carry bytes. Section format is exactly one of plain, xhtml or markdown, default plain. Only that representation key is returned. Depth is an integer of 0 or more. For sections, 0 is the whole subtree and the default, n keeps fragments at most n levels below the section. TOC depth defaults to 2, 0 is the whole tree. A TOC depth of n includes n levels starting with the root nodes at level 1. Sections and every TOC node always carry children_omitted, true when depth excludes children. A cut TOC node has children [] and children_omitted true. Nonempty fragments remain in document order. Plain joins their PlainText with one newline. XHTML wraps each rewritten stored body in a flat sibling div with its full data-anchor. Markdown separates fragment blocks by one blank line. The selected UTF-8 text is capped at 8192 bytes, cut back to a character start. Every section result and batch entry carries truncated, next_offset and continuation. On a cut, next_offset is the first byte not returned in the whole text. Continuation is the absolute single-section API URL for the version answered, with format, offset=next_offset and depth only when the request set it. Otherwise both fields are null and truncated is false. The url is the reader URL. Offset is a single-route argument only, default 0. Offset equal to the text length returns an empty uncut text. Negative, past-end and mid-character offsets answer 400 invalid. Following continuations reconstructs the whole text byte for byte. Batch anchors accepts 1 to 10 entries in caller order, one quota unit per returned section. Batch offset is unknown and answers 400 invalid. Pages are open to valid free and paid keys and answer 401 keyless. A version stored as one undivided page uses the page id whole in its pages list, every TOC node and the pages path. The whole page's source_url is its undivided dated URL. Whole on a divided version answers 404 not_found. No API page id is empty. Unknown and repeated arguments answer 400.

Cite ref is an ELI reference, exactly one citation, or a bare number/year optionally prefixed by č. after trimming. Empty input, no statute citation, multiple citations or text beyond it answers 400 invalid, with the single decision exception below. A single unparsed citation answers 200 with eli, citation and esbirka_url null, as do ambiguous and not_found results.

Act parts start after a character other than a letter, digit or slash. The year has exactly four digits and cannot be followed by a letter, digit, slash, or ASCII hyphen, U+2010 through U+2015 or U+2212 immediately followed by a digit. The six kind words are zákona, ústavního zákona, vyhlášky, nařízení vlády, smlouvy and sdělení. Standalone act parts require a kind word or collection mark, and unnamed marks start with an uppercase letter. Bare number/year, optionally prefixed by č., is accepted only as an entire trimmed Cite or tool ref. A failed act part leaves the preceding enumeration unparsed and produces no standalone citation.

Sb. m. s., including Sb.m.s., resolves into sm. Sb. or no collection mark resolves into sb. Other collection marks are unparsed. An act part ends an enumeration. Every written member joined by a comma, a, nebo or až is reported, including both written ends of a range. Paragraphs and letters inherit the levels above them. Without an ending act part, every member is unparsed. Bare § and čl. are unparsed spans of the sign alone. Spans never overlap. Each span covers its own designation, the last also its act part. Start and end are half-open Unicode code point offsets into decoded, unnormalized text. Citation statuses are found, not_found, ambiguous, repealed, not_in_force_on_date, unparsed and not_checked. Short names resolve through short_name.

Quote comparison folds case, drops NFD combining marks and quote marks "'„“”‚‘’«», maps U+2010 through U+2015 and U+2212 to ASCII hyphen, and collapses whitespace including no-break spaces and line breaks. Input with no letter or digit is invalid. Verbatim requires a normalized substring match on word boundaries and may cross sentences and fragments. Otherwise words are runs of letters or digits. Similarity is 1 minus minimum word edit distance over quote word count, using any contiguous text run. Ties prefer the earliest run, then the shortest. Near starts at 0.8 before rounding, similarity has three decimal places of precision. differing_words holds substituted or unmatched quote words as written. missing_words holds substituted or omitted text words as written. Both are ordered and empty on verbatim. best_matching_sentence covers the original sentences containing the first and last matched words. A sentence ends at a line break, at . ! or ? followed by whitespace and an uppercase letter, or at text end. Empty section text gives absent, similarity 0, empty lists and an empty sentence. Historic sections and below-section fragments read body at request time. Current sections use search_doc.plain.

POST responses always use no-store, carry no ETag and ignore If-None-Match. They never answer 304. Body bounds remain 32 KiB and every POST counts one unit. GET caching and conditional requests retain the body ETag rule above.

Links direction is in, out or both, default both. Page is an integer from 1, default 1. Both directions cover the anchor and its subtree, equal to a or starting with a/. Bare prefixes never match. Outgoing counts link rows and returns 50 in source fragment seq then link id order, including within-act references. Each has source_anchor. Incoming counts source acts, uses the newest version holding a reference, and returns 50 acts ordered by count descending then act ELI in byte order. Anchors are distinct source anchors. References are distinct source_anchor and exact target_anchor pairs in byte order by source then target. One page applies to both requested directions. A page past the end has an empty list and its total. An unrequested direction has both its list and total null.

MCP tools

Stateless streamable HTTP at /mcp. Successful law-data calls return the flat law document as structured content and compact JSON text. An isError result has one text item holding the compact error document, with no structured content and no evidence_kind. Protocol messages use the burst gate and consume no data unit. A law-data tool call consumes one unit, a section batch one per section. The optional submit_feedback operation consumes no data unit and has no HTTP route.

get_section

Tool
get_section
Required
ref
Optional
date,format,depth,offset
Evidence
evidence

version_at_date

Tool
version_at_date
Required
act
Optional
date
Evidence
evidence

list_versions

Tool
list_versions
Required
act
Optional
none
Evidence
hint

get_toc

Tool
get_toc
Required
act
Optional
date,depth
Evidence
hint

search

Tool
search
Required
q
Optional
page,collection,year_from,year_to,kind
Evidence
hint

search_in_act

Tool
search_in_act
Required
act,q
Optional
date
Evidence
hint

what_changed

Tool
what_changed
Required
act
Optional
anchor,since
Evidence
evidence

cite

Tool
cite
Required
ref
Optional
none
Evidence
evidence

get_links

Tool
get_links
Required
ref
Optional
date,direction,page
Evidence
evidence

check_citations

Tool
check_citations
Required
text
Optional
date
Evidence
evidence

verify_quote

Tool
verify_quote
Required
ref,quote
Optional
date,cursor
Evidence
evidence

get_sections

Tool
get_sections
Required
refs
Optional
date,format,depth
Evidence
evidence

coverage

Tool
coverage
Required
none
Optional
none
Evidence
hint

diff_versions

Tool
diff_versions
Required
act,from_date,to_date
Optional
anchor,page
Evidence
evidence

section_history

Tool
section_history
Required
ref
Optional
limit,offset
Evidence
evidence

get_decision

Tool
get_decision
Required
ref
Optional
part,cursor
Evidence
evidence

recent_changes

Tool
recent_changes
Required
none
Optional
since,cursor,limit
Evidence
hint

Observation feed

With feed and no glossary, sixteen law tools are registered when decision retrieval is off and seventeen when get_decision is registered by its flag and readiness. Enabled feedback adds one, giving seventeen or eighteen respectively. A shipped glossary adds one to each count. recent_changes and GET /api/v1/changes return the same journal page. since is an inclusive Prague observation day, rather than an effective date. The default is seven days including today, clamped to available_since. Free keys have thirty days including today. Paid keys have the complete journal since history_start. Bootstrap invents no historical events.

The flat document has null eli, citation and esbirka_url, source_url at the site root, the common data_date of the last successful load, events, history_start, available_since, has_more, next_cursor and continuation. An event has event_id, kind, observed_at, observation_day, act_eli, nullable version_eli, citation, source_url, esbirka_url, data_date, nullable effective_from, effective_to, state and change_counts. Counts have added, changed, removed and unchanged-but-renumbered. Counts compare legal versions, never yesterday's dump. Act counts and state are null. Links name the act timeline and the official act or version. Entries are hints, never legal evidence, with no snippets or titles.

limit is 1 to 100, default 50. since and cursor are mutually exclusive. A cursor is canonical unpadded base64url JSON, at most 2048 bytes, with format 1, epoch, nullable position and lower_day. A position has observed_at, event_id, act_eli and nullable version_eli. No upstream numeric identifier is exposed. Act identities match ^/eli/cz/(sb|sm|ul0|ul1)/[0-9]{4}/[no]?[0-9]+[a-z]?$, with a year from 0001 to 9999. The optional lowercase n or o prefix and single lowercase letter suffix are preserved, including combinations such as n1a. Version identities append a real calendar day /YYYY-MM-DD or /0000-00-00 to that exact act. No trailing slash, query, fragment, extra segment or encoded separator is accepted. Events, cursor positions, REST and MCP schemas and webhook eli, act_eli and version_eli fields use this same grammar. Pages ascend by commit-ordered observation instant and UUID. next_cursor and continuation are present even at the empty tail, ready for polling. continuation names only /api/v1/changes, cursor and limit.

A malformed cursor or future date answers 400 invalid. Expired dates, positions, epochs and restored-away positions answer 410 cursor_expired. Only that error has available_since, with an instruction to restart there. It has no ETag and is no-store. MCP uses isError with the same error document.

Keyless REST answers 401 unauthorized and the tool returns unauthorized. Every admitted keyed poll costs one shared daily unit, including empty results, errors and REST 304. Responses use private, no-store, Vary: Authorization, quota headers and the usual body ETag. The feed has no Valkey data cache and is excluded from the seven cached latency classes. The existing 15 second deadline applies.

Export defaults to disabled until the reader gate passes under export load. JSON ends with complete true, Markdown with <!-- zneni-export-complete -->. Clients must reject a failed transfer or a missing end marker. A free key admits twenty exports per UTC day. Every admitted export consumes one daily unit. Render deadlines, loader activity, conflicting DDL and database replacement release both reservations.

Before maintenance, the operator sets and applies API_EXPORT_ENABLED=false on all API replicas and leaves it disabled until verification finishes. Loader, migration, deployment and restore paths have no export coordination. Export observes loader lock 8140 and conflicting DDL, aborting without charge. Database context loss discards the partial spool without reconnecting. A completed spool can transfer independently while its global admission connection remains alive.

Exports use a private disk directory from API_EXPORT_DIR, default /var/tmp/zneni-export, with a 16 MiB file cap and 40 MiB directory budget. This path must be on disk, never tmpfs. Keep API_EXPORT_ENABLED=false until the unchanged reader gate passes under repeated, slow and disconnected export traffic. Render and transfer histograms report separately, outside the seven cached API classes.

Export size refusals expose error.reason as output_bytes, fragment_bytes or workspace_bytes. A render deadline is 503 export_render_deadline with render_deadline, a pages API pointer and neither quota unit charged. Other export availability reasons distinguish statement_timeout, database_unavailable and export_loader_active and export_schema_change.

Paid-key webhook account forms

Webhook registration and delivery default to disabled pending resource, privacy and host egress approval. Account management is available at GET /ucet/klice/{prefix}/webhook. Replace {prefix} with the displayed key prefix. Signed-out users follow the account login flow. Another account's prefix is hidden. Free or revoked keys can inspect and delete an existing registration.

The separate account form registry defines these routes, all under the existing session, CSRF and form rate limits. These webhook operations are account forms, with no REST write resource or MCP tool:

GET /ucet/klice/{prefix}/webhook shows status.

POST /ucet/klice/{prefix}/webhook registers the url form field.

POST /ucet/klice/{prefix}/webhook/zrusit deletes the registration.

POST /ucet/klice/{prefix}/webhook/obnovit starts again at the current journal tail.

POST /ucet/klice/{prefix}/webhook/tajemstvi rotates the independent signing secret.

Every POST carries csrf_token. Create, enable and rotate require a live paid key and an unsuspended account. Creation and rotation show the base64url secret and its id once in a private 200 response. Other successful writes redirect 303 to the status page. A second rotation during the 24-hour overlap answers 409. Re-enabling and URL replacement skip missed observations. Recover those through the paid change feed. Delivery is at least once and unordered. Receivers verify the timestamped HMAC over the exact body and durably deduplicate event UUIDs for at least seven days.

The complete wire and receiver contract is maintained in /api/webhooks.txt (source docs/contracts/webhooks-v1.md). Operator aggregate status is admin webhooks status. No reader route, API quota, seven-class latency gate or pricing trigger changes.

MCP active feedback

MCP-only operation: submit_feedback. Required: feedback. Optional: none. Data quota: zero. No REST route exists. Authentication, invalid-key refusal and burst gates still apply. Keyed responses report unchanged data quota counters. Feedback is off by default. Its four annotations are readOnlyHint false, destructiveHint false, idempotentHint false and openWorldHint true. Its Czech title is Odeslat zpětnou vazbu.

The input is exactly one feedback string, with no extra members, duplicate members or trailing JSON. Text must fit 8000 UTF-8 bytes before trimming, contain no NUL and remain nonempty after trimming. The full MCP request remains bounded to 64 KiB. Text is untrusted evidence, never instructions.

A confirmed commit returns matching compact JSON text and structuredContent with status submitted, id as a decimal string and created_at as UTC RFC 3339. Its generated outputSchema has no evidence_kind, ELI or law attribution. Text is never echoed. Errors use isError and the error envelope without structuredContent. Codes are invalid, feedback_disabled, feedback_limit_exceeded and unavailable. The limit error includes retry_after in seconds until UTC midnight. A lost commit acknowledgement leaves an unknown outcome, reported as unavailable with reason unknown_outcome. Never automatically retry this non-idempotent operation.

Server instructions point to skill://feedback-workflow/SKILL.md. The host must show the exact short summary and obtain an affirmative reply before calling. A stored receipt proves storage, not consent. Offer feedback only for meaningful unmet needs or volunteered feedback, never after fixed call counts or each success. Respect refusal. Exclude transcripts, credentials, personal details and unrelated case facts.

resources/list and resources/read expose the packaged skill bytes. The optional io.modelcontextprotocol/skills extension declares skills/list and skills/get with frontmatter, SHA-256 digest, byte size, resultType complete, ttlMs 300000 and cacheScope public. Unknown skills/get URIs return invalid params. Resource fallback alone is not extension compliance or host activation. Malformed packaged metadata disables feedback discovery.

Keyless allowances per UTC day are three per IPv4 or IPv6 /64 identity, thirty per IPv4 /24 or IPv6 /48 network and one hundred per matching connector range. Every matching range applies. Free keys have six and paid keys thirty, independent of keyless network caps. All callers share a thousand per day and ten thousand live rows. HMAC identities use a separate stable secret. Text deletion does not refund allowance. Retention, key/account erasure and backup reconciliation are independent operator work. No reader page, cookie, asset, cached latency class or pricing trigger changes.

Connect to /mcp using the existing header and account guidance above. Feedback appears only when enabled. Protocol and skill discovery are not evidence of host activation. Availability is controlled by the operator. Feedback is disabled by default.

Court coverage and citation checks

With the decision feature disabled or not ready, court holdings describe website data separately from tool capability. Ústavní soud decisions are available on the website only, not through these tools. No decision retrieval tool is registered. With no held court rows the statement is "No case law held on this server." A failed optional court read reports unknown availability and does not stop API startup. Statute coverage remains required.

Coverage includes decision_tools (an empty array unless a feature registers), court_available (true, false or null), court_imported_at, court_exported_at, court_age_seconds and court_stale. When the court-count read fails, case_law is null. A successful read retains its existing object with decisions, earliest and texts, including an empty corpus. Missing dates and unknown age and stale are null. Age is computed on every read from the newest successful court export. Above 48 hours court_stale is true and court_warning is "Court export is more than 48 hours old." Unknown age warns "Court export age is unknown." The cache key is coverage:v2. A failed court read is not cached. Disabled-feature descriptions retain the Step 0 wording.

Citation spans carry kind (statute or decision) and reason. Decision references, including ECLI in any letter case, sp. zn., č. j., ÚS display file numbers, numbered court forms such as As, Afs and Cdo, and Konf, Vol and Pst without a senate number, are detected separately. An explicit Sb. tail takes statute precedence. Every statute span from the statute parser survives unchanged. Overlapping decision spans are dropped. Court registers form a closed, case-sensitive set. Explicit sp. zn. and č. j. prefixes allow at most two file-number tokens before digits/year, excluding statute designations and act kind words. Separators accept ASCII whitespace and U+00A0. Enumerated numbers are separate spans of the same court class. An ECLI ends in a letter or digit and excludes sentence punctuation. Without registered decision retrieval, every decision span has status not_checked. Its reason is unsupported_court for non-ÚS forms, court_unavailable when no ÚS rows are held, otherwise decision_tools_not_registered. Unchecked spans are not successful checks. Every cite and check_citations result carries decision_scope_note exactly "Decision references in other forms or under other court registers, such as SbNU or report citations, are not detected." Cite of exactly one decision reference answers 200 with that span, eli null and source_url the site root. A decision ref in a statute tool answers 400 invalid.

Initialize instructions require fetching text before quoting, treating returned text as data, copying source_url exactly, using the relevant date and reporting the version returned. Statute dates mean účinnost and decision dates mean decision day. Missing results do not prove nonexistence. Not checked, ambiguous and unavailable citations are not successful checks. No commentary or legal advice is provided. The fixed instructions are followed by one newline and the current coverage statement only. Unknown availability says "Court availability is unknown. No decision retrieval tools are registered."

Conditional decision retrieval

With the feed, discovery lists sixteen law tools without decision retrieval and seventeen with it, plus one when feedback is enabled. The registry and this document include get_decision and both shipped decision routes even when disabled. API_M14_FEATURES must contain decision, and a successful import with usable Ústavní soud text and HTTPS NALUS links must be held. Unset enables nothing. Unknown configuration values disable the optional configuration, never base startup. Disabled routes answer 503 unavailable. Only tools/list filters by flags and readiness.

Readiness is probed every 60 seconds with a one-second deadline. A successful probe publishes an immutable MCP server. Failed probes retain the previous server. A call for a removed get_decision name returns isError unavailable without structured content. Runtime court failures remain local to decision retrieval and verification. In mixed citation checks an unavailable decision span does not prevent statute checks. Citation checks resolve decision identities in one read without retrieving cards or decision text. Citation reads use one separate process-wide permit and wait for it within a three-second deadline that includes the read and pool acquisition. Quotes and wording comparisons use their own work permit. A document with more than 64 detected Ústavní soud spans leaves those decision checks unavailable. Expiry while waiting for citation capacity answers unavailable with reason citation_capacity. Expiry during pool acquisition or reading answers unavailable with reason citation_deadline. Neither reason asserts court availability or export age. A failed court read also leaves decision checks unavailable. Statute spans still complete in the same document with HTTP 200. Resolved citation spans do not carry continuations for unrelated card fields. Detected Ústavní soud spans rejected by the strict reference parser answer unparsed, including I. Ús 311/99, I. ÚS 2147483648/20 and I. ÚS 1/2093.

ref is one exact, case-sensitive ECLI or one Ústavní soud file number, optionally prefixed by sp. zn. A sequence suffix filters that sequence. Without a suffix every sequence matches. Multiple matches remain ambiguous and have decision_candidates, never an arbitrarily selected newest decision. Multiple numbers require separate calls. Unsupported courts remain unchecked in citation tools and not_held in retrieval.

part defaults to text and accepts text, card, provisions and citations. Only the selected part is populated. Metadata segments retain field, ordinal and byte offset. Card segments include value_type and empty_array to distinguish nulls and empty arrays. Concatenate segments by identity and offset to recover the value. Raw citation segments use raw, offset and complete. Identity summaries over their bounded size set identity_omitted and are recoverable through the card part.

Text is plain, at most 8,192 UTF-8 bytes. Every compact decision document is at most 32,768 bytes. All parts page at row boundaries, with long individual values segmented without loss. next_cursor is null at the end. A cursor binds reference, ECLI, part, position and court import hash. Provisions also bind the comparison day and statute generation. A changed generation answers 409 corpus_changed and requires a fresh call. The statute generation includes the latest applying run's identity and status. A newer applying run that is not ok makes comparisons unknown with statute_apply_incomplete, until a later successful applying run. This does not change the loader, take its lock or affect statute tools. continuation is absolute on SITE_URL with no tracking parameters. New decision routes are no-store and every continuation costs one ordinary quota unit. Resolved decision evidence in cite is also no-store, including ambiguous and not_held answers. Statute-only cite retains its existing caching and conditional responses. get_decision and decision quote reader source URLs are also emitted without tracking parameters, identically through REST and MCP. A quote continuation is the POST endpoint and its cursor, repeated with the original ref and quote.

Decision documents keep eli, citation and esbirka_url null, binding false, and use the Prague day of court import for data_date. They carry kind decision, NALUS attribution, a held HTTPS deep link, court freshness and the notice: "Text je zveřejněn tak, jak jej publikuje NALUS, databáze Ústavního soudu. Nejde o autentické znění." A missing or invalid deep link makes retrieval unavailable. An unheld decision is not_held, which does not prove nonexistence. A held card without text is text_unavailable. Mixed documents retain the statute notice at the top and a NALUS notice on each decision span or candidate. No internal ids, importer storage paths or raw JSON appear.

Registered retrieval enables decision resolution in cite and check_citations. Each resolved decision span also carries court freshness, including unknown dates as null and the court warning. Disabled-feature spans retain the Step 0 shape. verify_quote accepts a decision reference and rejects an explicit date. It compares the whole held plain text, with the existing quote normalisation and scoring. Source offsets are bytes in plain. Matching excerpts are bounded and continued by cursor. Repeat the POST with ref, quote and the returned cursor. Ambiguous, not_held and text_unavailable answers have no score. Deadline and work refusals are unavailable, never absent. QuoteWorkCap bounds conservative word-DP work before DP allocation. One process-wide worker admits decision quote CPU work and provision comparisons. Excess calls fail unavailable without waiting for capacity. Quote text and generation are read in one snapshot, then the pooled connection is released before normalization and matching. Before publishing offsets, verification rechecks both the newest import generation and the source text fingerprint. A changed source returns corpus_changed. Normalization, word extraction, DP and alignment observe the request context. The cursor argument is invalid for statute quote verification. With decision retrieval disabled, quote references follow the existing statute resolver.

Each provision compares complete Section subtrees resolved through VersionAt on the decision date and the comparison day. Only whitespace is normalised. The result is same, changed or unknown with a specific reason. Missing sides, version ties, renumbering and incomplete work remain unknown. This compares a designation at two endpoints and makes no claim about the decision's applicability. Statute links use the same selected decision-date version. At most twenty provisions are compared per page.