Peppolpdf Docs

Generate PDF

POST /api/v1/generate-pdf — upload a Peppol BIS 3.0 XML file and receive a binary PDF download.

Generate PDF

POST /api/v1/generate-pdf

Accepts a multipart/form-data request containing a Peppol BIS 3.0 XML file and returns a binary PDF download.

Request

Headers

HeaderValueRequired
AuthorizationBearer <your_api_key>Yes

Form fields

FieldTypeRequiredDescription
filefileYesPeppol BIS 3.0 XML file to convert
configstringNoJSON object with generation options (see below)

The config field must be sent as a JSON string. When omitted, defaults to {"locale":"en"}.

Config options

{
  "locale": "en",
  "preset": "accountant",
  "fields": { ... }
}
FieldTypeDefaultDescription
localestringenLocale code for label translation. Supported: en, nl, fr
presetstringPredefined field mapping preset. One of accountant or administration. Mutually exclusive with fields
fieldsobjectGranular field visibility control. Mutually exclusive with preset

Presets

PresetDescription
accountantFields relevant for accounting purposes
administrationFields relevant for administrative purposes

Fields

Use fields to show or hide individual Peppol BIS 3.0 data fields in the generated PDF. Each key maps to a Peppol element and accepts a boolean (true to include, false to exclude). Nested objects allow fine-grained control over sub-fields.

Document header

FieldBT / BGDescription
CustomizationIDBT-24Specification identifier
ProfileIDBT-23Business process type
IDBT-1Invoice number
IssueDateBT-2Invoice issue date
DueDateBT-9Payment due date
InvoiceTypeCodeBT-3Invoice type code (e.g. 380)
NoteBT-22Invoice note
TaxPointDateBT-7Value added tax point date
DocumentCurrencyCodeBT-5Invoice currency code
TaxCurrencyCodeBT-6VAT accounting currency code
AccountingCostBT-19Buyer accounting reference
BuyerReferenceBT-10Buyer reference
PaymentTermsBT-20Payment terms

Document references

FieldBT / BGDescription
BillingReferenceBG-3Preceding invoice references
DespatchDocumentReferenceBT-16Despatch advice reference
ReceiptDocumentReferenceBT-15Receipt advice reference
OriginatorDocumentReferenceBT-17Tender or lot reference
ContractDocumentReferenceBT-12Contract reference
AdditionalDocumentReferenceBG-24Additional supporting documents
ProjectReferenceBT-11Project reference
InvoicePeriod

BG-14 — Invoicing period

InvoicePeriod accepts false or an object with sub-fields:

Sub-fieldBTDescription
StartDateBT-73Invoicing period start date
EndDateBT-74Invoicing period end date
DescriptionCodeBT-8Value added tax point date code
OrderReference

OrderReference accepts false or an object:

Sub-fieldBTDescription
IDBT-13Purchase order reference
SalesOrderIDBT-14Sales order reference

Parties

AccountingSupplierParty / AccountingCustomerParty

BG-4 — Seller / BG-7 — Buyer

AccountingSupplierParty (BG-4 — Seller) and AccountingCustomerParty (BG-7 — Buyer) each accept false or an object containing a Party sub-object with these fields:

Sub-fieldBTDescription
EndpointIDBT-34 / BT-49Electronic address (incl. scheme)
PartyIdentificationBT-29 / BT-46Identifier(s) (incl. scheme)
PartyNameBT-27 / BT-44Name / trading name
PostalAddressfalse or object — see sub-fields below
PartyTaxSchemeBT-31 / BT-48VAT identifier / tax registration identifier
PartyLegalEntityfalse or object — see sub-fields below
ContactBG-6 / BG-9false or object — see sub-fields below

PostalAddress sub-fields:

Sub-fieldDescription
StreetNameStreet name
AdditionalStreetNameAdditional street name
CityNameCity
PostalZonePost code
CountrySubentityCountry subdivision
AddressLine.LineAdditional address line
Country.IdentificationCodeCountry code

PartyLegalEntity sub-fields:

Sub-fieldBTDescription
RegistrationNameBT-27 / BT-44Legal registration name
CompanyIDBT-30 / BT-47Legal registration identifier
CompanyLegalFormBT-33 (seller only)Additional legal information

Contact sub-fields:

Sub-fieldDescription
NameContact name
TelephonePhone number
ElectronicMailEmail address
PayeeParty

BG-10 — Payee

PayeeParty accepts false or an object:

