For the complete documentation index, see llms.txt. This page is also available as Markdown.

Webhook API

Operations related to Web hooks

Get Webhook Configuration

get
/account/{accountRegNo}/webhook/configure

An API to fetch (GET) the webhook subscription for your Partner account.

Partner or Partners Account

Partners can configure their own web hooks through /partner/{partnerRegNo}/webhook/... URI, or their child accounts using /partner/{partnerRegNo}/account/{accountRegNo}/webhook/.... The latter is useful if you want to scope the subscription to a single account. A partner-level subscription covers the partner's own account only, not its children: to receive a child's events, subscribe to that child with /partner/{partnerRegNo}/account/{accountRegNo}/webhook/..., one child at a time. A partner's subscription to a child is separate from the child's own subscription (neither can see or change the other's), and an event for the child is delivered to both, with the same eventId. It delivers only while the partner may act for the child (the child's parentAccount is the partner and the partner holds the webhook scope), which is checked on every delivery.

parameter accountRegNo is only required for child accounts, and should be omitted for the Partner account itself.

Authorizations
AuthorizationstringRequired
Path parameters
accountRegNostringRequired

Account registration number issued by Qvalia

Responses
200

OK

application/json
idstring · uuidOptionalExample: a1b2c3d4-5678-90ab-cdef-1234567890ab
urlstringOptionalExample: https://example.com/webhooks/qvalia
typesstring[]OptionalExample: ["new_document","document_delivery"]
accountRegNostringOptionalExample: SE1234567890
enabledbooleanOptionalExample: true
authTypestring · enum · nullableOptionalExample: api_keyPossible values:
createdAtstring · date-timeOptionalExample: 2024-01-01T12:00:00.000Z
updatedAtstring · date-timeOptionalExample: 2024-01-02T12:00:00.000Z
get/account/{accountRegNo}/webhook/configure
GET /account/{accountRegNo}/webhook/configure HTTP/1.1
Host: api-test.qvalia.com
Authorization: YOUR_API_KEY
Accept: */*
{
  "id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
  "url": "https://example.com/webhooks/qvalia",
  "types": [
    "new_document",
    "document_delivery"
  ],
  "accountRegNo": "SE1234567890",
  "enabled": true,
  "authType": "api_key",
  "signing": {
    "algorithm": "hmac-sha256",
    "secrets": [
      {
        "id": "whsk_91be0c4d22af",
        "createdAt": "2026-09-14T09:12:44.031Z",
        "expiresAt": "2026-09-15T09:12:44.031Z",
        "active": true
      }
    ]
  },
  "createdAt": "2024-01-01T12:00:00.000Z",
  "updatedAt": "2024-01-02T12:00:00.000Z"
}

Configure Webhook

put
/account/{accountRegNo}/webhook/configure

An API to create or update (PUT) the webhook subscription for your account.

An account has a single webhook subscription. The first PUT creates it and returns a generated webhook id (a UUID v4); subsequent PUT requests update the same subscription (its url and/or types). Use the returned id with the /account/{accountRegNo}/webhook/{webhookId}/auth endpoints to attach outbound authentication.

A PUT that creates the subscription returns a signingSecret in clear text in that response only. Store it; see /account/{accountRegNo}/webhook/{webhookId}/secret to rotate it or to obtain one for an older subscription.

Event types

  • new_document — sent when a new document is received/created for an account.

  • document_delivery — sent when a document's delivery status changes.

  • document_delayed — sent when a delivery is being retried and has not finished.

  • document_error — sent when a document's delivery fails.

Delivery (webhook usage)

Events are delivered as an HTTP POST with a JSON body to the configured url (which must be https). Your endpoint should respond with a 2xx status code; the delivery request times out after 10 seconds. If outbound authentication is configured (see /account/{accountRegNo}/webhook/{webhookId}/auth) it is applied as request headers on every delivery. The delivered payload is a single flat JSON object — see the webhookEvent callback below for the full schema, and /partner/{partnerRegNo}/webhook/configure in the Partner API for worked examples of all three event types.

Every delivery carries X-Qvalia-Event-Id, and X-Qvalia-Signature once the subscription has a signing secret — see /account/{accountRegNo}/webhook/{webhookId}/secret.

Delivery is best-effort: duplicates are possible, and a failed delivery is not retried. A missed event can be fetched again for 30 days with GET .../webhook/{eventId}, but keep polling the Transaction API as a safety net — see /partner/{partnerRegNo}/webhook/configure in the Partner API for details.

Authorizations
AuthorizationstringRequired
Path parameters
accountRegNostringRequired

Account registration number issued by Qvalia

Body
urlstring · uriRequired

HTTPS endpoint that will receive webhook events

Example: https://example.com/webhooks/qvalia
Responses
200

OK

application/json
idstring · uuidOptionalExample: a1b2c3d4-5678-90ab-cdef-1234567890ab
urlstringOptionalExample: https://example.com/webhooks/qvalia
typesstring[]OptionalExample: ["new_document","document_delivery"]
accountRegNostringOptionalExample: SE1234567890
signingSecretstringOptional

Secret used to sign deliveries to this subscription (HMAC-SHA256).

Returned only when this PUT created the subscription, and only in this one response — we store it encrypted and cannot show it again. Store it now. Lost it, or updating a subscription created before signing existed? Use POST /account/{accountRegNo}/webhook/{webhookId}/secret.

Example: whsec_Zx8QvK3mR7pL2nT9wY4hB6jF1sD0gA5cE8uI3oP7kM
signingSecretIdstringOptional

Identifier for the secret above, for use in support and audit. Not itself a secret.

Example: whsk_4f1a90c2b7de
signatureAlgorithmstring · enumOptionalExample: hmac-sha256Possible values:
put/account/{accountRegNo}/webhook/configure
PUT /account/{accountRegNo}/webhook/configure HTTP/1.1
Host: api-test.qvalia.com
Authorization: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 90

{
  "url": "https://example.com/webhooks/qvalia",
  "types": [
    "new_document",
    "document_delivery"
  ]
}
{
  "id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
  "url": "https://example.com/webhooks/qvalia",
  "types": [
    "new_document",
    "document_delivery"
  ],
  "accountRegNo": "SE1234567890",
  "signingSecret": "whsec_Zx8QvK3mR7pL2nT9wY4hB6jF1sD0gA5cE8uI3oP7kM",
  "signingSecretId": "whsk_4f1a90c2b7de",
  "signatureAlgorithm": "hmac-sha256"
}

Delete Webhook Configuration

delete
/account/{accountRegNo}/webhook/configure

An API to DELETE the webhook subscription for your Partner account.

This removes the subscription and any attached outbound authentication.

Partner or Partners Account

Partners can configure their own web hooks through /partner/{partnerRegNo}/webhook/... URI, or their child accounts using /partner/{partnerRegNo}/account/{accountRegNo}/webhook/.... The latter is useful if you want to scope the subscription to a single account. A partner-level subscription covers the partner's own account only, not its children: to receive a child's events, subscribe to that child with /partner/{partnerRegNo}/account/{accountRegNo}/webhook/..., one child at a time. A partner's subscription to a child is separate from the child's own subscription (neither can see or change the other's), and an event for the child is delivered to both, with the same eventId. It delivers only while the partner may act for the child (the child's parentAccount is the partner and the partner holds the webhook scope), which is checked on every delivery.

parameter accountRegNo is only required for child accounts, and should be omitted for the Partner account itself.

Authorizations
AuthorizationstringRequired
Path parameters
accountRegNostringRequired

Account registration number issued by Qvalia

Responses
204

No Content. The request succeeded and there is no body to return.

No content

delete/account/{accountRegNo}/webhook/configure
DELETE /account/{accountRegNo}/webhook/configure HTTP/1.1
Host: api-test.qvalia.com
Authorization: YOUR_API_KEY
Accept: */*

