Document

Create, convert and send documents via the Peppol network.

The Document endpoints handle the full lifecycle: generate UBL XML from various input formats, validate against PEPPOL Schematron rules, and send through the Peppol network.

Looking for a worked example? Examples → BusinessDocument (UBL invoice) walks through a complete cross-border PEPPOL invoice via the standard-agnostic endpoint, in cURL, Java SDK, Python, Node.js and PHP.

List all renditions sharing a processId (sibling lookup)

GET /bizzlink/documents

Returns every document rendition produced by the same create-and-send call, identified by the shared processId. Useful when a single business document is rendered into multiple wire formats (e.g. IT seller → FatturaPA via SDI plus UBL via Peppol) and the caller wants the full picture without polling each rendition id separately.

Tenant-scoped — only renditions owned by the authenticated tenant are returned. Returns an empty data array if no renditions match.

Responses:

StatusDescription
200Sibling renditions
400Invalid direction parameter
cURL Request
curl -X GET https://gateway.vigasoft.lu/bizzlink/documents \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "X-Bizzlink-Signature: t=$TIMESTAMP,v1=$SIGNATURE"

Send a document from a JSON structure

POST /bizzlink/documents/json

Accepts a BusinessDocument (the same model the on-prem connector plugins build) and generates one or more wire-format renditions depending on sender/receiver country and regulatory requirements. The polymorphic @type discriminator (InvoiceDocument / CreditNoteDocument) decides the JSON:API resource type of each response entry (invoices or credit-notes).

The routing layer — based on sender country, receiver country and SMP capabilities — decides which formats/targets the document is rendered into. Examples:

  • LU/AT/BE/NL/DK/SE/IE seller → 1× UBL via Peppol
  • IT seller (any buyer) → FatturaPA via SDI plus UBL via Peppol (when receiver is not IT)
  • FR seller (post-2026-09-01) → Factur-X/UBL via PPF/PDP plus UBL via Peppol (when receiver is not FR)

Response is a JSON:API collection: data is an array with one entry per rendition. Each entry has its own id (= per-rendition document id, pollable via GET /documents/{id}/status); all siblings share the same attributes.processId, looked up via GET /documents?processId={uuid}.

Request Body:

FieldTypeRequiredDescription
dataobjectYesResource envelope. 'attributes' holds the domain fields; 'meta.scope' declares whether the resource belongs to the whole tenant or to a specific legal entity (Peppol ID).
    attributesanyYesThe actual resource fields.
    metaJsonApiMetaNoOptional JSON:API meta. Only used by scoped resources (e.g. email templates, notification emails) to declare their ownership scope.
        scopeJsonApiScopeYes
            typestringYesScope type. 'tenant' = applies to the whole tenant. 'legal-entity' = applies only to the Peppol ID given in 'value'. 'partner' = applies to all child tenants of the calling partner tenant; 'value' must be empty.
            valuestringNoRequired when type='legal-entity': the Peppol ID (scheme:identifier) that owns this resource, e.g. '9938:lu28079289'. Must belong to the requesting tenant. Ignored when type='tenant'. Must be empty when type='partner'.
    typestringNoMust be 'business-documents' for this endpoint.

Responses:

StatusDescription
200Document(s) accepted for async processing
403Sender Peppol ID does not belong to the tenant
422Synchronous XML generation failed or routing target not supported
500Internal server error

Response BodyJsonApiListDocumentDocumentAcceptedAttributes:

FieldTypeDescription
dataJsonApiResourceDocumentAcceptedAttributes[]
    attributesDocumentAcceptedAttributesResource-specific fields.
        formatstringWire format of the generated XML for this rendition.
        processIduuidCorrelation id shared by all renditions produced by the same create call. Use GET /documents?processId={uuid} to retrieve sibling renditions.
        statusstringStatus at the time of acknowledgement. Typically QUEUED_FOR_VALIDATION (awaiting async validation), VALID (when validation was skipped), or FAILED (on synchronous generation/conversion error).
        targetstringDestination network/platform this rendition will be delivered to.
        xmlstringGenerated XML content in the indicated format. Present when generation succeeded.
    idstringUnique resource identifier (UUID). Use this value to poll the status endpoint or to reference the resource in subsequent requests.
    typestringResource type — matches the endpoint (e.g. 'invoices' for POST /documents/invoices, 'documents' for GET /documents/{id}/status).
