# PeppolCheck.fr — full agent manual

> A complete, single-file reference for AI agents that need to use PeppolCheck.fr. Read this once and you can drive the entire product end-to-end.

## 1. Product summary

PeppolCheck.fr is a free, public, read-only verification service for the Peppol e-invoicing network. It answers two questions:

1. "Is this organisation reachable on Peppol, and what is their access point?"
2. "Which Peppol document types can this organisation receive?"

Coverage: every participant registered on the OpenPeppol SML — roughly 2.5 million organisations across 34 countries, including France (FR), Belgium (BE), and the rest of the EU/EEA.

Data is synced nightly from the OpenPeppol Service Metadata Locator (SML), Service Metadata Publisher (SMP) per-participant endpoints, and the Peppol Directory full-text search.

## 2. Peppol identifier format

A Peppol participant identifier has the shape `{scheme}:{value}`:

- `scheme` — a 4-digit ISO 6523 issuing authority code, e.g. `0208` (Belgian CBE), `9957` (French VAT), `9925` (Belgian VAT), `0184` (Danish CVR), `0106` (Dutch KvK).
- `value` — the issuer-specific registration value (digits and letters; case is preserved).

Examples:

- `0208:0848934496` — Carrefour (BE / CBE).
- `9957:FR79410820010` — French company by VAT.
- `0106:KVK33014286` — Heineken N.V. (NL / KvK).

The canonical URL form on PeppolCheck.fr uses a colon literal: `https://peppolcheck.fr/0208:0848934496`.

## 3. HTTP API

Base URL: `https://peppolcheck.fr`. All responses are UTF-8.

### 3.1 GET /api/v1/participant/{scheme}:{value}

Resolve a Peppol participant by its identifier.

Request:

```
GET /api/v1/participant/0208:0848934496 HTTP/1.1
Host: peppolcheck.fr
Accept: application/json
```

Response 200:

```json
{
  "participantId": "0208:0848934496",
  "directory": {
    "participantId": { "scheme": "0208", "value": "0848934496" },
    "name": "CARREFOUR BELGIUM SA",
    "countryCode": "BE",
    "registrationDate": "2019-07-01",
    "additionalInfo": null,
    "geoInfo": null,
    "entities": [ ... ],
    "docTypes": [
      { "scheme": "busdox-docid-qns", "value": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##..." }
    ]
  },
  "smp": {
    "url": "https://smp.example/iso6523-actorid-upis%3A%3A0208%3A0848934496",
    "hostname": "smp.example",
    "serviceCount": 7,
    "endpoint": { ... }
  }
}
```

Response 404 (not on Peppol):

```json
{ "error": { "code": "not_found", "message": "no Peppol record for 0208:0000000000" } }
```

Response 400 (malformed identifier):

```json
{ "error": { "code": "invalid_participant_id", "message": "'foo' is not a valid Peppol participant identifier" } }
```

Response 502 (upstream registry failed):

```json
{ "error": { "code": "lookup_failed", "message": "directory responded 503" } }
```

### 3.2 GET /api/v1/search?q={query}

Full-text search the Peppol Directory by name, VAT number, or registry value.

Request:

```
GET /api/v1/search?q=carrefour HTTP/1.1
Host: peppolcheck.fr
Accept: application/json
```

Response 200:

```json
{
  "query": "carrefour",
  "totalCount": 12,
  "results": [
    {
      "participantId": "0208:0848934496",
      "name": "CARREFOUR BELGIUM SA",
      "countryCode": "BE",
      "additionalInfo": null,
      "geoInfo": null
    }
  ]
}
```

Constraints:

- `q` must be at least 2 characters. Empty or too-short queries return 400 `missing_query` / `query_too_short`.
- Up to 25 results per response.

### 3.3 Error envelope

Every API error response uses the same envelope:

```json
{ "error": { "code": "<machine_code>", "message": "<human readable>" } }
```

Documented codes:

| Code                    | HTTP | Meaning                                          |
| ----------------------- | ---- | ------------------------------------------------ |
| `invalid_participant_id` | 400  | Identifier did not match `\d{4}:[A-Za-z0-9._\-+]+`. |
| `missing_query`         | 400  | `q` parameter missing or empty.                  |
| `query_too_short`       | 400  | `q` is shorter than 2 characters.                |
| `not_found`             | 404  | Participant has no record in directory or SMP.   |
| `lookup_failed`         | 502  | Upstream OpenPeppol registry failed.             |
| `search_failed`         | 502  | Upstream directory search failed.                |

## 4. Authentication

The public API is unauthenticated. Send GET requests with no credentials.

For agent-to-agent flows, see `https://peppolcheck.fr/auth.md` and `https://peppolcheck.fr/.well-known/oauth-protected-resource`. The current resource server does not require tokens; the metadata exists so agents can probe consistently and so future authenticated endpoints can plug in without breaking discovery.

## 5. MCP (Model Context Protocol)

PeppolCheck.fr serves an MCP server over Streamable HTTP at `https://peppolcheck.fr/mcp`. The server exposes the Peppol lookup capability as tools:

- `peppol_lookup` — resolve a participant by ID.
- `peppol_search` — search by name/VAT.

Discovery:

- Server card: `GET https://peppolcheck.fr/.well-known/mcp/server-card.json`
- Well-known root: `GET https://peppolcheck.fr/.well-known/mcp`

## 6. NLWeb /ask endpoint

`POST https://peppolcheck.fr/ask` accepts a natural-language query and returns JSON-Schema-flavoured results. Set `prefer: streaming` (or `Accept: text/event-stream`) to receive Server-Sent Events with NLWeb event types: `start`, `result`, `complete`.

Example:

```
POST /ask HTTP/1.1
Host: peppolcheck.fr
Content-Type: application/json
Accept: application/json

{ "query": "Find Carrefour on Peppol" }
```

## 7. Webhooks

Not currently offered. The Peppol Directory updates nightly, and PeppolCheck.fr does not yet provide a subscription bus. If you need push notifications when a new participant appears, file a request via `willem@e-invoice.be`.

## 8. Limits and fair use

- Per-IP soft rate limit applies; bulk re-export to seed a competing directory is not permitted (see `/mentions-legales`).
- The `User-Agent` header is logged. Identifying agents with a contact URL (e.g. `MyAgent/1.0 (+https://example.com)`) improves debuggability if you hit limits.

## 9. Data sources

- OpenPeppol SML — authoritative DNS-based locator for participant SMPs.
- Per-participant SMP — service metadata, document type endpoints.
- Peppol Directory (directory.peppol.eu) — search and listing.

PeppolCheck.fr does not modify or enrich the underlying data beyond stitching SML + SMP + Directory views together.

## 10. Legal and contact

- Operator: e-invoice.be.
- Contact: willem@e-invoice.be.
- Terms: https://peppolcheck.fr/mentions-legales
- Privacy: https://peppolcheck.fr/confidentialite (FR) and https://peppolcheck.fr/privacy (EN summary)
- Source data: OpenPeppol registries under their public terms.