No content

Get Webhook Authentication

get
/account/{accountRegNo}/webhook/{webhookId}/auth

An API to fetch (GET) the outbound authentication type configured for your account's webhook subscription. The credential itself is never returned.

Authorizations
AuthorizationstringRequired
Path parameters
accountRegNostringRequired

Account registration number issued by Qvalia

webhookIdstring · uuidRequired

Webhook identifier returned by PUT /webhook/configure, e.g. "a1b2c3d4-5678-90ab-cdef-1234567890ab"

Responses
200

OK

application/json
typestring · enumOptionalExample: api_keyPossible values:
get/account/{accountRegNo}/webhook/{webhookId}/auth
GET /account/{accountRegNo}/webhook/{webhookId}/auth HTTP/1.1
Host: api-test.qvalia.com
Authorization: YOUR_API_KEY
Accept: */*
{
  "type": "api_key"
}

Set Webhook Authentication

post
/account/{accountRegNo}/webhook/{webhookId}/auth

An API to set (POST) the outbound authentication applied to webhook deliveries for your Partner account's subscription.

{webhookId} must match the id returned by PUT /partner/{partnerRegNo}/account/{accountRegNo}/webhook/configure.

Provide exactly one of the supported auth types:

  • oauth — client-credentials. Qvalia fetches a Bearer token from tokenUrl using clientId/clientSecret (and optional scope) at delivery time.

  • api_key — sent as a request header (header, default X-API-Key) with value.

  • basic — HTTP Basic auth using username/password. The password must be at least 16 characters and contain an uppercase letter, a lowercase letter, a digit and a special character.

Authorizations
AuthorizationstringRequired
Path parameters
accountRegNostringRequired

Account registration number issued by Qvalia

webhookIdstring · uuidRequired

Webhook identifier returned by PUT /webhook/configure, e.g. "a1b2c3d4-5678-90ab-cdef-1234567890ab"

Body
or
or
Responses
200

OK

application/json
typestring · enumOptionalExample: api_keyPossible values:
post/account/{accountRegNo}/webhook/{webhookId}/auth
POST /account/{accountRegNo}/webhook/{webhookId}/auth HTTP/1.1
Host: api-test.qvalia.com
Authorization: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 131

{
  "type": "oauth",
  "clientId": "text",
  "clientSecret": "text",
  "tokenUrl": "https://auth.example.com/oauth/token",
  "scope": "webhooks:write"
}
{
  "type": "api_key"
}

Delete Webhook Authentication

delete
/account/{accountRegNo}/webhook/{webhookId}/auth

An API to DELETE the outbound authentication from your account's webhook subscription. The subscription itself is kept; deliveries are sent without auth headers afterwards.

Authorizations
AuthorizationstringRequired
Path parameters
accountRegNostringRequired

Account registration number issued by Qvalia

webhookIdstring · uuidRequired

Webhook identifier returned by PUT /webhook/configure, e.g. "a1b2c3d4-5678-90ab-cdef-1234567890ab"

Responses
204

No Content. The request succeeded and there is no body to return.

No content

delete/account/{accountRegNo}/webhook/{webhookId}/auth
DELETE /account/{accountRegNo}/webhook/{webhookId}/auth HTTP/1.1
Host: api-test.qvalia.com
Authorization: YOUR_API_KEY
Accept: */*

