Nordlet Peppol API
The peppol API from Nordlet — 2 operation(s) for peppol.
The peppol API from Nordlet — 2 operation(s) for peppol.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/nordlet:nordlet-peppol-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Nordlet Accounting Peppol API
version: 0.5.7
description: 'API-first accounting for the EU/EEA market (Lithuania first). Everything the product can do is available here.
## Conventions
- Every operation is `POST /v1/{module}/{resource}/{action}` with a JSON body.
- Authenticate with `Authorization: Bearer `. Keys carry scopes like `sales:write` or `*`.
- List actions accept `page`, `pageSize`, `sort: [{field, dir}]` and `filter: [{field, op, value}]`.
- Monetary amounts are decimal **strings** (e.g. `"121.0000"`), never floats.
- Errors share one envelope: `{ "error": { "code", "message", "requestId", "key?", "params?", "fieldErrors?" } }`; `key` is a stable identifier of the message for translation, with its values in `params`.
- Country-specific compliance endpoints are namespaced by jurisdiction (e.g. `/v1/declarations/lt/...`)
and return 422 unless the company is registered in that country (set at `account/companies/create`).
## Idempotency
Send an `Idempotency-Key` header on any mutating call. Retries replay the original response
(marked with `x-idempotent-replay: true`); reusing a key with a different payload returns 422.
## Rate limits
300 requests/min per API key by default. 429 responses include a `retry-after` header.
## Webhooks
Subscribe via `webhooks/subscriptions/create`. Deliveries are HMAC-signed
(`x-nordlet-signature-v2: t=,v1=.">`, plus the original
`x-nordlet-signature: sha256=`) and retried for about 24 hours. A subscription is paused, and its owners
e-mailed, after 5 events in a row could not be delivered. Every event type and its envelope
(`{ id, version, companyId, eventType, createdAt, data }`) are listed under `x-webhooks`.
Guides - getting started, SDKs, conventions, bank imports, migrating from another system, EU VAT,
revenue recognition, consolidation - live at .'
servers:
- url: https://api.nordlet.com
description: Production
security:
- apiKey: []
tags:
- name: peppol
paths:
/v1/peppol/participants/lookup:
post:
tags:
- peppol
description: Look a receiver up on the Peppol network (SML and SMP) and say which Peppol BIS Billing 3.0 documents it accepts. Give `partnerId` to look up a partner by its Peppol ID, VAT code or registration code, or `participantId` as ":". Works without an access point.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
partnerId:
type: string
minLength: 1
maxLength: 64
pattern: ^[\s\S]*$
participantId:
type: string
minLength: 6
maxLength: 120
pattern: ^[\s\S]*$
responses:
'200':
description: Default Response
content:
application/json:
schema:
type: object
properties:
participantId:
type: string
pattern: ^[\s\S]*$
registered:
type: boolean
smpUrl:
type:
- string
- 'null'
pattern: ^[\s\S]*$
accessPointUrl:
type:
- string
- 'null'
pattern: ^[\s\S]*$
acceptsInvoice:
type: boolean
acceptsCreditNote:
type: boolean
acceptsCii:
type: boolean
required:
- participantId
- registered
- smpUrl
- accessPointUrl
- acceptsInvoice
- acceptsCreditNote
- acceptsCii
additionalProperties: false
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'400':
description: Request validation failed
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'401':
description: Missing or invalid API key
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'402':
description: The trial or the prepaid credit has ended; top up or subscribe to continue
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'403':
description: The API key lacks the required scope
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'404':
description: The requested resource does not exist
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'409':
description: The request conflicts with the current state
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'413':
description: The request body or uploaded file is larger than allowed
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'422':
description: The request is well-formed but violates a business rule
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'429':
description: Rate limit exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
Retry-After:
description: Seconds to wait before retrying
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'500':
description: Unexpected server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
operationId: peppolParticipantsLookup
summary: Peppol participants lookup
x-fern-sdk-group-name: peppol
x-fern-sdk-method-name: participantsLookup
/v1/peppol/webhooks/{provider}/{companyId}:
post:
summary: Receive the webhook events of a company's Peppol access point.
tags:
- peppol
description: 'Apply one event: a delivery status event updates the Peppol status of the sale invoice with that message id and, when the status changes, emits `sale_invoice.peppol_delivered`, `sale_invoice.peppol_rejected` or `sale_invoice.peppol_failed`; a received-document event fetches the document from the access point, stores it as a document capture with the matched supplier, emits `document_capture.peppol_received` and marks it read at the access point (a document already stored is skipped). `handled` is false when the event matched no invoice or document. Answers 404 when no company uses that provider account, 401 when the signature does not match.'
parameters:
- schema:
type: string
enum:
- recommand
- storecove
- e-invoice-be
in: path
name: provider
required: true
- schema:
type: string
minLength: 1
maxLength: 64
pattern: ^[\s\S]*$
in: path
name: companyId
required: true
responses:
'200':
description: Default Response
content:
application/json:
schema:
type: object
properties:
handled:
type: boolean
required:
- handled
additionalProperties: false
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'400':
description: Request validation failed
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'401':
description: Missing or invalid API key
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'402':
description: The trial or the prepaid credit has ended; top up or subscribe to continue
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'403':
description: The API key lacks the required scope
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'404':
description: The requested resource does not exist
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'409':
description: The request conflicts with the current state
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'413':
description: The request body or uploaded file is larger than allowed
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'422':
description: The request is well-formed but violates a business rule
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'429':
description: Rate limit exceeded
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
headers:
X-RateLimit-Limit:
description: Request budget for the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Remaining:
description: Requests left in the current window
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
X-RateLimit-Reset:
description: Seconds until the window resets
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
Retry-After:
description: Seconds to wait before retrying
schema:
type: integer
format: int32
minimum: 0
maximum: 2147483647
'500':
description: Unexpected server error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
operationId: peppolWebhooks
x-fern-sdk-group-name: peppol
x-fern-sdk-method-name: webhooks
components:
schemas:
ErrorResponse:
type: object
required:
- error
additionalProperties: false
properties:
error:
type: object
required:
- code
- message
- requestId
additionalProperties: false
properties:
code:
type: string
enum:
- validation
- unauthorized
- forbidden
- not_found
- conflict
- idempotency_key_reuse
- idempotency_in_progress
- rate_limited
- payment_required
- internal
message:
type: string
maxLength: 2000
pattern: ^[\s\S]*$
requestId:
type: string
maxLength: 64
pattern: ^[a-zA-Z0-9_-]+$
fieldErrors:
type: object
maxProperties: 100
additionalProperties:
type: array
maxItems: 100
items:
type: string
maxLength: 2000
pattern: ^[\s\S]*$
securitySchemes:
apiKey:
type: http
scheme: bearer