Process sales invoices
In Banqup, any uploaded file undergoes a process where invoice data is extracted and checked for sanity and accuracy. After a successful validation process, the document will be sent automatically to the customer. After that, you can view details about the document and update the payment status.
Prerequisites
- The invoice is a valid UBL, XML or PDF.
- You have Banqup permissions.
- The resource IDs necessary to perform the API calls are:
Banqup uses a combination of the filename and request metadata to help identify duplicate uploads. To safely handle network timeouts or retries without issuing duplicate invoices, your integration should always log and map your internal system's invoice tracking IDs to Banqup's returned file id (from Step 1) before executing automated retries.
Step 1: Create file
Endpoint: /documents/core/transaction/v1/spaces/{spaceId}/files
Path parameter: spaceId
Requires a JSON request body (see
curlexample below).
curl -L 'https://{{serverURL}}/documents/core/transaction/v1/spaces/{spaceId}/files' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN' \
-d '{
"filename": "S_BE0479909676_999",
"description": "xml upload for document ABC2025-10-29",
"creatorSubject": "00000001-0001-0001-0001-000000000000",
"creatorType": "user",
"retentionTime": "2029-09-30T08:30:08.424Z",
"fileSize": 57308,
"fileType": "xml",
"contentType": "application/xml",
"source": "com.unifiedpost.btx.connectors:peppol",
"tags": [
"tag1",
"tag2"
],
"metadata": {
"folder": "SALES",
"documentCategory": "INVOICE"
}
}'
Successful response: Save the fileId returned in the response for further use.
{
"id": "a751dea0-cb12-4cde-8734-c6d839c863c3",
"filename": "S_BE0479909676_999",
"description": "xml upload for document ABC2025-10-29",
"creatorSubject": "f3c0e3c1-a0c8-4fd4-b53a-12dbd6c28d31",
"creatorType": "application",
"retentionTime": "2029-09-30T08:30:08.424Z",
"status": "AWAITING_UPLOAD",
"fileSize": 57308,
"fileType": "application/xml",
"contentType": "application/xml",
"uploadUrl": "https://storage.googleapis.com/gcs-rxjekoxh-eu-datastore-uat/pending/file/da3484f2-cd58-4039-85b1-f833d0c841da/a751dea0-cb12-4cde-8734-c6d839c863c3?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=sw-btxdata-3fac8c-uat-eu%40pj-bu-btxdata-uat-eu.iam.gserviceaccount.com%2F20251029%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20251029T080944Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=content-type%3Bhost&X-Goog-Signature=12564597c779d3b1a32ce1e2f6f7c322f86aafb94383fa80d65ac39b6e6b6181c14825c5bf726a17ad32f1ddb4aee65adfe149f11d620de5a4f8cedb81dbbb3a0d322aa250e926aaa0629cd5548313f08a6db5973b1b83c855c22e08641bc5b43f4ec9b5581d09be8091724f2c60eeaa6208570ecb8163c2a5cf74ccaab9f05576407bfb8689f833e0a4efa9ecf2880ff60c2bf81c7fddbffe777fd79ba47e98c506c5fc4444eab51f22142c8f468c8b5fa72c8f4bb2de384f4efb9c19bf369d3f38948555e1951c12518bac818fbd005150d711b0f42ef678ab7209575f133e4570a94782afe682967749d033a3d0dd7972f9f3ffd35b2b8b74b69e8de15be3",
"tags": [],
"metadata": {
"folder": "SALES",
"documentCategory": "INVOICE"
},
"createdAt": "2025-10-29T08:09:44.020545597Z",
"updatedAt": "2025-10-29T08:09:44.020545597Z"
}
Step 2: Upload file
Endpoint: /uploadUrl (returned in the previous response).
The uploadUrl is a presigned URL in GCP which allows users to temporarily and securely access bucket resources for upload.
Request body: Attach the file in PDF, UBL or XML format. Content type: binary.
To prevent 403 Forbidden or 400 Bad Request errors from the uploadUrl, the Content-Type in the header must exactly match the contentType value specified in the Step 1 POST request body (e.g., application/xml).
Successful response: The file has been accepted for processing. To check the file status, see step 3.1.