No content

Get Webhook Signing Secrets

get
/account/{accountRegNo}/webhook/{webhookId}/secret

An API to fetch (GET) which signing secrets exist on your account's webhook subscription and when each stops verifying.

This endpoint returns ids and dates only, never a secret value.

A secret is shown once, in the response that issues it: the PUT /account/{accountRegNo}/webhook/configure that creates the subscription, or POST /account/{accountRegNo}/webhook/{webhookId}/secret. It is stored encrypted and cannot be read back afterwards — if you have lost one, issue a new one with POST.

Authorizations
AuthorizationstringRequired
Path parameters
accountRegNostringRequired

Account registration number issued by Qvalia

webhookIdstring · uuidRequired

Webhook identifier returned by PUT /webhook/configure, e.g. "a1b2c3d4-5678-90ab-cdef-1234567890ab"

Responses
200

OK

application/json
webhookIdstring · uuidOptionalExample: a1b2c3d4-5678-90ab-cdef-1234567890ab
algorithmstring · enumOptionalExample: hmac-sha256Possible values:
get/account/{accountRegNo}/webhook/{webhookId}/secret
GET /account/{accountRegNo}/webhook/{webhookId}/secret HTTP/1.1
Host: api-test.qvalia.com
Authorization: YOUR_API_KEY
Accept: */*
{
  "webhookId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
  "algorithm": "hmac-sha256",
  "secrets": [
    {
      "id": "whsk_91be0c4d22af",
      "createdAt": "2026-09-14T09:12:44.031Z",
      "expiresAt": "2026-09-15T09:12:44.031Z",
      "active": true
    }
  ]
}

Issue or Rotate Webhook Signing Secret

post
/account/{accountRegNo}/webhook/{webhookId}/secret

Issue a signing secret for your account's webhook subscription, or rotate an existing one. The same endpoint does both, and the plaintext secret is returned here and nowhere else.

{webhookId} must match the id returned by PUT /account/{accountRegNo}/webhook/configure.

Deliveries are then signed with HMAC-SHA256 (X-Qvalia-Signature). See POST /partner/{partnerRegNo}/webhook/{webhookId}/secret for how to verify a delivery, the rotation rules and the overlapHours window.

Authorizations
AuthorizationstringRequired
Path parameters
accountRegNostringRequired

Account registration number issued by Qvalia

webhookIdstring · uuidRequired

Webhook identifier returned by PUT /webhook/configure, e.g. "a1b2c3d4-5678-90ab-cdef-1234567890ab"

Body
overlapHoursinteger · max: 168Optional

How long the secrets being replaced keep verifying, so you can deploy the new one at your own pace. During the window every delivery carries a v1= part for each active secret.

Use 0 when a secret has leaked: the old one stops verifying at once.

Default: 24Example: 24
Responses
200

OK — the new signing secret. This is the only response that contains it.

application/json
webhookIdstring · uuidOptionalExample: a1b2c3d4-5678-90ab-cdef-1234567890ab
algorithmstring · enumOptionalExample: hmac-sha256Possible values:
secretIdstringOptional

Identifier for the new secret. Not itself a secret.

Example: whsk_91be0c4d22af
secretstringOptional

The new signing secret, in clear text. Store it now — it is not retrievable afterwards. Rotate again if you lose it.

Example: whsec_Kd2MxW9fT4hR8nQ1vB6yL3jC7sZ0aE5gU2oI9pK4mN
createdAtstring · date-timeOptionalExample: 2026-09-14T09:12:44.031Z
post/account/{accountRegNo}/webhook/{webhookId}/secret
POST /account/{accountRegNo}/webhook/{webhookId}/secret HTTP/1.1
Host: api-test.qvalia.com
Authorization: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 19

{
  "overlapHours": 24
}
{
  "webhookId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
  "algorithm": "hmac-sha256",
  "secretId": "whsk_91be0c4d22af",
  "secret": "whsec_Kd2MxW9fT4hR8nQ1vB6yL3jC7sZ0aE5gU2oI9pK4mN",
  "createdAt": "2026-09-14T09:12:44.031Z",
  "previousSecrets": [
    {
      "id": "whsk_4f1a90c2b7de",
      "expiresAt": "2026-09-15T09:12:44.031Z"
    }
  ]
}

Delete Webhook Signing Secret

delete
/account/{accountRegNo}/webhook/{webhookId}/secret

An API to DELETE signing from your account's webhook subscription. Every secret is removed and deliveries are sent unsigned from the next event onwards. The subscription itself, and any outbound authentication on it, are kept.

Authorizations
AuthorizationstringRequired
Path parameters
accountRegNostringRequired

Account registration number issued by Qvalia

webhookIdstring · uuidRequired

Webhook identifier returned by PUT /webhook/configure, e.g. "a1b2c3d4-5678-90ab-cdef-1234567890ab"

Responses
204

No Content. The request succeeded and there is no body to return.

No content

delete/account/{accountRegNo}/webhook/{webhookId}/secret
DELETE /account/{accountRegNo}/webhook/{webhookId}/secret HTTP/1.1
Host: api-test.qvalia.com
Authorization: YOUR_API_KEY
Accept: */*