Sub-fieldBTDescription
PartyIdentificationBT-60Payee identifier (incl. scheme)
PartyNameBT-59Payee name
PartyLegalEntityBT-61Payee legal registration identifier
TaxRepresentativeParty

BG-11 — Seller tax representative party

TaxRepresentativeParty accepts false or an object:

Sub-fieldBTDescription
PartyNameBT-62Seller tax representative name
PostalAddressfalse or object — same sub-fields as PostalAddress above
PartyTaxSchemefalse or object — see sub-fields below

PartyTaxScheme sub-fields:

Sub-fieldBTDescription
CompanyIDBT-63Seller tax representative VAT identifier
TaxSchemeObject with ID (boolean)

Delivery

Delivery

BG-13 — Delivery information

Delivery accepts false or an object:

Sub-fieldBTDescription
ActualDeliveryDateBT-72Actual delivery date
DeliveryPartyBT-70Deliver to party name
DeliveryLocationBG-15false or object — see sub-fields below

DeliveryLocation sub-fields:

Sub-fieldBTDescription
IDBT-71Deliver to location identifier (incl. scheme BT-71-1)
Addressfalse or object — same sub-fields as PostalAddress above

Payment

PaymentMeans

BG-16 — Payment instructions

PaymentMeans accepts false or an object:

Sub-fieldBTDescription
PaymentMeansCodeBT-81Payment means type code (incl. BT-82 name)
PaymentIDBT-83Remittance information
PayeeFinancialAccountBG-17Credit transfer (IBAN, bank name, etc.)
CardAccountBG-18Payment card information
PaymentMandateBG-19Direct debit (mandate reference, debited account)
AllowanceCharge

BG-20 — Document level allowances / BG-21 — Document level charges

AllowanceCharge accepts false or an object:

Sub-fieldBTDescription
AllowanceChargeReasonCodeBT-98/BT-140Reason code
AllowanceChargeReasonBT-97/BT-139Reason text
MultiplierFactorNumericBT-94/BT-138Percentage
AmountBT-92/BT-137Amount
BaseAmountBT-93/BT-138Base amount
TaxCategoryfalse or object — see sub-fields below

TaxCategory sub-fields:

Sub-fieldBTDescription
IDBT-95/BT-102VAT category code
PercentBT-96/BT-103VAT rate
TaxSchemeObject with ID (boolean)

Tax and totals

TaxTotal

BG-22 — VAT breakdown

TaxTotal accepts false or an object:

Sub-fieldBTDescription
TaxAmountBT-110/BT-111Invoice total VAT amount
TaxSubtotalBG-23false or object — see sub-fields below

TaxSubtotal sub-fields (BG-23 — VAT breakdown row):

Sub-fieldBTDescription
TaxableAmountBT-116VAT category taxable amount
TaxAmountBT-117VAT category tax amount
TaxCategoryfalse or object — see sub-fields below

TaxSubtotal.TaxCategory sub-fields:

Sub-fieldBTDescription
IDBT-118VAT category code
PercentBT-119VAT category rate
TaxExemptionReasonCodeBT-121VAT exemption reason code
TaxExemptionReasonBT-120VAT exemption reason text
TaxSchemeObject with ID (boolean)
LegalMonetaryTotal

BG-22 — Document totals

LegalMonetaryTotal accepts false or an object:

Sub-fieldBTDescription
LineExtensionAmountBT-106Sum of invoice line net amounts
AllowanceTotalAmountBT-107Sum of allowances on document level
ChargeTotalAmountBT-108Sum of charges on document level
TaxExclusiveAmountBT-109Invoice total amount without VAT
TaxInclusiveAmountBT-112Invoice total amount with VAT
PrepaidAmountBT-113Paid amount
PayableRoundingAmountBT-114Rounding amount
PayableAmountBT-115Amount due for payment

Invoice lines

InvoiceLine

BG-25 — Invoice line

InvoiceLine accepts false or an object:

Sub-fieldBTDescription
IDBT-126Invoice line identifier
NoteBT-127Invoice line note
InvoicedQuantityBT-129 / BT-130Invoiced quantity / unit of measure
LineExtensionAmountBT-131Invoice line net amount
AccountingCostBT-133Invoice line buyer accounting reference
InvoicePeriodBG-26false or object — see sub-fields below
OrderLineReferencefalse or object — see sub-fields below
DocumentReferencefalse or object — see sub-fields below
AllowanceChargeBG-27 / BG-28false or object — see sub-fields below
ItemBG-31false or object — see sub-fields below
PriceBG-29false or object — see sub-fields below

