Endpoints: 28,729MCP servers: 18,413Payout addresses: 2,071Paid calls: 1,537Letters: 14Defects: 1,322counted just now
teppi

Server definition

Hash
sha256:cd0cd11a9da464fa9efdfd566d01ca213c18f984073f079c2063d39a99cf058c
What it is
What a remote MCP server returned when asked what it offers: 60 tools

The blob, as servednamed by its sha256

{ "instructions": "Read-only access to live Peppol network data, mirroring the public /v1 REST API — participants, providers, access points, SMPs, hosts, uptime, incidents, anomalies, change events, adoption statistics, and SML zone status. Every tool is read-only. The keyless (free) tools cover network health, participant statistics, SML status, a single participant record lookup, and the dashboard summary; the other tools require an API key (Authorization or X-API-Key header) from a Network or Market plan with the API & MCP access add-on — without one they return a 403 pointing to https://peppolstatus.com/pricing/. A key also raises rate limits. Prefer specific filters and small limits — responses are paginated, so page through large result sets with the returned next_cursor. Use is governed by the Terms of Service at https://peppolstatus.com/terms/.", "tools": [ { "description": "Get an access point\n\nOne Provider's detail: display name, verified flag, member seats (each with its embedded provider or unverified cert-CN), roster size, and the country + document-scheme composition of its roster. A request for a STALE key (a seat since curated, so its old unverified key left the directory) resolves to the current Provider; the returned `key` is always the canonical current one. `software` groups the Provider's sighted hosts by registrable domain with the crawled identity of each, and `hostname_count` / `smp_hostname_count` give the true totals behind the capped `hostnames` / `smp_hostnames` samples. `smp_tenants` lists the Access Points (seats) that serve the participants on this Provider's SMP hosts — on a multi-tenant SMP most of the hosted footprint belongs to other APs — with `smp_tenant_count` / `smp_tenant_other` / `smp_tenant_no_ap` so the rows add up to `hosted_participant_count` (both come from the same rollup run); `smp_hosted_by` is the reverse: other providers' SMPs that carry this AP's participants.", "inputSchema": { "properties": { "key": { "description": "The provider key (e.g. `c-tickstar`, `o-teamleader-nv-1f3a2b9c`).", "type": "string" } }, "required": [ "key" ], "type": "object" }, "name": "get_access_point", "outputSchema": null }, { "description": "Get an access point's churn\n\nAn Access Point's joiner / mover / leaver activity over a period: a daily category series with derived net growth, period totals, and the 'won from / lost to' counterpart breakdown. Joiners are first-ever serving seats (from 2026-08-02 onward, first-full-deep-sweep completion); movers change Provider (both sides resolved to the current identity); leavers deregister while served. Defaults to the trailing 30 days.", "inputSchema": { "properties": { "from": { "description": "Inclusive period start, `YYYY-MM-DD` UTC. Defaults to 29 days before `to`.", "format": "date", "type": "string" }, "key": { "description": "The Provider key (e.g. `c-tickstar`).", "type": "string" }, "to": { "description": "Inclusive period end, `YYYY-MM-DD` UTC. Defaults to today.", "format": "date", "type": "string" } }, "required": [ "key" ], "type": "object" }, "name": "get_access_point_churn", "outputSchema": null }, { "description": "Get a filtered access point roster breakdown\n\nThe five roster breakdowns of `GET /v1/aps/{key}` (country, entity type, NACE Rev. 2.1 division, size class, region) recomputed over a FILTERED slice of the roster, so a breakdown stays true while the roster is cut down. The filters are the same names and shapes as `GET /v1/participants`, scoped to this provider's seats.\n\nBOUNDED BY DESIGN. The breakdowns are computed only when the filtered slice is narrow (under an internal cap of 10,000 participants). A request that narrows on nothing, that carries a filter this endpoint cannot express (`doctype`, `transport_profile`, `q`, `host`, `sub_provider`, `postcode`, `provenance`, `vat_liable`), or whose slice is too wide answers `degraded: true` with every mix null — never a wrong number and never an error. Callers fall back to the stored whole-roster mixes on `GET /v1/aps/{key}`.\n\nCounts are sparse the same way the stored mixes are: company enrichment covers a handful of registers, so every mix except `country_mix` sums BELOW `participant_count` and the un-enriched remainder is derived from the total rather than served as a bucket.", "inputSchema": { "properties": { "country": { "description": "Comma-array of ISO-3166-1 alpha-2 country codes. Matched on the participant's card country, falling back to the country its ICD prefix implies — the same rule the stored `country_mix` buckets on.", "items": { "type": "string" }, "type": "array" }, "entity_type": { "description": "Comma-array of company legal-form families (`company`, `natural_person`, `association`, `public`).", "items": { "type": "string" }, "type": "array" }, "key": { "description": "The provider key (e.g. `c-tickstar`, `o-teamleader-nv-1f3a2b9c`).", "type": "string" }, "not_country": { "description": "Comma-array of country codes (`NO,SE`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_entity_type": { "description": "Comma-array of company legal-form families (`company`,`natural_person`,`association`,`public`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_region": { "description": "Comma-array of company seat region codes (`NO-32,BE-BRU`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_sector": { "description": "Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_size": { "description": "Comma-array of company size classes (as stored; SIRENE only) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "region": { "description": "Comma-array of company seat region codes (`NO-32,BE-BRU`).", "items": { "type": "string" }, "type": "array" }, "registered": { "description": "Restrict to participants present (`true`) or absent (`false`) in the Peppol Directory.", "type": "boolean" }, "scheme": { "description": "Comma-array of Peppol identifier schemes.", "items": { "type": "string" }, "type": "array" }, "seat": { "description": "Scope the slice to ONE member seat of this provider. A seat that is not a member answers an empty (not degraded) slice. Single-valued.", "type": "string" }, "sector": { "description": "Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`).", "items": { "type": "string" }, "type": "array" }, "size": { "description": "Comma-array of company size classes (as stored).", "items": { "type": "string" }, "type": "array" }, "smp": { "description": "Comma-array of SMP hostnames serving the participant.", "items": { "type": "string" }, "type": "array" } }, "required": [ "key" ], "type": "object" }, "name": "get_access_point_roster_mix", "outputSchema": null }, { "description": "Get a country's adoption aggregates\n\nPeppol adoption for one country as one bare object: headline totals (universe, on_peppol, penetration), the single-dimension cuts (sector with a NACE Rev. 2.1 section rollup (A–V), region, FR-only département + size class, BE-only province + postcode + mandate scope, legal-form family, and company age), the same categorical cuts cross-tabbed by company-age band (`cuts_by_age`), and the trend (monthly new adopters plus per-run penetration history). Region cells carry ISO 3166-2 (BE) / INSEE région (FR) codes and sector cells the NACE Rev. 2.1 division code, so the choropleth joins geometry with no string matching. Numerator cells below 10 matched companies are suppressed (`on_peppol`/`penetration` null, `suppressed` true); denominators are never suppressed. Cached for a day (data moves monthly).", "inputSchema": { "properties": { "country": { "description": "Country code — `be`, `fr`, `sk`, `no`, `se`, `fi` or `si`.", "enum": [ "be", "fr", "sk", "no", "se", "fi", "si" ], "type": "string" } }, "required": [ "country" ], "type": "object" }, "name": "get_adoption", "outputSchema": null }, { "description": "Get an anomaly\n\nOne anomaly by its stable content-derived key.", "inputSchema": { "properties": { "id": { "description": "The stable anomaly key.", "type": "string" } }, "required": [ "id" ], "type": "object" }, "name": "get_anomaly", "outputSchema": null }, { "description": "Network compliance landscape\n\nThe free compliance landscape (issue #692): per-country error rates — the share of a country's registered participants that break at least one published Peppol rule — and the per-rule breakdown of every open finding. Counts ONLY: no participant, seat or hostname appears here; the participant-level records are `GET /v1/compliance/findings` (Network tier). Read from the pre-computed compliance rollup tables and edge-cached. Keyless-cacheable.\n\nPass `country` to scope the whole body to one country (issue #716): the same shape, with `countries` holding that one cell, `rules` its own breakdown, each rule's `share` a share of THAT country's open findings, and the code echoed back in `country`. A country scope is how a structural national pattern is told apart from a real problem — AU and NZ, for example, break `not_in_peppol_directory` almost everywhere because A-NZ PINT participants are absent from the European Peppol Directory by design.", "inputSchema": { "properties": { "country": { "description": "Scope the landscape to one ISO 3166-1 alpha-2 country (or `ZZ`, the bucket for findings whose subject resolves to no country). A country the rollup has not seen returns an empty landscape, not an error.", "pattern": "^[A-Za-z]{2}$", "type": "string" } }, "type": "object" }, "name": "get_compliance_stats", "outputSchema": null }, { "description": "Network compliance trend\n\nThe network compliance picture over time: one point per UTC day the rollup ran, carrying that day's participant denominator, affected participants, error rate and open findings by grade. The series starts the day the rollup first ran. Keyless-cacheable.\n\nPass `country` for one country's trend (issue #716) — the same series shape, restricted to that country and echoed back in `country`. The per-country series starts the day the country rollup first ran, which is later than the network one.", "inputSchema": { "properties": { "country": { "description": "Scope the trend to one ISO 3166-1 alpha-2 country (or `ZZ`). A country the rollup has not seen returns an empty series, not an error.", "pattern": "^[A-Za-z]{2}$", "type": "string" }, "from": { "description": "Inclusive lower bound (YYYY-MM-DD UTC). Defaults to 90 days ago.", "format": "date", "type": "string" }, "to": { "description": "Inclusive upper bound (YYYY-MM-DD UTC). Defaults to today.", "format": "date", "type": "string" } }, "type": "object" }, "name": "get_compliance_stats_history", "outputSchema": null }, { "description": "Per-country participant churn\n\nNew (joiner) vs departed (leaver) participants for one country, as a daily series and an all-time monthly rollup, from the hourly churn rollup. A valid but unknown country returns empty arrays. Keyless-cacheable.", "inputSchema": { "properties": { "code": { "description": "Two-letter country code (ISO 3166-1 alpha-2), case-insensitive.", "pattern": "^[A-Za-z]{2}$", "type": "string" }, "from": { "description": "Inclusive lower bound of the daily series (YYYY-MM-DD UTC). Defaults to 30 days ago.", "format": "date", "type": "string" }, "to": { "description": "Inclusive upper bound of the daily series (YYYY-MM-DD UTC). Defaults to today.", "format": "date", "type": "string" } }, "required": [ "code" ], "type": "object" }, "name": "get_country_churn", "outputSchema": null }, { "description": "Providers serving a country\n\nThe Access Points serving one country, ranked two ways from the hourly rollup: `providers` by participant (Peppol-ID) count, and `providers_by_company` by the number of DISTINCT organizations (real businesses) each serves (issue #467). Each row's `key` is the `/v1/aps/{key}` handle and `share` is that provider's fraction of the country's AP-served total for its metric. `company_coverage` (0..1) is how much ID→organization dedup the market shows — ~0 (and `providers_by_company` empty) for markets without register enrichment, meaningfully positive for BE/FR. A valid but unknown country returns empty lists. Keyless-cacheable.", "inputSchema": { "properties": { "code": { "description": "Two-letter country code (ISO 3166-1 alpha-2), case-insensitive.", "pattern": "^[A-Za-z]{2}$", "type": "string" } }, "required": [ "code" ], "type": "object" }, "name": "get_country_providers", "outputSchema": null }, { "description": "Doctypes within a family\n\nThe concrete document types within one family (issue #647): each doctype's local name, version, participant count, and share of the family. An unknown family returns an empty `doctypes` array. Keyless-cacheable.", "inputSchema": { "properties": { "family": { "description": "The doctype family name (e.g. `Invoice`, `Order`, `Credit Note`).", "type": "string" } }, "required": [ "family" ], "type": "object" }, "name": "get_doctype_family", "outputSchema": null }, { "description": "A family's receivers by country\n\nOne document family's receiving participants sliced by ISO-3166 alpha-2 country (issue #652), each with its share of the family total. The country is derived from the participant identifier's ICD; unresolved identifiers bucket as `ZZ`. An unknown family returns an empty `countries` array. Keyless-cacheable.", "inputSchema": { "properties": { "family": { "description": "The doctype family name (e.g. `Invoice`, `Order`, `Credit Note`).", "type": "string" } }, "required": [ "family" ], "type": "object" }, "name": "get_doctype_family_countries", "outputSchema": null }, { "description": "A family's receivers by provider\n\nOne document family's receiving participants sliced by hosting provider (issue #652), attributed via the SMP-hosted footprint (the participant's current SMP host mapped to a provider), each with its share of the family total. Participants whose SMP host maps to no known provider are omitted. An unknown family returns an empty `providers` array. Keyless-cacheable.", "inputSchema": { "properties": { "family": { "description": "The doctype family name (e.g. `Invoice`, `Order`, `Credit Note`).", "type": "string" } }, "required": [ "family" ], "type": "object" }, "name": "get_doctype_family_providers", "outputSchema": null }, { "description": "Document-type landscape\n\nThe free document-type landscape (issue #647): per-family participant share (Invoice, Order, Credit Note, …), the wildcard-doctype bucket, and the participant denominator. Read from the pre-computed doctype rollup tables and edge-cached. Keyless-cacheable.", "inputSchema": { "properties": {}, "type": "object" }, "name": "get_doctype_stats", "outputSchema": null }, { "description": "Document-type landscape history\n\nThe document-type landscape over time: per UTC day, the participant count for each family, from the doctype history rollup. Keyless-cacheable.", "inputSchema": { "properties": { "from": { "description": "Inclusive lower bound (YYYY-MM-DD UTC). Defaults to 90 days ago.", "format": "date", "type": "string" }, "to": { "description": "Inclusive upper bound (YYYY-MM-DD UTC). Defaults to today.", "format": "date", "type": "string" } }, "type": "object" }, "name": "get_doctype_stats_history", "outputSchema": null }, { "description": "Get a host's current state\n\nCurrent role, verdict, network attribution (IPs/PTR), TLS certificate and operating provider for a host. `?at=` returns point-in-time state. `profile` carries the crawled software identity of the host's registrable domain when one is publishable (curated, or extraction confidence 0.8+ — then unverified).", "inputSchema": { "properties": { "at": { "description": "Point-in-time ISO 8601 instant; omitted returns current state.", "format": "date-time", "type": "string" }, "hostname": { "description": "The host's fully-qualified hostname.", "type": "string" } }, "required": [ "hostname" ], "type": "object" }, "name": "get_host", "outputSchema": null }, { "description": "Get a host's uptime aggregates\n\nThe aggregate ladder for a host at a chosen resolution, per-location plus the `__all__` rollup, optionally windowed by `[from, to)`, cursor-paginated.", "inputSchema": { "properties": { "cursor": { "description": "Opaque pagination cursor returned as `next_cursor` by the previous page.", "type": "string" }, "from": { "description": "Inclusive lower bound (ISO 8601). Must not be after `to`.", "format": "date-time", "type": "string" }, "hostname": { "description": "The host's fully-qualified hostname.", "type": "string" }, "limit": { "default": 50, "description": "Page size, clamped to [1, 200]. Defaults to 50.", "maximum": 200, "minimum": 1, "type": "integer" }, "location": { "description": "Restrict to one probe location, or `__all__` for the rollup.", "type": "string" }, "resolution": { "default": "hourly", "description": "Aggregate tier. Defaults to hourly.", "enum": [ "hourly", "daily", "monthly" ], "type": "string" }, "to": { "description": "Exclusive upper bound (ISO 8601).", "format": "date-time", "type": "string" } }, "required": [ "hostname" ], "type": "object" }, "name": "get_host_uptime", "outputSchema": null }, { "description": "Peppol ID quality summary\n\nPer-scheme (ICD) summary of the structural identifier checks: how many participants were checked, how many failed their scheme's rule, and the resulting violation rate. Ordered by violation count, busiest first.", "inputSchema": { "properties": {}, "type": "object" }, "name": "get_id_quality", "outputSchema": null }, { "description": "Hosting rollup for malformed identifiers\n\nWhich Access Points and SMPs serve the malformed identifiers, honouring the same `scheme`/`reason`/`q` filters as the malformed list. Access points and SMPs are ranked by malformed-id count; `totals` covers the filtered set.", "inputSchema": { "properties": { "q": { "description": "Case-insensitive substring match on the identifier value.", "type": "string" }, "reason": { "description": "Filter by the kind of structural failure.", "enum": [ "length", "charset", "check-digit" ], "type": "string" }, "scheme": { "description": "Filter to one Peppol ICD scheme (e.g. `0208`).", "type": "string" }, "smp": { "description": "Filter to malformed ids homed on one SMP hostname.", "type": "string" } }, "type": "object" }, "name": "get_id_quality_hosting", "outputSchema": null }, { "description": "Get the network verdict history\n\nThe host verdict mix over time, derived from the temporal verdict table in one windowed pass: per UTC day, the rows open at 00:00 that day, counted by verdict. Two caveats. Counts are (hostname, role) pairs — a host serving two roles counts twice, the same grain as `/v1/network`. And before 2026-08-15 an unresolvable host was recorded as `down`, so `unresolvable` reads 0 over the earlier stretch. The series starts 2026-07-21, the first day the table covers; an earlier `from` is clamped to it. Keyless-cacheable.", "inputSchema": { "properties": { "from": { "description": "Inclusive lower bound (YYYY-MM-DD UTC). Defaults to 90 days ago; clamped to 2026-07-21.", "format": "date", "type": "string" }, "to": { "description": "Inclusive upper bound (YYYY-MM-DD UTC). Defaults to today.", "format": "date", "type": "string" } }, "type": "object" }, "name": "get_network_history", "outputSchema": null }, { "description": "Get the network-level statistics\n\nHow the whole network moves: Movers (AP) and Movers (SMP), Cross-border moves, Bulk moves, Joiners, Leavers and Net growth, the Leaver rate (annualized), Concentration (AP) and Concentration (SMP) (HHI, top 5, top 10), Foreign-served participants and penetration. Each flow statistic gives its count over the last 7 and 30 days, the 7-day mean and the change against the period before.\n\nEvery rate is of the registered-participant count at the START of its period (`base`, the end of `base_day`) and is returned beside its absolute count. A day with no completed change scan is a gap: `gap_days` counts them, and moves found after a gap are counted on the next scan day. A 7-day mean is the mean over the scanned days of its window; a gap day is in neither the sum nor the divisor, and a window of gap days only has no mean (null). The series starts 2026-08-02; a window that would open earlier is clamped to it. `as_of` is the last complete UTC day and every flow period ends there. Concentration, Foreign-served participants and penetration are snapshots: each is the latest stored value and carries its own `day`, which can be one day after `as_of`.\n\nThe headline numbers are free. The organic/bulk split, the cross-border split, the bulk share, penetration and the 30-day trends are returned for a Market key only (see `x-required-tier` on the fields); the body is private to the caller.", "inputSchema": { "properties": {}, "type": "object" }, "name": "get_network_stats", "outputSchema": null }, { "description": "Get one network-level statistic as a daily series\n\nOne point for every UTC day of the window. `stat` is required. A flow statistic (`ap_switching` = Movers (AP), `cross_border` = Cross-border moves, `smp_switching` = Movers (SMP), `growth` = Net growth with Joiners and Leavers) carries per day its counts (`values`), the registered-participant count at the start of the day (`base`), the first key as a percentage of that base (`pct`) and its 7-day mean (`mean_7d`). For `cross_border`, `base` is all AP moves of the day and `pct` is the cross-border share of them. A day with no completed change scan has `gap: true` and `values: null` — a gap is never 0. The 7-day mean is the mean over the scanned days of `day − 6 .. day`: a gap day is in neither the sum nor the divisor, and the mean is null when all are gaps. It is the same figure as `trend_30d` of `/v1/network/stats`. For `growth`, a gap day keeps `joiners` and nulls `leavers` and `net`. A stock statistic (`concentration_ap` = Concentration (AP), `concentration_smp` = Concentration (SMP), `foreign_served` = Foreign-served participants, `penetration`) carries `values`, null on a day with no snapshot; `foreign_served` also carries `base`, the registered participants of that day. `concentration_ap`, `foreign_served` and `penetration` have no history before their first snapshot. The series starts 2026-08-02.", "inputSchema": { "properties": { "from": { "description": "Inclusive lower bound (YYYY-MM-DD UTC). Defaults to 90 days ago; clamped to 2026-08-02.", "format": "date", "type": "string" }, "stat": { "description": "REQUIRED. The statistic to return: `ap_switching` (keys total, organic, bulk), `cross_border` (cross, same, unknown, strict_cross, strict_unknown), `smp_switching` (total), `growth` (net, joiners, leavers), `concentration_ap` / `concentration_smp` (cr5_pct, cr10_pct, hhi, total, providers), `foreign_served` (pct, foreign, domestic, unknown) or `penetration` (per country: pct, on_peppol, universe).", "enum": [ "ap_switching", "cross_border", "smp_switching", "growth", "concentration_ap", "concentration_smp", "foreign_served", "penetration" ], "type": "string" }, "to": { "description": "Inclusive upper bound (YYYY-MM-DD UTC). Defaults to yesterday, the last complete day.", "format": "date", "type": "string" } }, "type": "object" }, "name": "get_network_stats_history", "outputSchema": null }, { "description": "Get the network summary\n\nCurrent host verdict counts, open incidents and anomalies in the last 24h, plus how fresh the Peppol Directory export behind every other endpoint is.", "inputSchema": { "properties": {}, "type": "object" }, "name": "get_network_summary", "outputSchema": null }, { "description": "Get a participant's current state\n\nDirectory presence, SML registration + current SMP, business card, the company-register enrichment block, endpoints and serving seats for a Peppol participant. Discovered participants carry no card; unmatched participants carry company: null.", "inputSchema": { "properties": { "id": { "description": "Canonical `scheme::value` Peppol identifier (e.g. `0208::0762747721`).", "type": "string" } }, "required": [ "id" ], "type": "object" }, "name": "get_participant", "outputSchema": null }, { "description": "Get a participant's measured availability\n\nThe real, probe-measured reachability of one Peppol ID over time. Two lanes — the participant's SMP host (discovery) and its Access Point host(s) (delivery) — are read from the uptime ladder and merged per bucket into one verdict (available | degraded | unreachable | no_data): an AP with any down check is unreachable; an AP up/degraded with the SMP down is degraded (discovery impaired, still deliverable); both lanes up is available. Returns per-lane `UptimeBucket` ladders, the worst-of combined lane, 30/90-day + full headline uptime (degraded counts as available), a monthly 99.5% Peppol AP service-level TARGET (never a contractual claim), host-change markers and window-overlapping incidents. `daily` spans the full history; `hourly` covers the last 90 days. Buckets before the 2026-08-02 AP epoch carry partial AP attribution (`pre_epoch`).", "inputSchema": { "properties": { "from": { "description": "Inclusive lower bound (ISO 8601). Must not be after `to`.", "format": "date-time", "type": "string" }, "id": { "description": "Canonical `scheme::value` Peppol identifier (e.g. `0208::0762747721`).", "type": "string" }, "resolution": { "default": "daily", "description": "Aggregate tier. `daily` spans the full history; `hourly` the last 90 days.", "enum": [ "daily", "hourly" ], "type": "string" }, "to": { "description": "Exclusive upper bound (ISO 8601). Defaults to now.", "format": "date-time", "type": "string" } }, "required": [ "id" ], "type": "object" }, "name": "get_participant_availability", "outputSchema": null }, { "description": "List a participant's temporal history\n\nThe participant's temporal rows across the directory/card/registration/SMP fact families, newest-first, cursor-paginated.", "inputSchema": { "properties": { "cursor": { "description": "Opaque pagination cursor returned as `next_cursor` by the previous page.", "type": "string" }, "id": { "description": "Canonical `scheme::value` Peppol identifier.", "type": "string" }, "limit": { "default": 50, "description": "Page size, clamped to [1, 200]. Defaults to 50.", "maximum": 200, "minimum": 1, "type": "integer" } }, "required": [ "id" ], "type": "object" }, "name": "get_participant_history", "outputSchema": null }, { "description": "Network joiners curve\n\nThe real onboarding curve (issue #222): joiner counts bucketed by derived network join date (business-card RegistrationDate, else genuine first-seen), with a whole-network coverage split (registration_date / first_seen / unknown). The unknown/seed tail is reported in `coverage` only, never folded into a bucket. Keyless-cacheable.", "inputSchema": { "properties": { "bucket": { "default": "year", "description": "Bucket granularity. Defaults to `year`.", "enum": [ "year", "month" ], "type": "string" } }, "type": "object" }, "name": "get_participant_joiners", "outputSchema": null }, { "description": "Participant facet stats\n\nGlobal participant facet counts (per country/scheme/smp/ap/doctype/transport_profile, registered share, provenance split) plus an estimated total, from the hourly rollup. `total_count` counts every ID ever registered; `registered_count` and the `country_registered` facet scope the same data to the LIVE (registered) IDs (issue #818). Keyless-cacheable — safe for the marketing site to hit directly.", "inputSchema": { "properties": {}, "type": "object" }, "name": "get_participant_stats", "outputSchema": null }, { "description": "Participant facet history\n\nA daily time series over one participant facet dimension (adoption curves / QoQ trends), from daily snapshots of the rollup. History accrues from the day the feature shipped. Keyless-cacheable.", "inputSchema": { "properties": { "dimension": { "description": "Which series to return: `total` (whole-network count) or a facet dimension.", "enum": [ "total", "country", "scheme", "registered", "provenance", "smp", "ap", "doctype", "transport_profile", "entity_type", "sector", "size", "region", "vat_liable", "unique_organizations" ], "type": "string" }, "from": { "description": "Inclusive lower bound (YYYY-MM-DD UTC). Defaults to 90 days ago.", "format": "date", "type": "string" }, "key": { "description": "Comma-separated facet keys to filter to (e.g. `BE,NL` for `dimension=country`). Omit for every key in the dimension.", "items": { "type": "string" }, "type": "array" }, "limit": { "default": 10000, "description": "Max points returned, clamped to [1, 10000]. Defaults to 10000.", "maximum": 10000, "minimum": 1, "type": "integer" }, "to": { "description": "Inclusive upper bound (YYYY-MM-DD UTC). Defaults to today.", "format": "date", "type": "string" } }, "required": [ "dimension" ], "type": "object" }, "name": "get_participant_stats_history", "outputSchema": null }, { "description": "Get a filtered participant breakdown\n\nThe participant set broken down by country, entity type, NACE Rev. 2.1 division, size class, region and serving Access Point, over a FILTERED slice — so a breakdown stays true while the list is cut down. The filters are the same names and shapes as `GET /v1/participants`.\n\nTWO SOURCES, one shape, named by `source`. A request that narrows on NOTHING is answered from the hourly rollup (`source: \"rollup\"`, with `refreshed_at`) — the whole-network breakdown, no scan. A request that narrows is computed live (`source: \"slice\"`).\n\nBOUNDED BY DESIGN. A live slice is computed only while it is narrow (under an internal cap of 10,000 participants). A slice wider than the cap, or a request carrying a filter this endpoint cannot express (`doctype`, `transport_profile`, `q`, `host`, `sub_provider`), answers `degraded: true` with every mix null — never a wrong number and never an error. Callers fall back to the whole-network breakdown on `GET /v1/stats/participants`.\n\nCounts are sparse the same way the rollup facets are: company enrichment covers a handful of registers, so every mix except `country_mix` sums BELOW `participant_count` and the un-enriched remainder is derived from the total rather than served as a bucket. `ap_mix` names the busiest Access Point Seats and folds the rest into one `__other__` bucket.", "inputSchema": { "properties": { "ap": { "description": "Comma-array of serving Access Point SeatIDs (`PBE000123,PNO000456`).", "items": { "type": "string" }, "type": "array" }, "country": { "description": "Comma-array of ISO-3166-1 alpha-2 country codes. Matched on the participant's card country, falling back to the country its ICD prefix implies — the same rule `country_mix` buckets on.", "items": { "type": "string" }, "type": "array" }, "entity_type": { "description": "Comma-array of company legal-form families (`company`,`natural_person`,`association`,`public`), from the company-register enrichment denormalized onto the participant.", "items": { "type": "string" }, "type": "array" }, "not_country": { "description": "Comma-array of country codes (`NO,SE`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_entity_type": { "description": "Comma-array of company legal-form families (`company`,`natural_person`,`association`,`public`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_region": { "description": "Comma-array of company seat region codes (`NO-32,BE-BRU`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_sector": { "description": "Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_size": { "description": "Comma-array of company size classes (as stored; SIRENE only) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_smp": { "description": "Comma-array of SMP hostnames to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "postcode": { "description": "Comma-array of company seat postcodes.", "items": { "type": "string" }, "type": "array" }, "provenance": { "description": "Comma-array of provenance values.", "items": { "enum": [ "directory", "discovered" ], "type": "string" }, "type": "array" }, "region": { "description": "Comma-array of company seat region codes (`BE-BRU,BE-VLG`).", "items": { "type": "string" }, "type": "array" }, "registered": { "description": "Filter by current SML registration state.", "type": "boolean" }, "scheme": { "description": "Comma-array of Peppol identifier schemes.", "items": { "type": "string" }, "type": "array" }, "sector": { "description": "Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`).", "items": { "type": "string" }, "type": "array" }, "size": { "description": "Comma-array of company size classes (as stored; SIRENE only).", "items": { "type": "string" }, "type": "array" }, "smp": { "description": "Comma-array of current SMP hostnames (`smp1.example,smp2.example`).", "items": { "type": "string" }, "type": "array" }, "vat_liable": { "description": "Filter by company VAT-liable / mandate-scope flag.", "type": "boolean" } }, "type": "object" }, "name": "get_participants_mix", "outputSchema": null }, { "description": "Get a curated provider\n\nA curated provider navigable to its seats and each seat's observed hosts.", "inputSchema": { "properties": { "slug": { "description": "The curated provider slug.", "type": "string" } }, "required": [ "slug" ], "type": "object" }, "name": "get_provider", "outputSchema": null }, { "description": "List provider SLA scorecards\n\nPer-provider SLA scorecards for one trailing period: checks-weighted uptime across each provider's mapped hosts, incident count, total downtime minutes and the single worst host. Ordered worst uptime first (providers with no checks in the window last). Materialized hourly by the batch runner. Not paginated (the envelope's `next_cursor` is always null).", "inputSchema": { "properties": { "period": { "default": "30d", "description": "Trailing window: `30d` (default) or `90d`.", "enum": [ "30d", "90d" ], "type": "string" } }, "type": "object" }, "name": "get_provider_sla", "outputSchema": null }, { "description": "Get a provider's SLA scorecards\n\nOne provider's SLA scorecards, one per trailing period (30d and 90d). `key` is the provider's natural key (as reported by `GET /v1/providers`). Empty `items` when the provider has no SLA data yet.", "inputSchema": { "properties": { "key": { "description": "The provider natural key.", "type": "string" } }, "required": [ "key" ], "type": "object" }, "name": "get_provider_sla_by_key", "outputSchema": null }, { "description": "Get a public provider profile\n\nThe FREE, crawlable public subset for one curated provider (same shape as a `GET /v1/providers/public` item). Reachable with no API key.", "inputSchema": { "properties": { "slug": { "description": "The curated provider slug.", "type": "string" } }, "required": [ "slug" ], "type": "object" }, "name": "get_public_provider", "outputSchema": null }, { "description": "Get a seat\n\nA Peppol certificate seat: its embedded provider (verified mapping or unverified cert-CN fallback) and the hosts it was observed operating.", "inputSchema": { "properties": { "seatId": { "description": "The seat identifier (e.g. `POP000748`).", "type": "string" } }, "required": [ "seatId" ], "type": "object" }, "name": "get_seat", "outputSchema": null }, { "description": "Get a seat's compliance scorecard\n\nOne seat's compliance posture: the registrations under it, its OPEN findings broken down by rule, the daily trend, and where the seat sits against the network. This is what a Peppol Authority's periodic scan reports, from the same published rules (`GET /v1/compliance/rules`), before the letter arrives.\n\nRates are open findings per 1,000 registrations, and `null` when the seat hosts no registrations. The network median and 90th percentile are taken over every seat that hosts registrations — a seat with no finding of a rule counts as 0 — so they describe the whole network, not only the seats that break the rule.\n\nRead from a daily rollup: `snapshot_date` is the day it describes, and is `null` (with zero counts and empty lists) for a seat no scan has covered yet.", "inputSchema": { "properties": { "days": { "default": 90, "description": "How many daily snapshots the trend covers (default 90).", "maximum": 365, "minimum": 1, "type": "integer" }, "seatId": { "description": "The seat identifier (e.g. `POP000748`).", "type": "string" } }, "required": [ "seatId" ], "type": "object" }, "name": "get_seat_compliance", "outputSchema": null }, { "description": "Get a seat's SLA scorecards\n\nOne seat's SLA scorecards, one per trailing period (30d and 90d). `seatId` is the seat identifier (as reported by `GET /v1/aps/{key}` on `seats[].seat_id`). Empty `items` when the seat has no SLA data yet.", "inputSchema": { "properties": { "seatId": { "description": "The seat identifier (e.g. `POP000748`).", "type": "string" } }, "required": [ "seatId" ], "type": "object" }, "name": "get_seat_sla", "outputSchema": null }, { "description": "Get SML/SMK zone status\n\nOne entry per monitored zone: quorum verdict, per-location canary breakdown, DNAME cutover state, management-host TLS snapshot and zone incidents.", "inputSchema": { "properties": {}, "type": "object" }, "name": "get_sml_status", "outputSchema": null }, { "description": "Get one software product (Market)\n\nOne engine of the software library: the same row the list returns (product metadata, host count per observed role, first/last seen, the compliance signal and the host-count trend) plus the catalogue version and generation stamp. `engine` is a catalogue engine slug as published in `engine` on the list; an unknown slug is a 404.\n\nBeyond the list row it also returns `advisory_list[]` (issue #798): every live advisory of the engine's lanes with its id, normalized severity, CVSS score, summary, url and publication stamp, newest first. Null when no lane of the engine has an advisory feed; `[]` when it has one and upstream has published nothing. Market tier.", "inputSchema": { "properties": { "days": { "default": 90, "description": "Trend window in trailing UTC days, 1..90 (default 90).", "maximum": 90, "minimum": 1, "type": "integer" }, "engine": { "description": "The catalogue engine slug, e.g. `phoss`.", "type": "string" } }, "required": [ "engine" ], "type": "object" }, "name": "get_software", "outputSchema": null }, { "description": "Software landscape\n\nThe free host-software landscape (issue #490): k-anonymised vendor share (k=5, the sub-k tail folded into `other`), version distribution within each named vendor (k=10), ASN hosting share, and a two-denominator coverage block (host-weighted ~90% and participant-weighted ~50%, each named, no bare coverage scalar). Computed live from the temporal software table and edge-cached. Names no operator. Keyless-cacheable.", "inputSchema": { "properties": {}, "type": "object" }, "name": "get_software_stats", "outputSchema": null }, { "description": "Software landscape history\n\nThe software landscape over time, derived from the temporal software table in one windowed pass: per UTC day, the host-weighted identified/total targets and the k-anonymised vendor shares. Keyless-cacheable.", "inputSchema": { "properties": { "from": { "description": "Inclusive lower bound (YYYY-MM-DD UTC). Defaults to 90 days ago.", "format": "date", "type": "string" }, "to": { "description": "Inclusive upper bound (YYYY-MM-DD UTC). Defaults to today.", "format": "date", "type": "string" } }, "type": "object" }, "name": "get_software_stats_history", "outputSchema": null }, { "description": "Get the public dashboard summary\n\nThe free marketing-dashboard rollup: the network-wide host rollup (fleet count + mean uptime/latency), the hourly fleet-average p50 latency trend over the last 24h, and the top-10 providers by market share (0..1 fraction). No host list, full registry or arbitrary per-host uptime is exposed.", "inputSchema": { "properties": {}, "type": "object" }, "name": "get_summary", "outputSchema": null }, { "description": "List participants behind a churn category\n\nThe drill-down: the participant IDs behind one churn category count for this Provider over the period. Bounded to 500 rows (never paginated; next_cursor null).", "inputSchema": { "properties": { "category": { "description": "The churn category to expand.", "enum": [ "joiner", "mover_in", "mover_out", "leaver" ], "type": "string" }, "from": { "description": "Inclusive period start, `YYYY-MM-DD` UTC.", "format": "date", "type": "string" }, "key": { "description": "The Provider key.", "type": "string" }, "to": { "description": "Inclusive period end, `YYYY-MM-DD` UTC.", "format": "date", "type": "string" } }, "required": [ "key", "category" ], "type": "object" }, "name": "list_access_point_churn_participants", "outputSchema": null }, { "description": "List access points\n\nThe Access Point directory: every Provider in its serving role, with its member seats and roster size (current participant count), busiest first. A Provider is resolved from each seat with the precedence curated mapping (verified) → exact signing-cert `O=` string (unverified) → bare SeatID. Not paginated (the envelope's `next_cursor` is always null). Pass `?country=CC` to compare providers within one market instead of network-wide. Every item carries the windowed net growth; a MARKET-tier key additionally gets the four churn components behind each net (`joiners`, `movers_in`, `movers_out`, `leavers` × 7d/30d/90d), which a lower-tier key simply does not receive.", "inputSchema": { "properties": { "country": { "description": "Scope the returned figures to one market: an ISO 3166-1 alpha-2 code (e.g. `BE`), case-insensitive. Anything that is not exactly two letters is a 400. When set, every item additionally carries `country_roster`, `country_orgs` and `country_net_7d|30d|90d`; the network-wide fields are unchanged. A MARKET-tier key additionally gets the scoped churn components `country_joiners|movers_in|movers_out|leavers_7d|30d|90d`.", "pattern": "^[A-Za-z]{2}$", "type": "string" } }, "type": "object" }, "name": "list_access_points", "outputSchema": null }, { "description": "List anomalies\n\nThe anomaly feed, newest-first, cursor-paginated.", "inputSchema": { "properties": { "acknowledged": { "description": "Filter by acknowledgement state.", "type": "boolean" }, "cursor": { "description": "Opaque pagination cursor returned as `next_cursor` by the previous page.", "type": "string" }, "detector": { "description": "Filter by detector.", "enum": [ "cert_identity_shift", "off_cadence_rotation", "endpoint_off_footprint", "moved_to_unverified_seat", "mass_change_burst", "split_id_registration", "host_tls_cert_expired", "host_tls_cert_expiring" ], "type": "string" }, "grade": { "description": "Filter by grade.", "enum": [ "notice", "warning", "info" ], "type": "string" }, "host": { "description": "Filter to anomalies targeting one host.", "type": "string" }, "limit": { "default": 50, "description": "Page size, clamped to [1, 200]. Defaults to 50.", "maximum": 200, "minimum": 1, "type": "integer" }, "seat": { "description": "Filter to anomalies targeting one seat.", "type": "string" }, "since": { "description": "Only include items at or after this ISO 8601 instant.", "format": "date-time", "type": "string" } }, "type": "object" }, "name": "list_anomalies", "outputSchema": null }, { "description": "List participants in a bulk AP migration\n\nThe drill-down: the participant IDs behind one cohort, oldest observation day first. A cohort's membership is DEFINED as the mover events its provider pair and day range select, so this list is always in step with the cohort's counts. Cursor-paginated on (day, value).\n\n`id` is the request-lifetime handle from `GET /v1/stats/cohort-moves`. The detector re-clusters the trailing window on every run, so a handle whose cohort boundaries have since shifted answers 404 rather than a stale list — re-read the feed instead of persisting ids.", "inputSchema": { "properties": { "cursor": { "description": "Opaque pagination cursor returned as `next_cursor` by the previous page.", "type": "string" }, "id": { "description": "The cohort handle: 16 lowercase hex characters.", "pattern": "^[0-9a-f]{16}$", "type": "string" }, "limit": { "default": 50, "description": "Page size, clamped to [1, 200]. Defaults to 50.", "maximum": 200, "minimum": 1, "type": "integer" } }, "required": [ "id" ], "type": "object" }, "name": "list_cohort_move_participants", "outputSchema": null }, { "description": "List bulk AP migrations\n\nDetected bulk migrations between Access Points, largest first. A cohort is a gap-≤3-day island of (from_provider, to_provider) mover days that clears three thresholds: at least 25 participants, at least 40 % of them on the busiest day (which rejects a steady drip), and at most 20 active days for the pair over the trailing 40 days (which rejects a recurring partnership).\n\nEvery day is the PROBE-OBSERVATION day — the day the change scan saw the SMP record change, not the day the migration was executed — so a cohort is always a `[first_day, last_day]` range and `peak_day` is the busiest observation day. Render the range, never a single date.\n\n`top_country` is derived from the ICD prefix of the participant identifiers, not from business-card country fields. `merge_suspect` marks a cohort large enough (or whose source provider no longer resolves in the directory) to be a provider merge or a renamed provider rather than that many independent customer decisions — the canonical case is Sovos → Sage, 10,574 participants. Such rows are data events, not customer decisions; verify one before quoting it. The flag is a CURRENT judgment, re-evaluated on every recompute, not frozen at detection.\n\n`from`/`to` are OVERLAP bounds (a cohort counts when its range intersects the window), defaulting to the trailing 90 days the detector re-clusters. Mover history begins 2026-07-24, so no cohort predates it. `id` is a request-lifetime handle for the participant drill-down — never persist one.", "inputSchema": { "properties": { "cursor": { "description": "Opaque pagination cursor returned as `next_cursor` by the previous page.", "type": "string" }, "direction": { "default": "both", "description": "Which side of the `provider` filter to take: `in` = cohorts the provider received, `out` = cohorts it lost, `both` = either. Only meaningful together with `provider`.", "enum": [ "in", "out", "both" ], "type": "string" }, "from": { "description": "Inclusive lower bound of the observation window (`YYYY-MM-DD` UTC); a cohort matches when its `last_day` is at or after it. Defaults to 90 days ago.", "format": "date", "type": "string" }, "limit": { "default": 50, "description": "Page size, clamped to [1, 200]. Defaults to 50.", "maximum": 200, "minimum": 1, "type": "integer" }, "merge_suspect": { "default": "include", "description": "How to treat probable provider merges / slug changes: `include` (default), `exclude` for real customer migrations only, or `only` to review the flagged rows.", "enum": [ "include", "exclude", "only" ], "type": "string" }, "min_participants": { "default": 25, "description": "Only cohorts with at least this many participants. The detector's own floor is 25, so a lower value cannot surface smaller groups.", "minimum": 1, "type": "integer" }, "provider": { "description": "Only cohorts involving this Provider key (`/v1/aps/{key}`). Matches EITHER side unless `direction` narrows it.", "type": "string" }, "to": { "description": "Inclusive upper bound of the observation window (`YYYY-MM-DD` UTC); a cohort matches when its `first_day` is at or before it. Defaults to today.", "format": "date", "type": "string" } }, "type": "object" }, "name": "list_cohort_moves", "outputSchema": null }, { "description": "List compliance findings\n\nDeterministic verdicts against the published rules, newest first and keyset-paginated on (`first_detected_at`, `finding_id`). A finding stays `open` until the registration is corrected, at which point the next scan stamps `resolved_at`; `first_detected_at` survives every re-scan. Distinct from `/v1/anomalies`, which reports observed behaviour rather than rule breaches. The first page's `meta.facets` gives rule and grade counts over the filtered set.", "inputSchema": { "properties": { "country": { "description": "Filter to one ISO 3166-1 alpha-2 country.", "type": "string" }, "cursor": { "description": "Opaque pagination cursor returned as `next_cursor` by the previous page.", "type": "string" }, "grade": { "description": "Filter by severity.", "enum": [ "fatal", "warning", "notice" ], "type": "string" }, "limit": { "default": 50, "description": "Page size, clamped to [1, 200]. Defaults to 50.", "maximum": 200, "minimum": 1, "type": "integer" }, "rule": { "description": "Filter to one rule code (from `GET /v1/compliance/rules`).", "type": "string" }, "scheme": { "description": "Filter to one participant scheme id, for participant-grain rules.", "type": "string" }, "seat": { "description": "Filter to one operating seat id (e.g. `PBE000123`).", "type": "string" }, "since": { "description": "Only findings whose `last_seen_at` or `resolved_at` is at or after this ISO 8601 instant: everything the latest scans still confirm, plus everything opened, changed or resolved since. A finding whose evidence has not moved for weeks stays in the answer for as long as its rule keeps being scanned, so polling this converges on the live set.", "format": "date-time", "type": "string" }, "status": { "default": "open", "description": "Lifecycle slice; defaults to the open findings.", "enum": [ "open", "resolved", "all" ], "type": "string" } }, "type": "object" }, "name": "list_compliance_findings", "outputSchema": null }, { "description": "List the compliance rule catalogue\n\nThe published rules registrations are judged against: what each rule requires, what it applies to, how severe a breach is, and how many findings requires, what it applies to, and how severe a breach is. Free — the rules themselves are public; the findings against them are on `GET /v1/compliance/findings`.", "inputSchema": { "properties": {}, "type": "object" }, "name": "list_compliance_rules", "outputSchema": null }, { "description": "List global change events\n\nEvery typed change event, newest-first, cursor-paginated. Any anomaly an event triggered is embedded on it. `cursor` walks older events; `prev_cursor` walks the newer edge (for live polling). The first page carries a `meta` block with exact type facets + filter count and an auto-bucketed timeline chart.", "inputSchema": { "properties": { "cursor": { "description": "Opaque pagination cursor returned as `next_cursor` by the previous page.", "type": "string" }, "doctype": { "description": "Filter to events touching one document-type URN. Matches both payload shapes: the merged `endpoint_changed` `doctypes` array and the legacy singular `doctype` on pre-merge rows.", "type": "string" }, "host": { "description": "Filter to events for one host.", "type": "string" }, "limit": { "default": 50, "description": "Page size, clamped to [1, 200]. Defaults to 50.", "maximum": 200, "minimum": 1, "type": "integer" }, "participant": { "description": "Filter to one participant (`scheme::value`).", "type": "string" }, "prev_cursor": { "description": "Opaque newer-direction cursor (from a page's `prev_cursor`): returns events newer than it, newest-first. Mutually exclusive with `cursor`.", "type": "string" }, "seat": { "description": "Filter to events referencing one seat.", "type": "string" }, "since": { "description": "Only include items at or after this ISO 8601 instant.", "format": "date-time", "type": "string" }, "type": { "description": "Comma-array of change-event types (a single value is valid).", "items": { "enum": [ "participant_registered", "participant_deregistered", "participant_smp_changed", "endpoint_changed", "doctype_support_changed", "ap_seat_changed", "host_cert_rotated", "hosting_changed", "directory_card_changed" ], "type": "string" }, "type": "array" }, "until": { "description": "Only include events at or before this ISO 8601 instant.", "format": "date-time", "type": "string" } }, "type": "object" }, "name": "list_events", "outputSchema": null }, { "description": "List a host's incidents\n\nIncidents for one host, newest-first, cursor-paginated.", "inputSchema": { "properties": { "cursor": { "description": "Opaque pagination cursor returned as `next_cursor` by the previous page.", "type": "string" }, "hostname": { "description": "The host's fully-qualified hostname.", "type": "string" }, "limit": { "default": 50, "description": "Page size, clamped to [1, 200]. Defaults to 50.", "maximum": 200, "minimum": 1, "type": "integer" }, "since": { "description": "Only include items at or after this ISO 8601 instant.", "format": "date-time", "type": "string" }, "status": { "description": "Filter by incident lifecycle state.", "enum": [ "open", "closed" ], "type": "string" } }, "required": [ "hostname" ], "type": "object" }, "name": "list_host_incidents", "outputSchema": null }, { "description": "List monitored hosts\n\nEvery monitored host with its current verdict, latest hourly all-locations latency and 24h uptime, worst-first, plus a network-wide rollup.", "inputSchema": { "properties": {}, "type": "object" }, "name": "list_hosts", "outputSchema": null }, { "description": "List malformed participant identifiers\n\nThe individual identifiers that failed their scheme's structural rule, keyset-paginated on (scheme, value). The first page's `meta.facets` gives scheme and reason counts over the filtered set.", "inputSchema": { "properties": { "cursor": { "description": "Opaque pagination cursor returned as `next_cursor` by the previous page.", "type": "string" }, "limit": { "default": 50, "description": "Page size, clamped to [1, 200]. Defaults to 50.", "maximum": 200, "minimum": 1, "type": "integer" }, "q": { "description": "Case-insensitive substring match on the identifier value.", "type": "string" }, "reason": { "description": "Filter by the kind of structural failure.", "enum": [ "length", "charset", "check-digit" ], "type": "string" }, "scheme": { "description": "Filter to one Peppol ICD scheme (e.g. `0208`).", "type": "string" }, "smp": { "description": "Filter to malformed ids homed on one SMP hostname (from `meta.facets.smp`).", "type": "string" } }, "type": "object" }, "name": "list_id_quality_malformed", "outputSchema": null }, { "description": "List incidents\n\nThe global incident feed, newest-first, cursor-paginated.", "inputSchema": { "properties": { "cursor": { "description": "Opaque pagination cursor returned as `next_cursor` by the previous page.", "type": "string" }, "host": { "description": "Filter to one host's incidents.", "type": "string" }, "limit": { "default": 50, "description": "Page size, clamped to [1, 200]. Defaults to 50.", "maximum": 200, "minimum": 1, "type": "integer" }, "since": { "description": "Only include items at or after this ISO 8601 instant.", "format": "date-time", "type": "string" }, "status": { "description": "Filter by incident lifecycle state.", "enum": [ "open", "closed" ], "type": "string" } }, "type": "object" }, "name": "list_incidents", "outputSchema": null }, { "description": "List a participant's change events\n\nThe participant's typed change events, newest-first, cursor-paginated.", "inputSchema": { "properties": { "cursor": { "description": "Opaque pagination cursor returned as `next_cursor` by the previous page.", "type": "string" }, "id": { "description": "Canonical `scheme::value` Peppol identifier.", "type": "string" }, "limit": { "default": 50, "description": "Page size, clamped to [1, 200]. Defaults to 50.", "maximum": 200, "minimum": 1, "type": "integer" } }, "required": [ "id" ], "type": "object" }, "name": "list_participant_events", "outputSchema": null }, { "description": "List participants\n\nThe participant set, keyset-paginated. Default sort is first-seen newest-first. Comma-array filters (`country`, `scheme`, `smp`, `ap`, `doctype`, `transport_profile`, `host`, `provenance`, and the company-register cuts `entity_type`, `sector`, `size`, `region`, `postcode`), the single-valued `sub_provider` cut, `registered` + `vat_liable` booleans, and a smart `q` (a `scheme::value`/bare value hits the ID index; free text runs a trigram name-contains). First-page `meta` carries estimated totals and rollup facets; `meta.filter_count` is a bounded exact count that degrades to null (never an error) if it exceeds the query timeout. Discovered participants carry no name/card fields (privacy).", "inputSchema": { "properties": { "ap": { "description": "Comma-array of serving Access Point SeatIDs (`PBE000123,PNO000456`).", "items": { "type": "string" }, "type": "array" }, "country": { "description": "Comma-array of ISO country codes (`BE,NL`).", "items": { "type": "string" }, "type": "array" }, "cursor": { "description": "Opaque pagination cursor returned as `next_cursor` by the previous page.", "type": "string" }, "doctype": { "description": "Comma-array of Peppol document type ids. Matches a participant if ANY of its current endpoints declares one of the given doctypes. Used ALONE (no other filter) results are ordered by identifier and `sort` is ignored; combined with another filter the requested `sort` applies.", "items": { "type": "string" }, "type": "array" }, "entity_type": { "description": "Comma-array of company legal-form families (`company`,`natural_person`,`association`,`public`), from the company-register enrichment denormalized onto the participant.", "items": { "type": "string" }, "type": "array" }, "host": { "description": "Comma-array of endpoint-URL hostnames (`ap.example.com`). Matches a participant if ANY of its current endpoints publishes an endpoint URL on one of the given hosts — the exact participant set an Access Point host serves. Case-insensitive. Used ALONE (no other filter) results are ordered by identifier and `sort` is ignored; combined with another filter the requested `sort` applies.", "items": { "type": "string" }, "type": "array" }, "limit": { "default": 50, "description": "Page size, clamped to [1, 200]. Defaults to 50.", "maximum": 200, "minimum": 1, "type": "integer" }, "not_country": { "description": "Comma-array of country codes (`NO,SE`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_entity_type": { "description": "Comma-array of company legal-form families (`company`,`natural_person`,`association`,`public`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_region": { "description": "Comma-array of company seat region codes (`NO-32,BE-BRU`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_sector": { "description": "Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_size": { "description": "Comma-array of company size classes (as stored; SIRENE only) to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "not_smp": { "description": "Comma-array of SMP hostnames to EXCLUDE. Rows with no value are KEPT — excluding a value never drops the un-enriched remainder. Combines with its include twin: `?region=NO-03&not_region=NO-32` applies both.", "items": { "type": "string" }, "type": "array" }, "postcode": { "description": "Comma-array of company seat postcodes.", "items": { "type": "string" }, "type": "array" }, "provenance": { "description": "Comma-array of provenance values.", "items": { "enum": [ "directory", "discovered" ], "type": "string" }, "type": "array" }, "q": { "description": "Smart search: `scheme::value`/bare value → ID lookup; else name-contains.", "type": "string" }, "region": { "description": "Comma-array of company seat region codes (`BE-BRU,BE-VLG`).", "items": { "type": "string" }, "type": "array" }, "registered": { "description": "Filter by current SML registration state.", "type": "boolean" }, "scheme": { "description": "Comma-array of Peppol identifier schemes.", "items": { "type": "string" }, "type": "array" }, "sector": { "description": "Comma-array of 2-digit NACE Rev. 2.1 divisions (`47,62`).", "items": { "type": "string" }, "type": "array" }, "size": { "description": "Comma-array of company size classes (as stored; SIRENE only).", "items": { "type": "string" }, "type": "array" }, "smp": { "description": "Comma-array of current SMP hostnames (`smp1.example,smp2.example`).", "items": { "type": "string" }, "type": "array" }, "sort": { "default": "first_seen.desc", "description": "Sort + keyset key. `registered`, `entity_type` (the Type column) and `sector` (the Activity / NACE-division column) order over `(<col>, first_seen_at, id)`; the `entity_type`/`sector` views show only enriched (non-null) participants. It is IGNORED when `doctype`/`transport_profile`/`host` is set WITHOUT any other narrowing filter, and when `sub_provider` is set without `q` or one of those endpoint filters — those results are driven from the matching index and ordered by identifier (`scheme`, `value`), the only ordering that stays inside the query timeout. Otherwise (an endpoint filter combined with `country`/`smp`/`ap`/`registered`/`provenance`/`q`, or `sub_provider` with `q`) the normal sort applies.", "enum": [ "first_seen.desc", "first_seen.asc", "name.asc", "name.desc", "country.asc", "country.desc", "registered.asc", "registered.desc", "entity_type.asc", "entity_type.desc", "sector.asc", "sector.desc" ], "type": "string" }, "sub_provider": { "description": "ONE curated sub-provider (reseller) slug (`codabox`) — the same slugs `GET /v1/aps/{key}` reports in `sub_providers[].sub_provider`. Matches a participant the daily rollup fingerprinted to that brand on ANY of its current endpoints, from three signals: the SMP `ServiceDescription`, the SMP technical-contact domain, and the endpoint host. Only curated names resolve, so the free-text long tail is not addressable here. Unlike the other filters this one takes a single value: a comma list, or a value that is not a slug (lowercase alphanumerics, dash-separated), is a 400. The sub-provider is an ADDITIVE annotation — the `ap` seat stays the operator of record. Results are ordered by identifier (`scheme`, `value`) and `sort` is ignored, EXCEPT alongside `q` or `doctype`/`transport_profile`/`host`, where the requested `sort` applies. Combining it with any other filter (`country`, `scheme`, `smp`, `ap`, `registered`, `provenance`, `entity_type`, `sector`, `size`, `region`, `postcode`, `vat_liable`) evaluates that filter against the rollup's DAILY SNAPSHOT of those participant columns, not the live row — a participant changing SMP or country is reflected here on the next rollup. Those combinations report an exact `meta.filter_count` (`filter_count_source: \"exact\"`); adding `q` or an endpoint filter falls back to the bounded count.", "type": "string" }, "transport_profile": { "description": "Comma-array of transport profile ids (`peppol-transport-as4-v2_0`). Matches a participant if ANY of its current endpoints uses one of the given profiles. Used ALONE (no other filter) results are ordered by identifier and `sort` is ignored; combined with another filter the requested `sort` applies.", "items": { "type": "string" }, "type": "array" }, "vat_liable": { "description": "Filter by company VAT-liable / mandate-scope flag.", "type": "boolean" } }, "type": "object" }, "name": "list_participants", "outputSchema": null }, { "description": "Get a provider's certificate posture\n\nA curated provider's whole-fleet certificate posture in one call: per-Seat cert counts, soonest expiry, expired / expiring-within-30-days counts, observed cert organisations and last identity shift, plus the rolled-up fleet summary.", "inputSchema": { "properties": { "slug": { "description": "The curated provider slug.", "type": "string" } }, "required": [ "slug" ], "type": "object" }, "name": "list_provider_certs", "outputSchema": null }, { "description": "List providers\n\nThe OpenPeppol member registry with role flags, country, mapped hostnames and per-provider participant counts (market share), busiest first. Not paginated (the envelope's `next_cursor` is always null).", "inputSchema": { "properties": {}, "type": "object" }, "name": "list_providers", "outputSchema": null }, { "description": "List public provider profiles\n\nThe FREE, crawlable public subset for each curated provider, busiest first: identity + role flags, the seat-directory columns (legal entity, commercial name, website, infra provider, hosting), mapped hostnames, participant count, roster country mix, the 30d/90d uptime headline, a cert-health summary and an `as_of` freshness stamp. Reachable with no API key. `limit` clamps to [1, 500] (default 100). Not paginated (the envelope's `next_cursor` is always null).", "inputSchema": { "properties": { "limit": { "default": 100, "description": "Number of providers to return, clamped to [1, 500]. Defaults to 100.", "maximum": 500, "minimum": 1, "type": "integer" } }, "type": "object" }, "name": "list_public_providers", "outputSchema": null }, { "description": "List SMPs\n\nThe SMP directory: every current SMP hostname with the seat(s) and provider that sign its metadata, busiest first. A hostname is listed if it currently homes participants (from the participant rollup's `smp` facet) or carries an open `smp-signing` certificate. `participant_count` comes from that bounded top-N facet, so a hostname with a signing cert but outside the top-N carries a null count (unknown), not zero. The provider is resolved from the most-recent open signing cert with the precedence curated mapping (verified) → unverified cert-CN — the same as `/v1/aps`. `provider` is who OPERATES the host; `owner` names the party the curated registry says OWNS it, and is set only when that is a different party (a shared registry SMP served under another party's cert), else null. Not paginated (the envelope's `next_cursor` is always null).", "inputSchema": { "properties": { "limit": { "description": "Cap on returned rows (non-negative integer). Defaults to all.", "minimum": 0, "type": "integer" }, "q": { "description": "Case-insensitive substring filter on the SMP hostname.", "type": "string" } }, "type": "object" }, "name": "list_smps", "outputSchema": null }, { "description": "List the software library (Market)\n\nThe software catalogue's PRODUCT taxonomy joined to what the network shows: for every engine, its display name, vendor, category and homepage, the current host count broken down by observed role, when it was first and last seen, a compliance signal for the seats running it, and a host-count trend of up to 90 UTC days.\n\nEvery catalogue engine appears, including one the network does not currently show (`hosts: 0`, a flat trend) — the library is the catalogue, not only today's sightings. `category` is the vendor's own framing; `roles` is the OBSERVED fact and is the one to trust where the two disagree.\n\n`compliance.seats_linked` is deliberately not called \"owned\": an engine → seat link is MANY-TO-MANY, so a seat whose hosts run two engines is counted under both and its findings appear under both. Summing `open_findings` across engines therefore OVER-COUNTS the network total; the figure answers \"how much compliance debt sits behind this engine\", never \"who is to blame\". `compliance` is null when no seat is linked to the engine, and `snapshot_date` always travels with the numbers because the daily rollup can be a day stale.\n\n`lanes[]` (issue #798) reports each tracked upstream LANE of the engine — a lane is not an engine: `oxalis` covers three independent release ladders — with its `latest_release` and the `hosts_current` / `hosts_behind` / `hosts_unknown` split of the hosts running it (all three null when any is below 10). `advisories` summarises the live advisories published for the product by CVSS severity. Both are NULL — never `[]` or zero counts — for the engines the catalogue tracks no upstream feed for. Market tier.", "inputSchema": { "properties": { "days": { "default": 90, "description": "Trend window in trailing UTC days, 1..90 (default 90). The ceiling is part of the contract — `days` can only narrow the window, never widen it.", "maximum": 90, "minimum": 1, "type": "integer" } }, "type": "object" }, "name": "list_software", "outputSchema": null } ] }
Verify it yourselfcurl -s https://api.teppi.xyz/v1/evidence/sha256:cd0cd11a9da464fa9efdfd566d01ca213c18f984073f079c2063d39a99cf058c | sha256sum