No content

Get a Delivered Webhook

get
/account/{accountRegNo}/webhook/{eventId}

Fetch a delivered webhook again by its eventId, e.g. one your endpoint missed. Every delivered body is kept for 30 days.

The response is the body exactly as it was POSTed to your url, same eventId included, so it deduplicates against a delivery you did receive. It is not signed: this request is authenticated like the rest of the API instead.

The eventIds of failed deliveries are listed on the document's GET /transaction/{accountRegNo}/{documents}/{direction}/status, under metadata.webhooks_dispatched, with the HTTP status/statusText your endpoint returned.

An event is served only for the account it is about (accountRegNo in the body). An unknown or expired eventId, or another account's, answers 204.

Authorizations
AuthorizationstringRequired
Path parameters
accountRegNostringRequired

Account registration number issued by Qvalia

eventIdstring · uuidRequired

The eventId of a delivered webhook, as sent in the body and the X-Qvalia-Event-Id header, e.g. "4d1c9f84-3a2b-5c6d-9e0f-1a2b3c4d5e6f"

Responses
200

OK — the webhook body as it was delivered.

application/json

A webhook body, as POSTed to your endpoint and as returned by GET /account/{accountRegNo}/webhook/{eventId}. Field reference: the webhookEvent callback in the Partner API.