InvoicePeriod sub-fields (BG-26 — Invoice line period):

Sub-fieldBTDescription
StartDateBT-134Invoice line period start date
EndDateBT-135Invoice line period end date

OrderLineReference sub-fields:

Sub-fieldBTDescription
LineIDBT-132Referenced purchase order line reference

DocumentReference sub-fields:

Sub-fieldBTDescription
IDBT-128Invoice line object identifier (incl. scheme)
DocumentTypeCodeDocument type code

AllowanceCharge sub-fields (BG-27 / BG-28 — Invoice line allowances / charges):

Sub-fieldBTDescription
ChargeIndicatortrue for charge, false for allowance
AllowanceChargeReasonCodeBT-140 / BT-145Reason code
AllowanceChargeReasonBT-139 / BT-144Reason text
MultiplierFactorNumericBT-138 / BT-143Percentage
AmountBT-136 / BT-141Amount
BaseAmountBase amount

Item sub-fields (BG-31 — Item information):

Sub-fieldBTDescription
NameBT-153Item name
DescriptionBT-154Item description
SellersItemIdentification.IDBT-155Item seller's identifier
BuyersItemIdentification.IDBT-156Item buyer's identifier
StandardItemIdentification.IDBT-157Item standard identifier (incl. scheme BT-157-1)
OriginCountry.IdentificationCodeBT-159Item country of origin
CommodityClassificationBT-158Item classification identifier
ClassifiedTaxCategoryBG-30false or object — see sub-fields below
AdditionalItemPropertyBG-32Item attributes (name/value pairs)

ClassifiedTaxCategory sub-fields (BG-30 — Line VAT information):

Sub-fieldBTDescription
IDBT-151Invoiced item VAT category code
PercentBT-152Invoiced item VAT rate
TaxSchemeObject with ID (boolean)

Price sub-fields (BG-29 — Price details):

Sub-fieldBTDescription
PriceAmountBT-146Item net price
BaseQuantityBT-149 / BT-150Item price base quantity / unit code
AllowanceChargefalse or object — see sub-fields below

Price.AllowanceCharge sub-fields:

Sub-fieldBTDescription
ChargeIndicatorShould be false (discount)
AmountBT-147Item price discount
BaseAmountBT-148Item gross price

Response

200 — Success

Returns a binary PDF download.

Content-Type: application/pdf

400 — Bad request

{
  "error": "string"
}

Returned when the file is missing, the XML is invalid, or the document type is not supported.

401 — Unauthorized

{
  "error": "string"
}

Returned when the API key is missing or invalid.

Examples

Basic — download PDF

curl -X POST "https://api.peppolpdf.eu/api/v1/generate-pdf" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@invoice.xml" \
  -o invoice.pdf
generate-pdf.ts
import fs from "fs";

const form = new FormData();
form.append("file", new Blob([fs.readFileSync("invoice.xml")], { type: "application/xml" }), "invoice.xml");
form.append("config", JSON.stringify({ locale: "en" }));

const res = await fetch("https://api.peppolpdf.eu/api/v1/generate-pdf", {
  method: "POST",
  headers: { "Authorization": `Bearer ${process.env.PEPPOLPDF_API_KEY!}` },
  body: form,
});

if (!res.ok) {
  const { error } = await res.json();
  throw new Error(error);
}

fs.writeFileSync("invoice.pdf", Buffer.from(await res.arrayBuffer()));
generate_pdf.py
import os
import requests

with open("invoice.xml", "rb") as f:
    response = requests.post(
        "https://api.peppolpdf.eu/api/v1/generate-pdf",
        headers={"Authorization": f"Bearer {os.environ['PEPPOLPDF_API_KEY']}"},
        files={"file": ("invoice.xml", f, "application/xml")},
    )

response.raise_for_status()

with open("invoice.pdf", "wb") as f:
    f.write(response.content)
generate_pdf.php
<?php

$curl = curl_init('https://api.peppolpdf.eu/api/v1/generate-pdf');

curl_setopt_array($curl, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . getenv('PEPPOLPDF_API_KEY')],
    CURLOPT_POSTFIELDS     => [
        'file' => new CURLFile('invoice.xml', 'application/xml', 'invoice.xml'),
    ],
]);

$pdf      = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);

if ($httpCode !== 200) {
    throw new RuntimeException('API error: ' . $pdf);
}