linksJsonApiLinks
    firststringURL of the first page.
    laststringURL of the last page.
    nextstringURL of the next page, null on last page.
    prevstringURL of the previous page, null on first page.
    selfstringURL of the current page.
metaJsonApiPaginationMeta
    pageinteger1-based index of the current page.
    sizeintegerNumber of items per page.
    totalElementsintegerTotal number of items across all pages.
    totalPagesintegerTotal number of pages.
cURL Request
curl -X POST https://gateway.vigasoft.lu/bizzlink/documents/json \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "X-Bizzlink-Signature: t=$TIMESTAMP,v1=$SIGNATURE" \
  -H "Content-Type: application/json" \
  -d '{
      "data": {}
  }'
Response 200 OK
{
    "data": [
    {
        "attributes": {
          "format": "string",
          "processId": "00000000-0000-0000-0000-000000000000",
          "status": "QUEUED_FOR_VALIDATION",
          "target": "string"
      },
        "id": "770e8400-e29b-41d4-a716-446655440000",
        "type": "invoices"
    }
    ],
    "links": {
      "first": "https://gateway.vigasoft.lu/bizzlink/documents?page%5Bnumber%5D=1&page%5Bsize%5D=20",
      "last": "https://gateway.vigasoft.lu/bizzlink/documents?page%5Bnumber%5D=7&page%5Bsize%5D=20",
      "next": "https://gateway.vigasoft.lu/bizzlink/documents?page%5Bnumber%5D=4&page%5Bsize%5D=20",
      "prev": "https://gateway.vigasoft.lu/bizzlink/documents?page%5Bnumber%5D=2&page%5Bsize%5D=20",
      "self": "https://gateway.vigasoft.lu/bizzlink/documents?page%5Bnumber%5D=3&page%5Bsize%5D=20"
  },
    "meta": {
      "page": 1,
      "size": 20,
      "totalElements": 137,
      "totalPages": 7
  }
}

Send a document from an XML file

POST /bizzlink/documents/xml

Accepts a UBL 2.1 Invoice or Credit Note XML, validates it asynchronously against PEPPOL BIS 3.0 Schematron rules, and sends it into the Peppol network.

Request body is a JSON:API resource envelope with data.type = "ubl-xml". Response shape: JSON:API collection (data: [...]) with one rendition per entry. Each entry’s JSON:API type reflects the detected document kind (invoices or credit-notes).

Poll GET /documents/{id}/status per rendition for the validation/delivery outcome.

Request Body:

FieldTypeRequiredDescription
dataobjectYesResource envelope. 'attributes' holds the domain fields; 'meta.scope' declares whether the resource belongs to the whole tenant or to a specific legal entity (Peppol ID).
    attributesUblDocumentRequestYesThe actual resource fields.
        emailDeliveryEmailDeliveryRequestNoOptional email delivery after successful Peppol transmission
            attachmentsstring[]NoAttachments to include. Valid values: 'pdf', 'xml'. Default: ['pdf']
            bccEmailRecipient[]NoBCC recipients (optional)
                addressstringYesEmail address
                namestringNoDisplay name
            bodyTemplateIduuidNoID of an email body template owned by the sender. If null, a default body is used.
            ccEmailRecipient[]NoCC recipients (optional)
                addressstringYesEmail address
                namestringNoDisplay name
            contextobjectNoCustom template variables that override or extend variables extracted from the UBL XML. Available in subject and body via {{variableName}} placeholders.
            fromEmailRecipientNoCustom sender address. The domain's SPF record must authorize our mail server. If set, the email is sent from this address instead of noreply@bizzlink.lu, and replyTo becomes optional.
                addressstringYesEmail address
                namestringNoDisplay name
            pdfTemplateIduuidNoID of a PDF template owned by the sender. If null, the default Jasper template is used.
            replyToEmailRecipientNoReply-To address. Required if 'from' is not set (since emails default to noreply@bizzlink.lu). Optional if 'from' is provided.
                addressstringYesEmail address
                namestringNoDisplay name
            subjectstringNoEmail subject with optional {{variable}} placeholders. If empty, a default subject is used: 'Invoice {{invoiceNumber}} from {{sellerName}}'
            toEmailRecipient[]YesPrimary recipients (mandatory, at least one)
                addressstringYesEmail address
                namestringNoDisplay name
        skipValidationbooleanNoSkip Schematron validation before sending (default: false)
        ublXmlstringYesUBL 2.1 Invoice or Credit Note XML content
    metaJsonApiMetaNoOptional JSON:API meta. Only used by scoped resources (e.g. email templates, notification emails) to declare their ownership scope.
        scopeJsonApiScopeYes
            typestringYesScope type. 'tenant' = applies to the whole tenant. 'legal-entity' = applies only to the Peppol ID given in 'value'. 'partner' = applies to all child tenants of the calling partner tenant; 'value' must be empty.
            valuestringNoRequired when type='legal-entity': the Peppol ID (scheme:identifier) that owns this resource, e.g. '9938:lu28079289'. Must belong to the requesting tenant. Ignored when type='tenant'. Must be empty when type='partner'.
    typestringNoMust be 'ubl-xml' for this endpoint.

Responses:

StatusDescription
200Document accepted for async processing
403Sender Peppol ID does not belong to the tenant
422Synchronous processing failed
500Internal server error

Response BodyJsonApiListDocumentDocumentAcceptedAttributes:

FieldTypeDescription
dataJsonApiResourceDocumentAcceptedAttributes[]
    attributesDocumentAcceptedAttributesResource-specific fields.
        formatstringWire format of the generated XML for this rendition.
        processIduuidCorrelation id shared by all renditions produced by the same create call. Use GET /documents?processId={uuid} to retrieve sibling renditions.
        statusstringStatus at the time of acknowledgement. Typically QUEUED_FOR_VALIDATION (awaiting async validation), VALID (when validation was skipped), or FAILED (on synchronous generation/conversion error).
        targetstringDestination network/platform this rendition will be delivered to.
        xmlstringGenerated XML content in the indicated format. Present when generation succeeded.
    idstringUnique resource identifier (UUID). Use this value to poll the status endpoint or to reference the resource in subsequent requests.
    typestringResource type — matches the endpoint (e.g. 'invoices' for POST /documents/invoices, 'documents' for GET /documents/{id}/status).
linksJsonApiLinks
    firststringURL of the first page.
    laststringURL of the last page.
    nextstringURL of the next page, null on last page.
    prevstringURL of the previous page, null on first page.
    selfstringURL of the current page.
metaJsonApiPaginationMeta
    pageinteger1-based index of the current page.
    sizeintegerNumber of items per page.
    totalElementsintegerTotal number of items across all pages.
    totalPagesintegerTotal number of pages.
cURL Request
curl -X POST https://gateway.vigasoft.lu/bizzlink/documents/xml \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "X-Bizzlink-Signature: t=$TIMESTAMP,v1=$SIGNATURE" \
  -H "Content-Type: application/json" \
  -d '{
      "data": {}
  }'
