---
title: "Get an access point"
method: GET
path: "/v1/aps/{key}"
tags: ["Access Points"]
---

# Get an access point

`GET /v1/aps/{key}`

## Request

- Base URL: `https://api.peppolstatus.com`
- URL: `https://api.peppolstatus.com/v1/aps/{key}`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

One 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. Each `sub_providers` bucket names its Vendor (`name`) and links to the Vendor's row (`vendor_key`).

A Vendor key (`v-<slug>`) returns the Vendor detail instead and needs a Market-tier key: the Providers it connects through (`via`), its participants and Companies, the signals that back the row, and the composition of its roster. A Vendor has no Seats, no certificate and no hosts of its own.

## Path parameters

- `key` string, required

## Response `200`

The access point detail: a Provider, or a Vendor.

- union
  - ApProviderDetail
    - `kind` 'provider': The row kind. Always `provider` on this shape.
    - `key` string, required: The canonical provider key (see ApView.key). Always the current one.
    - `name` string, required
    - `verified` boolean, required
    - `commercial_name` string, nullable: Customer-facing brand from the curated seat directory, which can differ from the certificate O= name. Across several member seats the lowest seat id with a value wins. null when uncurated. Additive.
    - `website` string, nullable: The provider's own website from the curated seat directory, picked like commercial_name. null when unknown. Additive.
    - `participant_count` integer, required: AP-cert roster size: participants whose signing-cert identity attributes them to this Provider, independent of who hosts their SMP.
    - `hosted_participant_count` integer, nullable: SMP-hosting footprint of the linked registry provider (the /v1/providers participant_count): participants whose current SMP binding resolves to one of that provider's hosts. For a multi-tenant SMP operator this far exceeds participant_count above. null/absent when no registry provider link exists. Additive.
    - `smp_hostnames` string[], nullable: The linked registry provider's mapped SMP hostnames backing hosted_participant_count (from provider_host), capped at 10 — the /v1/participants `smp=` filter values, for deep-linking the hosted footprint to the pre-filtered participants list. null/absent when unlinked/unmapped. Additive.
    - `smp_hostname_count` integer, nullable: TRUE total of the linked registry provider's mapped SMP hostnames, behind the capped smp_hostnames sample above. null/absent when no registry provider link exists. Additive.
    - `hostnames` string[], nullable: The host machines the member seats are currently sighted operating on (seat_sighting, across AP and SMP signing certs — distinct, sorted, capped at 20). The reverse of the host detail page's Seat(s) list, for linking each host to its /hosts/{hostname} page. null/absent when no member seat is sighted on an open host. Additive.
    - `hostname_count` integer, nullable: TRUE total of distinct currently-sighted hostnames, behind the capped hostnames sample above. null/absent when none is sighted. Additive.
    - `software` ApSoftwareRow[], nullable: The sighted hostnames grouped by registrable domain, each with the crawled software identity of that domain — who operates the machines and what product answers there. An `infrastructure` row reads "runs on X", never "is X". Sorted host_count desc, then domain. null/absent when no domain passes the surfacing rule (curated, or confidence >= 0.8). Additive.
      - `profile` HostProfileView, required: Crawled software identity of the host's registrable domain (eTLD+1), so every `smp.acme.com` / `ap.acme.com` shares one profile. Only rows that pass the surfacing rule appear: a curator confirmed the identity (`curated: true`), or extraction confidence reached 0.8 — then the row is AUTO-GENERATED and UNVERIFIED and must be labelled as such.
        - `domain` string, required: The registrable domain the profile describes.
        - `status` 'identified' | 'infrastructure', required: `identified` — the domain's own company/product. `infrastructure` — a multi-tenant platform the host RUNS ON (read it as "runs on X", never "is X").
        - `company_name` string, nullable, required
        - `product_name` string, nullable, required
        - `tagline` string, nullable, required
        - `category` string, nullable, required
        - `confidence` number, nullable, required: Extraction confidence 0..1; null for a curated row with no stored score.
        - `curated` boolean, required: True when a curator confirmed the identity. False means auto-generated and unverified — annotate, never assert.
        - `screenshot_url` string, nullable, required: Same-origin path to the homepage screenshot (`/v1/hosts/asset/{domain}/screenshot.jpg`, free tier); null when none captured.
        - `crawled_at` string, date-time, nullable, required
      - `host_count` integer, required: TRUE count of distinct sighted hostnames on this domain.
      - `hostnames` string[], required: A sorted SAMPLE of those hostnames (capped at 5) for deep-linking /hosts/{hostname}; see host_count for the total.
    - `sub_providers` object[], nullable: Sub-providers (resellers) detected behind the member seats via the SMP ServiceDescription fingerprint (seat_sub_provider_rollup) — who resells or brands the traffic behind a shared seat, e.g. CodaBox behind the Flowin / Wolters Kluwer seat. Only curated allow-list matches surface (the free-text long tail is never exposed raw); an ADDITIVE annotation — the signing cert and seat remain the operator ground truth. Sorted participants desc, capped at 20. null/absent when nothing matches. Additive.
      - `seat_id` string, required: The member seat the bucket belongs to.
      - `sub_provider` string, required: Curated sub-provider (reseller) slug, e.g. `codabox`.
      - `participants` integer, required: Distinct participants on that seat whose SMP ServiceDescription matches the slug.
      - `name` string: The curated Vendor label of the slug.
      - `vendor_key` string, nullable: The key of the Vendor's own row (`/v1/aps/{key}`, Market tier); null when the Vendor has none, because all its traffic is on Seats of its own company.
    - `smp_tenants` ApSmpTenant[], nullable: The Access Points that serve the participants on this Provider's SMP hosts: the hosted footprint (`hosted_participant_count`) grouped by each participant's current serving seat, from a precomputed rollup. On a multi-tenant SMP most of the hosted footprint is served by OTHER APs, each signing with its own seat; the Provider's own seats carry `self: true`. Sorted participants desc, then seat_id, capped at 25. Participants with no current AP are not a row (see `smp_tenant_no_ap`). null/absent when no registry provider is linked or before the first rollup. Additive.
      - `seat_id` string, required: The serving seat id (e.g. `PFR000964`).
      - `ap_key` string, nullable, required: The access point key of the Provider that holds this seat, for a `/v1/aps/{key}` lookup; null when unresolved.
      - `ap_name` string, nullable, required: Display name of that Provider; null when unresolved.
      - `participants` integer, required: Participants on the SMP hosts whose current serving seat is `seat_id`.
      - `self` boolean, required: true when the seat is one of this Provider's own member seats.
    - `smp_tenant_count` integer, nullable: True number of distinct serving seats behind the capped `smp_tenants`.
    - `smp_tenant_other` integer, nullable: Participants summed over the seats folded out of `smp_tenants` by the cap.
    - `smp_tenant_no_ap` integer, nullable: Participants on this Provider's SMP hosts with no current serving AP.
    - `smp_hosted_by` ApSmpHost[], nullable: Reverse direction: the registry providers whose SMP hosts carry participants that this Provider's member seats serve (e.g. a SaaS AP whose participants sit on a third-party SMP). The Provider's own SMP is excluded. Sorted participants desc, capped at 10. null/absent when none or before the first rollup. Additive.
      - `provider_key` string, required: Registry provider natural key (the SMP host's operator).
      - `ap_key` string, nullable, required: The access point key of that Provider; null when unresolved.
      - `name` string, required: Display name; falls back to the provider_key.
      - `participants` integer, required: Participants on that provider's SMP hosts that this AP's member seats serve.
    - `unique_organizations` integer: Unique organizations across the roster (sum of member seats' distinct company_key counts). Additive; absent on a pre-#451 rollup.
    - `ids_per_organization` number, nullable: participant_count / unique_organizations; null under the <100-participant noise guard, absent on a pre-#451 rollup.
    - `seats` SeatRef[], required
      - `seat_id` string, required
      - `provider` SeatProvider, required: Embedded provider for a seat, verified mapping or unverified CN fallback.
        - `slug` string, nullable, required
        - `name` string, nullable, required
        - `country` string, nullable, required
        - `verified` boolean, required
        - `key` string, nullable: The curated provider's OpenPeppol registry natural key, when the mapping carries one. It decides whether the seat's operator and a host's owner are the same party; it is not a /v1/aps route key and not the slug. Optional: absent on a cached response minted before the field shipped.
    - `country_mix` ApMixBucket[], required
      - `value` string, required
      - `count` integer, required
      - `label` string: Display label of `value`, on the buckets of a `size_mix` and a `region_mix` only: the English size band label (21 → "50–99 employees") and the region name in the local language (84 → "Auvergne-Rhône-Alpes"). Equal to `value` when the code is unknown. Filter on `value`.
    - `scheme_mix` ApMixBucket[], required
      - `value` string, required
      - `count` integer, required
      - `label` string: Display label of `value`, on the buckets of a `size_mix` and a `region_mix` only: the English size band label (21 → "50–99 employees") and the region name in the local language (84 → "Auvergne-Rhône-Alpes"). Equal to `value` when the code is unknown. Filter on `value`.
    - `entity_type_mix` ApMixBucket[]: Roster composition by company entity type (company | natural_person | association | public). Company enrichment covers part of the roster only, so the buckets sum BELOW participant_count — the difference is the unenriched remainder, which a client should show as its own bucket rather than drop. Absent when nothing in the roster is enriched. Additive.
      - `value` string, required
      - `count` integer, required
      - `label` string: Display label of `value`, on the buckets of a `size_mix` and a `region_mix` only: the English size band label (21 → "50–99 employees") and the region name in the local language (84 → "Auvergne-Rhône-Alpes"). Equal to `value` when the code is unknown. Filter on `value`.
    - `sector_mix` ApMixBucket[]: Roster composition by 2-digit NACE Rev. 2.1 division. Same sparsity caveat as entity_type_mix; absent when nothing is enriched. Additive.
      - `value` string, required
      - `count` integer, required
      - `label` string: Display label of `value`, on the buckets of a `size_mix` and a `region_mix` only: the English size band label (21 → "50–99 employees") and the region name in the local language (84 → "Auvergne-Rhône-Alpes"). Equal to `value` when the code is unknown. Filter on `value`.
    - `size_mix` ApMixBucket[]: Roster composition by company size band code, each bucket with its `label`. The register data has a size for FR (INSEE trancheEffectifs codes; `NN` = unknown) and NO (the same code set plus `1-4`) only, so absent for a roster with no such participant. Additive.
      - `value` string, required
      - `count` integer, required
      - `label` string: Display label of `value`, on the buckets of a `size_mix` and a `region_mix` only: the English size band label (21 → "50–99 employees") and the region name in the local language (84 → "Auvergne-Rhône-Alpes"). Equal to `value` when the code is unknown. Filter on `value`.
    - `region_mix` ApMixBucket[]: Roster composition by company region code, each bucket with its `label`. The register data has a region for FR (bare INSEE région code) and BE, NO, SK (ISO 3166-2) only, so absent for a roster with no such participant. Additive.
      - `value` string, required
      - `count` integer, required
      - `label` string: Display label of `value`, on the buckets of a `size_mix` and a `region_mix` only: the English size band label (21 → "50–99 employees") and the region name in the local language (84 → "Auvergne-Rhône-Alpes"). Equal to `value` when the code is unknown. Filter on `value`.
    - `doctypes` string[], required: Distinct Peppol document type URNs present in this provider's roster (sorted). The roster-scoped option set for the doctype filter; empty on a pre-rollup row, where the client falls back to the global doctype catalog.
    - `transports` string[], required: Distinct transport profile ids present in this provider's roster (sorted). The roster-scoped option set for the transport filter; empty → global fallback.
  - ApVendorDetail: One Vendor (`GET /v1/aps/v-<slug>`, Market tier). Every mix describes `participant_count`, so a Seat of the Vendor's own company is in none of them.
    - `kind` 'vendor', required
    - `key` string, required: `v-<slug>`.
    - `slug` string, required
    - `name` string, required: The curated display label.
    - `verified` unknown, required
    - `seats` unknown, required
    - `via` ApVendorVia[], required: The Providers the Vendor connects through, largest first. A participant can be on more than one Seat, so the entries can sum above `participant_count`.
      - `key` string, required: The Provider's key (`/v1/aps/{key}`); `s-<seatid>` when the Seat resolves to no Provider.
      - `name` string, required
      - `participants` integer, required: The Vendor's distinct participants across this Provider's Seats.
      - `seats` object[], required: The Vendor's participants per Seat of this Provider. Each count equals the sub-provider count on that Provider's detail.
        - `seat_id` string, required
        - `participants` integer, required
    - `signals` string[], required: The observed signals that match participants to this Vendor.
    - `participant_count` integer, required: Distinct registered participants across the Seats in `via`.
    - `own_seat_participants` integer, required: Registered participants matched on Seats of the Vendor's own company. They count for that Provider and are not in `participant_count`.
    - `own_seat_ids` string[], required
    - `unique_organizations` integer, required
    - `ids_per_organization` number, nullable, required: participant_count / unique_organizations; null below 10 participants.
    - `churn_since` string, date, nullable, required: The first day movement is counted from; null before the first daily run.
    - `country_mix` ApMixBucket[], required
      - `value` string, required
      - `count` integer, required
      - `label` string: Display label of `value`, on the buckets of a `size_mix` and a `region_mix` only: the English size band label (21 → "50–99 employees") and the region name in the local language (84 → "Auvergne-Rhône-Alpes"). Equal to `value` when the code is unknown. Filter on `value`.
    - `scheme_mix` ApMixBucket[], required
      - `value` string, required
      - `count` integer, required
      - `label` string: Display label of `value`, on the buckets of a `size_mix` and a `region_mix` only: the English size band label (21 → "50–99 employees") and the region name in the local language (84 → "Auvergne-Rhône-Alpes"). Equal to `value` when the code is unknown. Filter on `value`.
    - `entity_type_mix` ApMixBucket[]: Absent when no participant of the roster is enriched for it.
      - `value` string, required
      - `count` integer, required
      - `label` string: Display label of `value`, on the buckets of a `size_mix` and a `region_mix` only: the English size band label (21 → "50–99 employees") and the region name in the local language (84 → "Auvergne-Rhône-Alpes"). Equal to `value` when the code is unknown. Filter on `value`.
    - `sector_mix` ApMixBucket[]: Absent when no participant of the roster is enriched for it.
      - `value` string, required
      - `count` integer, required
      - `label` string: Display label of `value`, on the buckets of a `size_mix` and a `region_mix` only: the English size band label (21 → "50–99 employees") and the region name in the local language (84 → "Auvergne-Rhône-Alpes"). Equal to `value` when the code is unknown. Filter on `value`.
    - `size_mix` ApMixBucket[]: Absent when no participant of the roster is enriched for it.
      - `value` string, required
      - `count` integer, required
      - `label` string: Display label of `value`, on the buckets of a `size_mix` and a `region_mix` only: the English size band label (21 → "50–99 employees") and the region name in the local language (84 → "Auvergne-Rhône-Alpes"). Equal to `value` when the code is unknown. Filter on `value`.
    - `region_mix` ApMixBucket[]: Absent when no participant of the roster is enriched for it.
      - `value` string, required
      - `count` integer, required
      - `label` string: Display label of `value`, on the buckets of a `size_mix` and a `region_mix` only: the English size band label (21 → "50–99 employees") and the region name in the local language (84 → "Auvergne-Rhône-Alpes"). Equal to `value` when the code is unknown. Filter on `value`.
    - `refreshed_at` string, date-time, required

## Other responses

- `403`: A Vendor key with a key below the Market tier.
- `404`: No such access point is known.

---

[API](https://skmtc.dev/peppolstatus/apis/peppolstatus-api.md) · [All operations](https://skmtc.dev/peppolstatus/apis/peppolstatus-api/llms.txt) · [OpenAPI document](https://skmtc.dev/peppolstatus/apis/peppolstatus-api/revisions/7e74fb32f23c?raw)