file_put_contents('invoice.pdf', $pdf);
main.go
package main

import (
	"bytes"
	"io"
	"mime/multipart"
	"net/http"
	"os"
)

func main() {
	file, _ := os.Open("invoice.xml")
	defer file.Close()

	var body bytes.Buffer
	writer := multipart.NewWriter(&body)
	part, _ := writer.CreateFormFile("file", "invoice.xml")
	io.Copy(part, file)
	writer.Close()

	req, _ := http.NewRequest(http.MethodPost, "https://api.peppolpdf.eu/api/v1/generate-pdf", &body)
	req.Header.Set("Authorization", "Bearer " + os.Getenv("PEPPOLPDF_API_KEY"))
	req.Header.Set("Content-Type", writer.FormDataContentType())

	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()

	out, _ := os.Create("invoice.pdf")
	defer out.Close()
	io.Copy(out, resp.Body)
}
GeneratePdf.cs
using var fileStream = File.OpenRead("invoice.xml");
using var content = new MultipartFormDataContent
{
    { new StreamContent(fileStream), "file", "invoice.xml" },
};

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + Environment.GetEnvironmentVariable("PEPPOLPDF_API_KEY"));

var response = await client.PostAsync("https://api.peppolpdf.eu/api/v1/generate-pdf", content);
response.EnsureSuccessStatusCode();

var pdf = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("invoice.pdf", pdf);
GeneratePdf.java
import okhttp3.*;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;

var client = new OkHttpClient();

var body = new MultipartBody.Builder()
    .setType(MultipartBody.FORM)
    .addFormDataPart("file", "invoice.xml",
        RequestBody.create(new File("invoice.xml"), MediaType.parse("application/xml")))
    .build();

var request = new Request.Builder()
    .url("https://api.peppolpdf.eu/api/v1/generate-pdf")
    .addHeader("Authorization", "Bearer " + System.getenv("PEPPOLPDF_API_KEY"))
    .post(body)
    .build();

try (var response = client.newCall(request).execute()) {
    if (!response.isSuccessful()) throw new IOException("API error: " + response);
    Files.write(Path.of("invoice.pdf"), response.body().bytes());
}

With locale and preset

curl -X POST "https://api.peppolpdf.eu/api/v1/generate-pdf" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@invoice.xml" \
  -F 'config={"preset":"administration","locale":"nl"}' \
  -o invoice.pdf
generate-pdf.ts
import fs from "fs";

const form = new FormData();
form.append("file", new Blob([fs.readFileSync("invoice.xml")], { type: "application/xml" }), "invoice.xml");
form.append("config", JSON.stringify({ preset: "administration", locale: "nl" }));

const res = await fetch("https://api.peppolpdf.eu/api/v1/generate-pdf", {
  method: "POST",
  headers: { "Authorization": `Bearer ${process.env.PEPPOLPDF_API_KEY!}` },
  body: form,
});

if (!res.ok) {
  const { error } = await res.json();
  throw new Error(error);
}

fs.writeFileSync("invoice.pdf", Buffer.from(await res.arrayBuffer()));
generate_pdf.py
import os
import json
import requests

with open("invoice.xml", "rb") as f:
    response = requests.post(
        "https://api.peppolpdf.eu/api/v1/generate-pdf",
        headers={"Authorization": f"Bearer {os.environ['PEPPOLPDF_API_KEY']}"},
        files={"file": ("invoice.xml", f, "application/xml")},
        data={"config": json.dumps({"preset": "administration", "locale": "nl"})},
    )

response.raise_for_status()

with open("invoice.pdf", "wb") as f:
    f.write(response.content)
generate_pdf.php
<?php

$curl = curl_init('https://api.peppolpdf.eu/api/v1/generate-pdf');

curl_setopt_array($curl, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . getenv('PEPPOLPDF_API_KEY')],
    CURLOPT_POSTFIELDS     => [
        'file'   => new CURLFile('invoice.xml', 'application/xml', 'invoice.xml'),
        'config' => json_encode(['preset' => 'all', 'locale' => 'nl']),
    ],
]);

$pdf      = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);

if ($httpCode !== 200) {
    throw new RuntimeException('API error: ' . $pdf);
}

file_put_contents('invoice.pdf', $pdf);
main.go
package main

import (
	"bytes"
	"io"
	"mime/multipart"
	"net/http"
	"os"
)