Response 200 OK
{
    "data": [
    {
        "attributes": {
          "format": "string",
          "processId": "00000000-0000-0000-0000-000000000000",
          "status": "QUEUED_FOR_VALIDATION",
          "target": "string"
      },
        "id": "770e8400-e29b-41d4-a716-446655440000",
        "type": "invoices"
    }
    ],
    "links": {
      "first": "https://gateway.vigasoft.lu/bizzlink/documents?page%5Bnumber%5D=1&page%5Bsize%5D=20",
      "last": "https://gateway.vigasoft.lu/bizzlink/documents?page%5Bnumber%5D=7&page%5Bsize%5D=20",
      "next": "https://gateway.vigasoft.lu/bizzlink/documents?page%5Bnumber%5D=4&page%5Bsize%5D=20",
      "prev": "https://gateway.vigasoft.lu/bizzlink/documents?page%5Bnumber%5D=2&page%5Bsize%5D=20",
      "self": "https://gateway.vigasoft.lu/bizzlink/documents?page%5Bnumber%5D=3&page%5Bsize%5D=20"
  },
    "meta": {
      "page": 1,
      "size": 20,
      "totalElements": 137,
      "totalPages": 7
  }
}

Get document processing status

GET /bizzlink/documents/{documentId}/status

Returns the current processing status of a document as a JSON:API resource. Use this endpoint to poll the status of asynchronously processed documents.

Possible attributes.status values:

  • ACCEPTED — Document received and saved
  • QUEUED_FOR_VALIDATION — Waiting for Schematron validation
  • VALID — Passed validation
  • INVALID — Failed validation (see attributes.errors)
  • QUEUED_FOR_SENDING — Waiting for Peppol transmission
  • SENT — Transmitted to Peppol network
  • DELIVERED — Delivery confirmed
  • FAILED — Processing failed

Responses:

StatusDescription
200Document status retrieved
403Document belongs to a different tenant
404Document not found

Response BodyJsonApiDocumentDocumentAttributes:

FieldTypeDescription
dataJsonApiResourceDocumentAttributes
    attributesDocumentAttributesResource-specific fields.
        acknowledgementStatusstringAcknowledgement outcome of a sent document: SUCCESS (AS4 receipt / positive MLS AP/AB) or FAILURE (send failure / negative MLS RE). Null until acknowledged.
        createdAtdatetimeTimestamp when the document was first accepted.
        errorsValidationError[]Validation errors. Populated after async Schematron validation completes with status INVALID. Null otherwise.
            flagstringRaw schematron severity flag id (e.g. fatal_error, warn)
            idstringSchematron rule ID
            locationstringXPath location of the error in the XML
            severitystringParsed severity; ERROR/FATAL_ERROR block sending, WARNING/INFO do not
            textstringHuman-readable error message
        formatstringWire format of the stored XML.
        processIduuidCorrelation id shared by all renditions produced by the same create call. Use GET /documents?processId={uuid} to retrieve sibling renditions.
        statusstringSymbolic status. Typical values: ACCEPTED, QUEUED_FOR_VALIDATION, VALID, INVALID, QUEUED_FOR_SENDING, SENT, DELIVERED, FAILED.
        targetstringDestination network/platform this rendition was/will be delivered to.
        updatedAtdatetimeTimestamp of the most recent state change.
    idstringUnique resource identifier (UUID). Use this value to poll the status endpoint or to reference the resource in subsequent requests.
    typestringResource type — matches the endpoint (e.g. 'invoices' for POST /documents/invoices, 'documents' for GET /documents/{id}/status).
cURL Request
curl -X GET https://gateway.vigasoft.lu/bizzlink/documents/{documentId}/status \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "X-Bizzlink-Signature: t=$TIMESTAMP,v1=$SIGNATURE"
Response 200 OK
{
    "data": {
      "attributes": {
        "acknowledgementStatus": "SUCCESS",
        "createdAt": "2026-01-01T00:00:00Z",
        "errors": [
        {
            "flag": "fatal_error",
            "id": "BR-01",
            "location": "/Invoice/cac:AccountingSupplierParty",
            "severity": "FATAL_ERROR",
            "text": "An Invoice shall have a Specification identifier"
        }
        ],
        "format": "string",
        "processId": "00000000-0000-0000-0000-000000000000",
        "status": "VALID",
        "target": "string",
        "updatedAt": "2026-01-01T00:00:00Z"
    },
      "id": "770e8400-e29b-41d4-a716-446655440000",
      "type": "invoices"
  }
}