eventIdstring · uuidRequired

Identifies the event, not the delivery attempt. Derived from the event content, so every redelivery of the same event carries the same value — deduplicate on it. Also sent as the X-Qvalia-Event-Id header.

Example: 4d1c9f84-3a2b-5c6d-9e0f-1a2b3c4d5e6f
eventTypestring · enumRequiredExample: new_documentPossible values:
accountRegNostringRequiredExample: SE1234567890
documentTypestringOptional

e.g. Invoice, CreditNote, Order

Example: Invoice
integrationIdstring · uuidOptional

Qvalia unique identifier for the transaction/message

Example: a1b2c3d4-5678-90ab-cdef-1234567890ab
directionstring · enumOptionalExample: incomingPossible values:
occurredAtstring · date-timeOptionalExample: 2024-01-01T12:00:00.000Z
documentIdstringOptional

Document number (e.g. invoice number). Present on new_document; may be absent on document_delivery/document_error when the upstream delivery channel does not report one.

Example: 123456-INV
globalTransactionIdstring · uuidOptional

Qvalia's platform-wide transaction id for this document exchange. Absent if not available for this event.

Example: 6b928ef1-fb0d-4b9a-a56f-b5dbca7a0fd4
errorstringOptional

Error message describing the delivery failure. Only present when eventType is document_error.

Example: Peppol validation failed: invoice does not conform to UBL 2.1
get/account/{accountRegNo}/webhook/{eventId}
GET /account/{accountRegNo}/webhook/{eventId} HTTP/1.1
Host: api-test.qvalia.com
Authorization: YOUR_API_KEY
Accept: */*
{
  "eventId": "4d1c9f84-3a2b-5c6d-9e0f-1a2b3c4d5e6f",
  "eventType": "new_document",
  "accountRegNo": "SE1234567890",
  "documentType": "Invoice",
  "integrationId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
  "direction": "incoming",
  "occurredAt": "2024-01-01T12:00:00.000Z",
  "documentId": "123456-INV",
  "globalTransactionId": "6b928ef1-fb0d-4b9a-a56f-b5dbca7a0fd4",
  "status": {
    "status": "processed",
    "event": "message-log/create",
    "deliveryMethod": "peppol",
    "updatedAt": "2026-08-19T09:25:37.228Z"
  },
  "error": "Peppol validation failed: invoice does not conform to UBL 2.1",
  "peppol_metadata": {
    "messageId": "9cab8ba5-d2a4-45d0-842d-8ede91dcac9f@QVALIA-PSE000094",
    "accessPoint": "PSE000094",
    "docTypeId": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1",
    "processId": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
    "exchangeDateTime": "2026-08-19T09:25:34.226Z",
    "senderPeppolId": "0007:5560004755",
    "receiverPeppolId": "0007:5567321707"
  }
}

Last updated

Was this helpful?