func main() {
	file, _ := os.Open("invoice.xml")
	defer file.Close()

	var body bytes.Buffer
	writer := multipart.NewWriter(&body)
	part, _ := writer.CreateFormFile("file", "invoice.xml")
	io.Copy(part, file)
	writer.WriteField("config", `{"preset":"administration","locale":"nl"}`)
	writer.Close()

	req, _ := http.NewRequest(http.MethodPost, "https://api.peppolpdf.eu/api/v1/generate-pdf", &body)
	req.Header.Set("Authorization", "Bearer " + os.Getenv("PEPPOLPDF_API_KEY"))
	req.Header.Set("Content-Type", writer.FormDataContentType())

	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()

	out, _ := os.Create("invoice.pdf")
	defer out.Close()
	io.Copy(out, resp.Body)
}
GeneratePdf.cs
using var fileStream = File.OpenRead("invoice.xml");
using var content = new MultipartFormDataContent
{
    { new StreamContent(fileStream), "file", "invoice.xml" },
    { new StringContent("""{ \"preset\":\"administration\",\"locale\":\"nl\"}"""), "config" },
};

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + Environment.GetEnvironmentVariable("PEPPOLPDF_API_KEY"));

var response = await client.PostAsync("https://api.peppolpdf.eu/api/v1/generate-pdf", content);
response.EnsureSuccessStatusCode();

var pdf = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("invoice.pdf", pdf);
GeneratePdf.java
import okhttp3.*;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;

var client = new OkHttpClient();

var body = new MultipartBody.Builder()
    .setType(MultipartBody.FORM)
    .addFormDataPart("file", "invoice.xml",
        RequestBody.create(new File("invoice.xml"), MediaType.parse("application/xml")))
    .addFormDataPart("config", "{\"preset\":\"administration\",\"locale\":\"nl\"}")
    .build();

var request = new Request.Builder()
    .url("https://api.peppolpdf.eu/api/v1/generate-pdf")
    .addHeader("Authorization", "Bearer " + System.getenv("PEPPOLPDF_API_KEY"))
    .post(body)
    .build();

try (var response = client.newCall(request).execute()) {
    if (!response.isSuccessful()) throw new IOException("API error: " + response);
    Files.write(Path.of("invoice.pdf"), response.body().bytes());
}

With granular field control

curl -X POST "https://api.peppolpdf.eu/api/v1/generate-pdf" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@invoice.xml" \
  -F 'config={"locale":"en","fields":{"ID":true,"IssueDate":true,"DueDate":true,"LegalMonetaryTotal":true,"InvoiceLine":true}}' \
  -o invoice.pdf
generate-pdf.ts
import fs from "fs";

const config = {
  locale: "en",
  fields: {
    ID: true,
    IssueDate: true,
    DueDate: true,
    AccountingSupplierParty: {
      Party: { PartyName: true, PostalAddress: true, PartyTaxScheme: true },
    },
    AccountingCustomerParty: {
      Party: { PartyName: true, PostalAddress: true },
    },
    LegalMonetaryTotal: true,
    InvoiceLine: true,
  },
};

const form = new FormData();
form.append("file", new Blob([fs.readFileSync("invoice.xml")], { type: "application/xml" }), "invoice.xml");
form.append("config", JSON.stringify(config));

const res = await fetch("https://api.peppolpdf.eu/api/v1/generate-pdf", {
  method: "POST",
  headers: { "Authorization": `Bearer ${process.env.PEPPOLPDF_API_KEY!}` },
  body: form,
});

if (!res.ok) {
  const { error } = await res.json();
  throw new Error(error);
}

fs.writeFileSync("invoice.pdf", Buffer.from(await res.arrayBuffer()));
generate_pdf.py
import os
import json
import requests

config = {
    "locale": "en",
    "fields": {
        "ID": True,
        "IssueDate": True,
        "DueDate": True,
        "AccountingSupplierParty": {
            "Party": {"PartyName": True, "PostalAddress": True, "PartyTaxScheme": True}
        },
        "AccountingCustomerParty": {
            "Party": {"PartyName": True, "PostalAddress": True}
        },
        "LegalMonetaryTotal": True,
        "InvoiceLine": True,
    },
}

with open("invoice.xml", "rb") as f:
    response = requests.post(
        "https://api.peppolpdf.eu/api/v1/generate-pdf",
        headers={"Authorization": f"Bearer {os.environ['PEPPOLPDF_API_KEY']}"},
        files={"file": ("invoice.xml", f, "application/xml")},
        data={"config": json.dumps(config)},
    )

