API Documentation
Integrate invoicing capabilities directly into your application
Authentication
All API requests require an API key to be included in the header of the request:
x-api-key: YOUR_API_KEYPro-tip: API keys are business-scoped. Any signed-in owner of a business can generate and manage them viaBusinesses > select a business > API Keys.
/api/v1/invoices/xrechnung
This endpoint generates an XRechnung XML document from a JSON payload and validates it before returning the result. It is intended for German and EN 16931 compatible B2B and B2G invoicing flows.
Successful generation with valid validation returns 201 Created. If the request payload is valid but the generated document fails validation, the API returns 422 Unprocessable Content and includes the generated XML together with validation errors.
Request Body (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
| schema_version | string | No | Default is "1". |
| invoice_number | string | Yes | Unique invoice ID. |
| buyer_reference | string | No | Optional buyer or routing reference. Strongly recommended for PEPPOL. |
| order_reference | string | No | Optional order or purchase order reference. Strongly recommended for PEPPOL. |
| issue_date | string | Yes | Format: YYYY-MM-DD. |
| due_date | string | No | Recommended for positive-payable invoices. Format: YYYY-MM-DD. |
| currency | string | Yes | e.g. EUR, USD. |
| seller | object | Yes | Supplier information. See nested object reference below for supported fields. |
| buyer | object | Yes | Customer information. See nested object reference below for supported fields. |
| line_items | array | Yes | Invoice lines. See nested object reference below for supported fields. Monetary values use major currency units, e.g. 150.00 EUR, not cents. |
| totals | object | No | Invoice totals. See nested object reference below. Monetary values use major currency units, e.g. 1785.00, not 178500. |
| payment | object | No | Payment account details. See nested object reference below for supported fields. |
Nested Object Reference
seller
Issuer of the invoice. This data is used for supplier party information in the generated e-invoice.
Legal or trading name of the seller.
Street and house number.
City or locality.
Postal or ZIP code.
Two-letter ISO country code, for example DE or FR.
VAT identifier used for tax and party identification.
Optional PEPPOL participant identifier for the seller.
Optional PEPPOL participant scheme identifier, for example 9930.
Seller contact email. Required for some formats and useful fallback endpoint data.
Seller contact phone number.
buyer
Invoice recipient or customer. This becomes the customer party in the generated document.
Legal or trading name of the buyer.
Street and house number.
City or locality.
Postal or ZIP code.
Two-letter ISO country code.
VAT identifier when available.
Optional PEPPOL participant identifier for the buyer.
Optional PEPPOL participant scheme identifier for the buyer.
Buyer email when available.
line_items[]
Each array entry represents one invoice line. Amounts are passed in major currency units, not cents.
Human-readable item or service description.
Billed quantity for the line item.
Unit price in normal currency units, for example 150.00.
Line total in normal currency units, usually quantity multiplied by price before invoice-level adjustments.
VAT percentage for the line, for example 19 or 0.
UNECE unit code such as HUR for hours or C62 for pieces.
totals
Invoice totals in major currency units. These should match the sum of your line items and taxes.
Net amount before tax.
Total tax amount.
Grand total including tax.
payment
Optional payment account details shown in the generated invoice when available.
Bank account IBAN for invoice payment.
BIC or SWIFT code for the receiving bank.
Response Structure
| Field | Description |
|---|---|
| id | Generated local identifier for the response payload. |
| xml_base64 | Base64-encoded version of the generated XRechnung XML. |
| xml | Generated XRechnung XML as a plain string. |
| format | E-invoice format identifier. The public XRechnung endpoint currently returns UBL. |
| schema_version | Schema version echoed back from the request, defaulting to 1. |
| validation | Validation result object containing valid, errors, and warnings. |
| warnings | Top-level warnings array mirrored from the validation result for convenience. |
| code | Present only on validation failure. Currently returned as VALIDATION_FAILED. |
| message | Present only on validation failure and describes why the document received a 422 response. |
Example Request (cURL)
All monetary fields such as price, total, totals.net, totals.tax, and totals.gross are expected in normal currency units, not cents.
curl -X POST https://www.quotecash.io/api/v1/invoices/xrechnung -H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"schema_version": "1",
"invoice_number": "INV-2024-001",
"issue_date": "2024-03-14",
"due_date": "2024-03-28",
"currency": "EUR",
"seller": {
"name": "Acme Corp",
"street": "123 Seller St",
"city": "Berlin",
"postal_code": "10115",
"country": "DE",
"vat_id": "DE123456789"
},
"buyer": {
"name": "Global Client",
"street": "456 Buyer Rd",
"city": "Munich",
"postal_code": "80331",
"country": "DE",
"vat_id": "DE987654321"
},
"line_items": [
{
"description": "API Consulting",
"quantity": 10,
"price": 150,
"total": 1500,
"unitCode": "HUR",
"vatRate": 19
}
],
"totals": {
"net": 1500,
"tax": 285,
"gross": 1785
},
"payment": {
"iban": "DE12345678901234567890",
"bic": "ABCDEFGHXXX"
}
}'Example Response (201)
{
"id": "local-1710412800000",
"xml_base64": "PEludm9pY2UgLi4uPg==",
"xml": "<Invoice ...>",
"format": "UBL",
"schema_version": "1",
"validation": {
"valid": true,
"errors": [],
"warnings": []
},
"warnings": []
}Example Response (422)
{
"code": "VALIDATION_FAILED",
"message": "Generated document failed KoSIT validation",
"id": "local-1710412800000",
"xml_base64": "PEludm9pY2UgLi4uPg==",
"xml": "<Invoice ...>",
"format": "UBL",
"schema_version": "1",
"validation": {
"valid": false,
"errors": [
{
"rule": "BR-DE-1",
"message": "Example validation rule failure returned for an invalid XRechnung payload or generated document."
}
],
"warnings": []
},
"warnings": []
}/api/v1/invoices/peppol
This endpoint generates a PEPPOL BIS Billing 3.0 UBL invoice and validates it before returning the XML payload and validation result. It is intended for PEPPOL-compatible invoicing flows where EN 16931 UBL output is required.
Successful generation with valid validation returns 201 Created. If the request payload is valid but the generated document fails PEPPOL validation, the API returns 422 Unprocessable Content and still includes the generated XML and validation errors.
Request Body (JSON)
The request payload is identical to the XRechnung endpoint.
For PEPPOL interoperability, buyer_reference or order_reference should be supplied, and payment.iban is recommended whenever the payment means is bank transfer. Use valid PEPPOL endpoint identifiers and schemes in seller.endpoint_id, seller.endpoint_scheme, buyer.endpoint_id, and buyer.endpoint_scheme. The API emits ISO alpha-2 country codes such as GB or DE in the XML.
Response Structure
| Field | Description |
|---|---|
| id | Generated local identifier for the response payload. |
| xml_base64 | Base64-encoded version of the generated PEPPOL UBL XML. |
| xml | Generated PEPPOL BIS Billing 3.0 XML as a plain string. |
| format | E-invoice format identifier. The public PEPPOL endpoint returns PEPPOL. |
| schema_version | Schema version echoed back from the request, defaulting to 1. |
| validation | Validation result object containing valid, errors, and warnings. |
| warnings | Top-level warnings array mirrored from the validation result for convenience. |
| filename | Suggested filename for the generated PEPPOL XML document. |
| code | Present only on validation failure. Currently returned as VALIDATION_FAILED. |
| message | Present only on validation failure and describes why the document received a 422 response. |
Example Response (201)
{
"id": "local-1710412800000",
"xml_base64": "PEludm9pY2UgLi4uPg==",
"xml": "<Invoice ...>",
"format": "PEPPOL",
"schema_version": "1",
"validation": {
"valid": true,
"errors": [],
"warnings": []
},
"warnings": [],
"filename": "invoice-GB-INV-2024-001-peppol.xml"
}Example Response (422)
{
"code": "VALIDATION_FAILED",
"message": "Generated document failed PEPPOL validation",
"id": "local-1710412800000",
"xml_base64": "PEludm9pY2UgLi4uPg==",
"xml": "<Invoice ...>",
"format": "PEPPOL",
"schema_version": "1",
"validation": {
"valid": false,
"errors": [
{
"rule": "PEPPOL-EN16931-R001",
"message": "Example PEPPOL validation rule failure returned for an invalid document."
}
],
"warnings": []
},
"warnings": [],
"filename": "invoice-GB-INV-2024-001-peppol.xml"
}/api/v1/invoices/zugferd
This endpoint generates a ZUGFeRD (Factur-X) hybrid PDF containing both a human-readable PDF and a machine-readable CII XML. It validates the generated CII XML and returns the validation result inline.
Successful generation with valid validation returns 201 Created. If the request payload is valid but the generated document fails validation, the API returns 422 Unprocessable Content and still includes the generated PDF, XML, and validation errors.
Request Body (JSON)
The request payload is identical to the XRechnung endpoint.
For common positive-payable invoices, include due_date. Otherwise validation can return BR-CO-25, which means either a payment due date or explicit payment terms must be present.
Response Structure
| Field | Description |
|---|---|
| Base64 encoded hybrid PDF/A-3 file. | |
| xml | The generated CII XML string. |
| validation | Validation results with EN 16931 / CII rule errors and warnings. |
| filename | Suggested filename for the generated hybrid PDF. |
Example Response (422)
{
"code": "VALIDATION_FAILED",
"message": "Generated document failed validation",
"pdf": "JVBERi0xLjQKJ...",
"xml": "<rsm:CrossIndustryInvoice ...>",
"validation": {
"valid": false,
"errors": [
{
"rule": "BR-CO-25",
"message": "[BR-CO-25]-In case the Amount due for payment (BT-115) is positive, either the Payment due date (BT-9) or the Payment terms (BT-20) shall be present."
}
],
"warnings": []
},
"filename": "invoice-INV-2024-001-zugferd.pdf"
}/api/v1/validate
This endpoint validates an existing XML document without generating a new invoice artifact. It is intended for integrators that already have XML output and only need a QuoteCash-hosted validation result.
The validation-only endpoint returns 200 OK whenever the XML was accepted for validation. Inspect validation.valid to determine whether the supplied document passed the selected validator.
Request Body (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
| format | string | Yes | One of xrechnung, peppol, or zugferd. Aliases factur-x, facturx, and cii are accepted for zugferd. |
| xml | string | Yes* | Raw XML string to validate. Provide either xml or xml_base64. |
| xml_base64 | string | Yes* | Base64-encoded XML. Use this when sending large XML bodies or binary-safe payloads. |
Supply either xml or xml_base64. For PEPPOL, the endpoint uses the configured PEPPOL validator URL when available. For ZUGFeRD, pass the embedded CII XML, not the PDF container.
Response Structure
| Field | Description |
|---|---|
| format | Normalized target validator format returned as XRECHNUNG, PEPPOL, or ZUGFERD. |
| received_as | Shows whether the endpoint validated xml or xml_base64 input. |
| valid | Convenience boolean mirrored from validation.valid. |
| validation | Validation result object containing valid, errors, and warnings. |
Example Request (cURL)
curl -X POST https://www.quotecash.io/api/v1/validate -H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" -d '{
"format": "peppol",
"xml": "<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">...</Invoice>"
}'Example Response (200)
{
"format": "PEPPOL",
"received_as": "xml",
"valid": false,
"validation": {
"valid": false,
"errors": [
{
"rule": "PEPPOL-EN16931-R001",
"message": "Example validation rule failure returned for an uploaded XML document."
}
],
"warnings": []
}
}/api/v1/cashflow/forecast
Use this endpoint to retrieve a business-scoped cashflow forecast with summary totals, period buckets, and optional invoice-level detail for open, partially paid, paid, or overdue invoices.
The public cashflow endpoint returns a business-scoped forecast for the API key owner. If you pass business_id, it must match the business attached to that key. The invoices array is only returned when include_invoices=true.
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| from | string | Yes | Start date in ISO format YYYY-MM-DD. |
| to | string | Yes | End date in ISO format YYYY-MM-DD. |
| groupBy | string | No | Aggregation window. Supported values: month or week. Defaults to month. |
| payment_state | string | No | Optional filter: open, partially_paid, paid, or overdue. |
| reminder_stage | string | No | Optional filter: first, second, final, manual, or none. |
| include_invoices | boolean | No | Set true to include paginated invoice rows in the response. |
| sort_by | string | No | Optional invoice sorting when include_invoices=true. Supported values: dueDate, open_amount, customer_name. |
| sort_direction | string | No | Optional invoice sort direction: asc or desc. |
| page | number | No | Page number for invoice pagination. Defaults to 1. |
| per_page | number | No | Items per page when include_invoices=true. Defaults to 25, max 100. |
| currency | string | No | Optional currency override. Defaults to the API key business currency. |
| business_id | string | No | Optional explicit business scope. Must match the business attached to the API key. |
Pass include_invoices=true when you want invoice rows back for drill-down UIs. Without it, the response contains only range, filters, summary, periods, and pagination.
Response Structure
| Field | Description |
|---|---|
| range | Normalized request window, aggregation mode, currency, and generatedAt timestamp. |
| filters | Echoes the active payment/reminder filters and invoice pagination settings. |
| summary | Top-level totals including openAmount, overdueAmount, paidAmountInRange, expectedIncomingInRange, and invoice counters. |
| periods | Aggregated weekly or monthly buckets with expectedIncoming, paidAmount, overdueAmount, openAmount, and invoiceCount. |
| invoices | Present only when include_invoices=true. Contains paginated invoice rows with paymentState, overdue status, and reminder metadata. |
| pagination | Pagination metadata for the invoices array, including page, perPage, totalItems, and totalPages. |
Example Request (cURL)
curl -X GET "https://www.quotecash.io/api/v1/cashflow/forecast?from=2026-05-01&to=2026-06-30&groupBy=month&payment_state=overdue&include_invoices=true&per_page=10" -H "x-api-key: YOUR_API_KEY"
Example Response (200)
{
"range": {
"from": "2026-05-01T00:00:00.000Z",
"to": "2026-06-30T23:59:59.999Z",
"groupBy": "month",
"currency": "EUR",
"generatedAt": "2026-05-17T08:30:00.000Z"
},
"filters": {
"paymentState": "overdue",
"reminderStage": null,
"includeInvoices": true,
"sortBy": "dueDate",
"sortDirection": "asc"
},
"summary": {
"openAmount": 800,
"overdueAmount": 800,
"partiallyPaidAmount": 200,
"paidAmountInRange": 200,
"expectedIncomingInRange": 800,
"invoiceCount": 1,
"openInvoiceCount": 1,
"overdueInvoiceCount": 1
},
"periods": [
{
"periodStart": "2026-05-01T00:00:00.000Z",
"periodEnd": "2026-05-31T23:59:59.999Z",
"label": "May 2026",
"expectedIncoming": 800,
"paidAmount": 200,
"overdueAmount": 800,
"openAmount": 800,
"invoiceCount": 1
}
],
"invoices": [
{
"id": "inv-1",
"invoiceNumber": "INV-001",
"customerName": "Alpha GmbH",
"date": "2026-05-01T00:00:00.000Z",
"dueDate": "2026-05-10T00:00:00.000Z",
"total": 1000,
"paidAmount": 200,
"openAmount": 800,
"currency": "EUR",
"status": "OVERDUE",
"paymentState": "overdue",
"isOverdue": true,
"reminder": {
"enabled": true,
"lastStage": "first",
"lastSentAt": "2026-05-11T00:00:00.000Z",
"nextStage": null,
"status": "sent",
"nextScheduledFor": null
}
}
],
"pagination": {
"page": 1,
"perPage": 10,
"totalItems": 1,
"totalPages": 1
}
}Integration Examples
Use these snippets as copy-paste starting points when wiring QuoteCash into your backend, scripts, or API tools.
Public API calls still respect plan-based monthly caps. When Stripe metered billing is enabled in the environment, successful API-key requests are also reported to the active Stripe subscription as usage records.
Node.js fetch example
const response = await fetch('https://www.quotecash.io/api/v1/invoices/xrechnung', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.QUOTECASH_API_KEY,
},
body: JSON.stringify({
schema_version: '1',
invoice_number: 'INV-2026-001',
issue_date: '2026-05-16',
due_date: '2026-05-30',
currency: 'EUR',
seller: {
name: 'Acme GmbH',
street: 'Seller Street 1',
city: 'Berlin',
postal_code: '10115',
country: 'DE',
vat_id: 'DE123456789',
email: 'billing@acme.test',
phone: '+49 30 123456'
},
buyer: {
name: 'Client GmbH',
street: 'Buyer Street 5',
city: 'Hamburg',
postal_code: '20095',
country: 'DE',
vat_id: 'DE987654321'
},
line_items: [
{
description: 'Consulting',
quantity: 8,
price: 125,
total: 1000,
unitCode: 'HUR',
vatRate: 19,
},
],
totals: {
net: 1000,
tax: 190,
gross: 1190,
},
payment: {
iban: 'DE12345678901234567890',
bic: 'ABCDEFGHXXX',
},
}),
});
const data = await response.json();
console.log(response.status, data.validation?.valid, data.filename);