Document processing and delivery
If the document is processed successfully by the system, the invoice will be sent automatically to the customer.
Step 3: View results
- Document
- Document events
- Customer
Step 3.1: Check file status (optional)
Every newly created file undergoes a process of validation by Banqup, which is reflected in different file statuses.
Use this endpoint to check the file status.
Endpoint: /documents/core/transaction/v1/spaces/{spaceId}/files/{fileId}
Path parameters:
spaceIdfileId
curl -L 'https://{{serverURL}}/documents/core/transaction/v1/spaces/{spaceId}/files/{fileId}' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN'
Successful response:
{
"id": "a751dea0-cb12-4cde-8734-c6d839c863c3",
"filename": "S_BE0479909676_999",
"description": "xml upload for document ABC2025-10-29",
"creatorSubject": "f3c0e3c1-a0c8-4fd4-b53a-12dbd6c28d31",
"creatorType": "application",
"retentionTime": "2029-09-30T08:30:08.424Z",
"status": "PROCESSED",
"fileSize": 7326,
"fileType": "application/xml",
"contentType": "application/xml",
"uploadUrl": "https://storage.googleapis.com/gcs-rxjekoxh-eu-datastore-uat/transaction/file/da3484f2-cd58-4039-85b1-f833d0c841da/a751dea0-cb12-4cde-8734-c6d839c863c3?GoogleAccessId=sw-btxdata-3fac8c-uat-eu@pj-bu-btxdata-uat-eu.iam.gserviceaccount.com&Expires=1761729179&Signature=WwG1ZnR1sVhbbwnQClNs3KZA4EWSZ2vJE83XIq9t1aQHvYeLZbXh2lOPM%2Bii2xSoPSqehq2XQDYyRQqsoW6CAyQELp8ZVz%2FreOl3dl7kp857F30OA%2Fl%2FO0y3j%2FrKAXnVIasE%2FfaDna9QyXOfoyxY%2B6lHep5hWWeVvMahMbstyUP4S4tSjjRV1ll%2F9DYxxXbj1II7uwPLhPfBnQnrypdxfHGQrPJtzKGOwKcky3S1pSGZ47DHSzmW6ctBuAWryWTdoqaDjEugnODAZlxCgc9PMrNhGPyVeo0%2BUD2hJfVaiyG41vnPNmWPOlEX6oar3NmhdJsQNiPaqWaAxnFrw7zHpQ%3D%3D",
"tags": [],
"metadata": {
"folder": "SALES",
"documentCategory": "INVOICE"
},
"createdAt": "2025-10-29T08:09:44.020546Z",
"updatedAt": "2025-10-29T08:12:50.610060Z"
}
Step 3.2: Retrieve the document Id
Endpoint: /documents/core/transaction/v1/spaces/{spaceId}/files/{fileId}/documents
Path parameters:
spaceIdfileId
curl -L 'https://{{serverURL}}/documents/core/transaction/v1/spaces/{spaceId}/files/{fileId}/documents' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN'
Successful response: Save the documentId returned in the response for further use.
{
"documents": [
{
"id": "53705523-fd58-4510-86f8-b7619a75a4b9"
}
]
}
Step 3.3: Retrieve document results
Endpoint: documents/core/transaction/v2/spaces/{spaceId}/documents/{documentId}
Path parameters:
spaceIddocumentId
Query parameters: optional.
include: processingData,validationData,connections,lines
curl -L 'https://{{serverURL}}/documents/core/transaction/v2/spaces/{spaceId}/documents/{documentId}' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR_TOKEn'
Successful response:
Validation failures
If "validated": false is returned in the response payload, look closely at the spaceExtensions object under validationData.
Common rejection reasons include:
peppolvalidation failure: e.g. the UBL/XML structurally violates Peppol standard specifications (e.g., missing mandatory tax schemas).dataExtractionmismatch: e.g. the computed line item totals do not match thegrossAmountorpayableAmountstated in the document totals.
How to handle: If an automatically processed invoice fails validation, it will not be delivered to the customer. You will need to upload a valid document.
{
"lines": [
{
"id": "9e4ad3b9-a410-4a83-a531-fd4528ae0837",
"sequence": 1,
"data": {
"productIdentifiers": {
"itemDescription": "test"
},
"unit": "H87",
"quantity": "1",
"netAmount": "20",
"currency": "EUR",
"id": "83l02e5b-bae7-4eef-91ec-1c7bf536f454",
"vatDetails": {
"vatCategory": "S",
"vatPercentage": "12"
},
"pricing": {
"itemNetPrice": "20",
"itemPriceQuantity": "1"
}
}
}
],
"connections": [
{
"displayName": " Belgium Test Company",
"relationType": "CUSTOMER",
"id": "11166d33-dc4a-4af2-9588-575a26558c4f"
}
],
"id": "ff9d8da5-ae70-4ee1-a6e9-4b5085678051",
"spaceId": "da3284f2-cd58-4039-85b1-f833d0c841da",
"source": "documentcreator",
"folder": "SALES",
"status": {
"pay": "UNPAID",
"delivery": "RECEIVED",
"document": "VALIDATED",
"processing": "GENERATED_DOCUMENT_NUMBER",
"spaceExtensions": {
"com.unifiedpost.btx.connectors": {
"email": {
"status": "DELIVERED"
},
"document-processor": {
"processing": "FINALIZED_DOCUMENT"
}
}
}
},
"category": "INVOICE",
"metadata": {
"$schema": "https://btx.unifiedpost.com/btx/datastore/document/document_metadata/v1/document-metadata-schema.json",
"dueDate": "2025-10-23",
"customer": {
"address": {
"country": "BE",
"postCode": " 92812",
"townName": "ANTWERPEN",
"streetName": "StreetName 34"
},
"legalName": " Belgium Test Company",
"tradeName": " Belgium Test Company",
"globalIdentifiers": {
"eu:reid": "PKE_CUST-003",
"global:email": [
"pjohn.smith@example.com"
],
"global:participantId": "9913:PKE_CUST-003"
}
},
"supplier": {
"address": {
"country": "BE",
"postCode": "3110",
"townName": "Fernandahaven",
"streetName": "Nitzsche Lodge",
"buildingNumber": "80728"
},
"legalName": "LuiTest1",
"globalIdentifiers": {
"flwb": "BE0417497106",
"flwp": "PRC-d62ff2cd-7ca1-11hf-9466-8eb5ddeed38a",
"be:en": "0417497106",
"be:vat": "BE0417497106",
"companyType": "BE006",
"companyIdentifier": "BE0417497106",
"dateOfIncorporation": "1900-01-01",
"countryOfIncorporation": "BE",
"primaryBusinessActivity": "474",
"onboardingProcessInstanceId": "PRC-d69ff2cd-7ca1-11ef-9466-8eb5ddeed38a",
"provisioningProcessInstanceId": "PRC-ekf6c3e6-7ca1-11ef-9466-8eb5ddeed38a"
}
},
"issueDate": "2025-09-23",
"vatDetails": [
{
"netAmount": "20",
"vatAmount": "2.4",
"vatCategory": "S",
"vatPercentage": "12"
}
],
"invoiceType": "380",
"currencyCode": "EUR",
"documentNumber": "ABC000007",
"documentTotals": {
"netAmount": "20",
"vatAmount": "2.4",
"grossAmount": "22.4",
"payableAmount": "22.4"
}
},
"tags": [
"SEEN"
],
"retentionTime": "2036-09-23T00:00:00Z",
"processingData": {
"spaceExtensions": {
"com.unifiedpost.btx.payments": {
"aggregation": {
"lock": "60830b7a-cd2e-41c9-9e93-22d5eefacda1",
"openBalance": "22.4",
"projectedBalance": "22.4"
}
},
"com.unifiedpost.btx.connectors": {
"email": {
"reference": "da3484h2-cd58-4039-85b1-f833d0c841da/aa955a8a-d089-4096-aad4-cd4325f23819",
"notificationId": "8l7f946c-0774-4832-be55-3517b28de163"
}
}
}
},
"validationData": {
"validated": true,
"spaceExtensions": {
"com.unifiedpost.btx.documents.validators": {
"general": {
"status": "COMPLETED",
"validationId": "9c742f4a-dc34-4885-bc95-298c1616629a"
}
},
"com.unifiedpost.btx.connectors.validators": {
"peppol": {
"status": "COMPLETED",
"validationId": "9c741f4a-dc34-4885-bc95-298c1616629a"
},
"dataExtraction": {
"status": "COMPLETED",
"validationId": "9c741f4a-dc34-4885-bc95-298c1616629a"
}
}
}
},
"balanceOffsets": []
}
All relevant actions performed on a document are recorded in an events log in Banqup.
Endpoint: /platform/event/v1/spaces/{spaceId}/events
Path parameter: spaceId
curl -L 'https://{{serverURL}}/platform/event/v1/spaces/{spaceId}/events' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN'
Successful response
{
"events": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"level": "INFO",
"subjectId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"subjectType": "user",
"ownerId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"ownerType": "SPACE",
"body": "The invoices has been sent",
"category": "document",
"subcategory": "document_sent",
"metadata": {
"some": "value"
},
"properties": {
"connector": "chorus_pro"
},
"createdAt": "2024-05-31T11:58:22.189Z"
}
],
"totalElements": 0,
"currentPage": 0,
"pageSize": 0
}
If the customer doesn't exist in the system when the invoice is sent, it will be created based on the information in the invoice as a new connection.
Customers, suppliers and other business partners are collectively called connections in Banqup.
Endpoint: /network/core/transaction/v1/spaces/{spaceId}/connections/{connectionId}
Path parameters:
spaceIdconnectionId
curl -L 'https://{{serverURL}}/network/core/transaction/v1/spaces/{spaceId}/connections/{connectionId}' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer YOUR_TOKEN'
A successful response returns the connection details. There are two types of responses, depending on the customer type (business or person):
- Business connection
- Person connection
{
"type": "business",
"id": "aaba0614-b8b6-45d6-94b7-957cde946300",
"spaceUrl": "https://entity.store/entitystore/v1/directory/entities/entity_1/spaces/space_1",
"globalIdentifiers": {
"be:vat": "123456789",
"global:email": [
"john.smith@novafish.com"
],
"global:phoneNumber": [
"0032563259874"
]
},
"localIdentifier": "001",
"alias": "UP",
"connectionStatus": "CONNECTED",
"relationType": "CUSTOMER",
"addresses": {
"main": {
"streetName": "Nitzsche Lodge",
"house": "80728",
"postalCode": "3110",
"city": "Fernandahaven",
"country": "Belgium",
"countryCode": "BE"
}
},
"tags": [
"validate",
],
"active": true,
"metadata": {
"channels": {
"main": "delivery_on_platform",
"secondary": "email"
},
"department": "Accounting",
"logo": "https://address.com/logo.jpg",
"website": "https://mycompanywebsite.com",
"notes": "Professional and amateur fishing gear",
"industry": "Agriculture, Forestry And Fishing"
},
"legalName": "Nova Fish",
"tradeName": "Fishing Gear",
"businessType": "ENTERPRISE"
}
{
"type": "person",
"id": "44285181-3714-40c0-acd2-22dd5596269e",
"spaceUrl": "https://entity.store/entitystore/v1/directory/entities/entity_1/spaces/space_1",
"globalIdentifiers": {
"global:email": [
"susan.anderson@xyz.com"
],
"global:phoneNumber": [
"00301234567"
]
},
"alias": "UP",
"connectionStatus": "CONNECTED",
"relationType": "CUSTOMER",
"addresses": {
"main": {
"street": "Milo Crossroad",
"house": "7850",
"postalCode": "3100",
"city": "Kubhaven",
"country": "Belgium",
"countryCode": "BE"
}
},
"tags": [
"validate"
],
"active": true,
"metadata": {
"channels": {
"main": "delivery_on_platform",
"secondary": "email"
},
"department": "Accounting",
"logo": "https://address.com/logo.jpg",
"website": "https://mycompanywebsite.com",
"notes": "My notes",
"industry": "Construction"
},
"firstName": "Susan",
"lastName": "Anderson"
}
Step 4: Update payment status
- Refer to this guide for a list of available payment statuses.
- See this glossary for an explanation of possible document actions.
In this example, the document will be marked as paid.
Endpoint: payments/reconciliation/documents/v1/spaces/{spaceId}/documents/{documentId}:markAsPaid
Path parameters:
spaceIddocumentId
Requires a JSON request body (see
curlexample below).
curl -L 'https://{{serverURL}}/payments/reconciliation/documents/v1/spaces/{spaceId}/documents/{documentId}:markAsPaid' \
-H 'Content-Type: application/json' \
-d '{
"comment": "Payment received for Invoice ABC2025-10-29",
"paymentAmount": "20",
"paymentDate": "2026-01-15",
"paymentReferenceNumber": "GHT1234",
"paymentMethod": "BANK_TRANSFER",
"sharePaymentStatus": true
}'
Successful response: 200 response.
The :markAsPaid endpoint returns an HTTP 200 OK status even if the documents failed to update. Your integration must inspect the response body to ensure your document IDs are not listed in the failure array.
Common reasons for failure:
- The
documentIddoes not exist or has been deleted. - The document is in an invalid state (e.g., still
PROCESSING).