response.raise_for_status()

with open("invoice.pdf", "wb") as f:
    f.write(response.content)
generate_pdf.php
<?php

$config = [
    'locale' => 'en',
    'fields' => [
        'ID'        => true,
        'IssueDate' => true,
        'DueDate'   => true,
        'AccountingSupplierParty' => [
            'Party' => ['PartyName' => true, 'PostalAddress' => true, 'PartyTaxScheme' => true],
        ],
        'AccountingCustomerParty' => [
            'Party' => ['PartyName' => true, 'PostalAddress' => true],
        ],
        'LegalMonetaryTotal' => true,
        'InvoiceLine'        => true,
    ],
];

$curl = curl_init('https://api.peppolpdf.eu/api/v1/generate-pdf');

curl_setopt_array($curl, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . getenv('PEPPOLPDF_API_KEY')],
    CURLOPT_POSTFIELDS     => [
        'file'   => new CURLFile('invoice.xml', 'application/xml', 'invoice.xml'),
        'config' => json_encode($config),
    ],
]);

$pdf      = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);

if ($httpCode !== 200) {
    throw new RuntimeException('API error: ' . $pdf);
}

file_put_contents('invoice.pdf', $pdf);
main.go
package main

import (
	"bytes"
	"encoding/json"
	"io"
	"mime/multipart"
	"net/http"
	"os"
)

func main() {
	config, _ := json.Marshal(map[string]any{
		"locale": "en",
		"fields": map[string]any{
			"ID": true, "IssueDate": true, "DueDate": true,
			"LegalMonetaryTotal": true, "InvoiceLine": true,
		},
	})

	file, _ := os.Open("invoice.xml")
	defer file.Close()

	var body bytes.Buffer
	writer := multipart.NewWriter(&body)
	part, _ := writer.CreateFormFile("file", "invoice.xml")
	io.Copy(part, file)
	writer.WriteField("config", string(config))
	writer.Close()

	req, _ := http.NewRequest(http.MethodPost, "https://api.peppolpdf.eu/api/v1/generate-pdf", &body)
	req.Header.Set("Authorization", "Bearer " + os.Getenv("PEPPOLPDF_API_KEY"))
	req.Header.Set("Content-Type", writer.FormDataContentType())

	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()

	out, _ := os.Create("invoice.pdf")
	defer out.Close()
	io.Copy(out, resp.Body)
}
GeneratePdf.cs
var config = new {
    locale = "en",
    fields = new {
        ID = true, IssueDate = true, DueDate = true,
        AccountingSupplierParty = new { Party = new { PartyName = true, PostalAddress = true, PartyTaxScheme = true } },
        AccountingCustomerParty = new { Party = new { PartyName = true, PostalAddress = true } },
        LegalMonetaryTotal = true,
        InvoiceLine = true,
    },
};

using var fileStream = File.OpenRead("invoice.xml");
using var content = new MultipartFormDataContent
{
    { new StreamContent(fileStream), "file", "invoice.xml" },
    { new StringContent(JsonSerializer.Serialize(config)), "config" },
};

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + Environment.GetEnvironmentVariable("PEPPOLPDF_API_KEY"));

var response = await client.PostAsync("https://api.peppolpdf.eu/api/v1/generate-pdf", content);
response.EnsureSuccessStatusCode();

var pdf = await response.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("invoice.pdf", pdf);
GeneratePdf.java
import okhttp3.*;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;

var config = """
    {"locale":"en","fields":{"ID":true,"IssueDate":true,
    "DueDate":true,"LegalMonetaryTotal":true,"InvoiceLine":true}}
    """;

var client = new OkHttpClient();

var body = new MultipartBody.Builder()
    .setType(MultipartBody.FORM)
    .addFormDataPart("file", "invoice.xml",
        RequestBody.create(new File("invoice.xml"), MediaType.parse("application/xml")))
    .addFormDataPart("config", config)
    .build();

var request = new Request.Builder()
    .url("https://api.peppolpdf.eu/api/v1/generate-pdf")
    .addHeader("Authorization", "Bearer " + System.getenv("PEPPOLPDF_API_KEY"))
    .post(body)
    .build();

try (var response = client.newCall(request).execute()) {
    if (!response.isSuccessful()) throw new IOException("API error: " + response);
    Files.write(Path.of("invoice.pdf"), response.body().bytes());
}

On this page