eDelivery
eDelivery enables the online exchange of data and documents reliably and securely.
Sovos makes use of the the PEPPOL eDelivery network, acting as a PEPPOL-certified Service Provider (Access Point). This means that all involved parties need to be already registered in PEPPOL to be able to exchange documents.
It is one of Sovos' responsibilities (within our PEPPOL services) to assign a proper Participant ID and to register our PEPPOL receiving customers with their receiving capabilities in the Service Metadata Publisher (SMP) or Service Metadata Locator (SML), according to the market-specific PEPPOL Authorities, whenever applicable.
Although issuers and receivers can be directly connected to the network, they still need to use a Service Provider's Access Point to "reach" each-other.
To get started with Sovos' Sandbox (UAT) or Production environments, you must meet the following prerequisites:
Have a product registered with Sovos to use eDelivery in your company.
Have your company configured under the PEPPOL network.
Configuration is currently not possible via Indirect Tax API, so everything is handled by the Sovos Professional Services team during the implementation phase. This includes backend configuration, uploading the required certificate(s) for the customer, and establishing PEPPOL connection. For more information, contact the Professional Services team.
PEPPOL eDelivery inbound
The following diagram gives a detailed overview of the PEPPOL eDelivery inbound flow for e-invoice retrieval:
Step 1: Sovos Receives the Document
Sovos receives the document from the supplier's PEPPOL.
Step 2: Validation
Sovos performs the necessary semantic, syntactic, and legal validations.
Step 3: Send the Response
Sovos sends the status response to the supplier's PEPPOL.
Step 4: Mapping
Once the document passes Sovos' validations, Sovos maps the document from the PEPPOL format (Business Interoperability Specifications (BIS) 3 or PEPPOL International (PINT)) to the buyer's format.
Step 5: Sovos makes the document available
Sovos stores the retrieved documents and makes them available to buyers for retrieval.
Step 6: Buyer retrieves the available documents
To complete a transaction, the buyer must retrieve the application responses until the transaction has finished. If the buyer has subscribed to all notifications, the transaction can generate different application responses.
The country code used here is the country code from the buyer's company.
This endpoint allows setting the following query parameters:
Name | Type | Required | Default | Description |
---|---|---|---|---|
taxId | string | No | Include only notifications related to the specified taxId . | |
page | integer | No | 1 | The page to be returned, ranging from "1" to "10". |
perPage | integer | No | 10 | The number of results for the returned page, ranging from "1" to "100". Note: If the attachment file is configured to return the binary content instead of a link, use only values between "1" and "10". |
sourceSystemId | string | Yes | Include only notifications related to documents that originate from the given source system. | |
includeAcknowledged | boolean | No | false | "true" to include previously acknowledged notifications in the result. |
processType | string | No | "1" to only include notifications related to inbound documents. | |
orgId | string | No | Unique identifier for the organization. When provided, restricts the notifications listed to documents associated with this organization ID (only applicable for Worskspace tenants). | |
senderDocumentId | string | No | Unique identifier for the sender's document. When provided, restricts the notifications listed to this sender document ID (only applicable if the scope SenderDocumentId has been provided in the POST /v1/documents endpoint). |
Request sample:
curl --location 'https://api-test.sovos.com/v1/notifications/{countryCode}?processType=1&sourceSystemId=SystemERP&taxId=YOUR-TAXID&orgId=0000000-0000-0000-0000000000001&senderDocumentId=0000000AB' \
--header 'x-correlationId: SET-TO-UNIQUE-VALUE'
Response sample:
{
"status": 200,
"message": "Notifications Listed",
"success": true,
"timestamp": 1693343820329,
"data": {
"pageState": {
"page": 1,
"perPage": 10,
"totalEntries": 4,
"totalPages": 1
},
"notifications": [
{
"notificationId": "d1718adb-...-68e16d80ffb2",
"correlationId": "rrt-...-1335030-1",
"appPrefix": "DLT",
"metadata": {
"productId": "aa_eDelivery_1.0",
"transactionId": "6b8bc357-...-b2b7c6573ca1",
"documentId": "DOCUMENT-ID",
"erpDocumentId": "ERP-DOCUMENT-ID",
"erpSystemId": "SystemERP",
"processType": "1",
"taxId": "YOUR-TAXID",
"sciCloudStatusCode": "209",
"sciResponseCode": "AP",
"sciStatusAction": "NOA"
},
"content": "PD9...T4=",
"createdDate": 1693339001904
}
]
}
}
For a full example, download this application response sample document.
Step 7: Buyer acknowledges the Retrieved Documents
After retrieving the documents, the buyer must process them and mark them as read. This can be done by sending a PUT request to the /notifications/{countryCode} endpoint.
To make this request, set the following parameters:
Name | Type | Required | Parameter type | Default | Description |
---|---|---|---|---|---|
countryCode | string | Yes | Path | The two-digit country code specified by the ISO 3166-1 alpha-2 standard. | |
status | string | Yes | Request body | Enter "read". | |
notificationId | string | Yes | Request body | false | The ID of the notification that should be marked as acknowledged. |
notificationId
values can be acknowledged via one Indirect Tax API call by including them in a single request.Request sample:
curl --location --request PUT 'https://api-test.sovos.com/v1/notifications/{countryCode}' \
--header 'Content-Type: application/json' \
--header 'x-correlationId: SET-TO-UNIQUE-VALUE' \
--data '[
{
"status": "read",
"notificationId": "55f26671-...-d42925946ebf"
}
]'
Response sample:
{
"status": 200,
"message": "OK",
"success": true,
"timestamp": 1653424820578,
"data": {}
}
Error handling
When handling errors, the client application must follow the Indirect Tax API's error handling principles, as specified in the Error handling documentation.
In general, all error codes in the 400 range are client errors, which you need to analyze. After fixing the error, you can resend the request. Error codes 408 and 429 are exceptions: in these cases, you should wait at least 60 seconds before retrying. Error codes in the 500 range are server errors. In that case, resend the request according to the instructions given on the error handling documentation, which also includes a full list of error codes the Indirect Tax API can return.
PEPPOL eDelivery outbound
Document delivery is based on the eDelivery business process, which follows this order: Validation and Transmission.
The diagram below provides a detailed overview of the PEPPOL eDelivery outbound flow for e-invoice issuance:
Step 1: Create the Standard Business Document (SBD)
Every invoice sent to Sovos must be part of a Standard Business Document (SBD). This document includes a Standard Business Document Header (SBDH) and a Sovos Document node, which in turn includes a Sovos Canonical Invoice (SCI). To create the SBD, follow the detailed instructions in the SBDH, Sovos Document, and SCI pages. In addition, we'll now take a closer look at some key elements that should be included in the SBD:
Node | Required | Value |
---|---|---|
StandardBusinessDocumentHeader.Sender.Identifier.Authority | Yes | The relevant country code |
StandardBusinessDocumentHeader.Sender.Identifier | Yes | Supplier's TIN |
StandardBusinessDocumentHeader.Receiver.Identifier.Authority | Yes | The relevant country code |
StandardBusinessDocumentHeader.Receiver.Identifier | Yes | Buyer's TIN |
StandardBusinessDocumentHeader.DocumentIdentification.Standard | Yes | urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 |
StandardBusinessDocumentHeader.DocumentIdentification.TypeVersion | Yes | 2.1 |
StandardBusinessDocumentHeader.DocumentIdentification.Type | Yes | Invoice |
StandardBusinessDocumentHeader.BusinessScope.Scope (with child nodes) | Yes |
|
StandardBusinessDocumentHeader.BusinessScope.Scope (with child nodes) | Yes |
|
StandardBusinessDocumentHeader.BusinessScope.Scope (with child nodes) | Yes |
|
StandardBusinessDocumentHeader.BusinessScope.Scope (with child nodes) | Yes |
|
StandardBusinessDocumentHeader.BusinessScope.Scope (with child nodes) | Yes |
|
StandardBusinessDocumentHeader.BusinessScope.Scope (with child nodes) | Yes |
|
StandardBusinessDocumentHeader.BusinessScope.Scope (with child nodes) | Yes |
|
StandardBusinessDocumentHeader.BusinessScope.Scope (with child nodes) | Yes |
|
SovosDocument.SovosCanonicalInvoice.Invoice | Yes | SCI |
Here is an SBD sample:
<sbd:StandardBusinessDocument xmlns="http://uri.etsi.org/01903/v1.4.1#" xmlns:sbd="http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader" xmlns:ad="http://www.sovos.com/namespaces/additionalData" xmlns:sci="http://www.sovos.com/namespaces/sovosCanonicalInvoice" xmlns:svs="http://www.sovos.com/namespaces/sovosDocument" xmlns:sov="http://www.sovos.com/namespaces/sovosExtensions" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:leg="http://www.sovos.com/namespaces/sovosExtensions/LegalExtension" xmlns:inv="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader file:///C:\Users\helder.barbosa\OneDrive - Sovos Compliance\Sovos\Sovos XSDs\Sovos Document/StandardBusinessDocumentHeader.xsd">
<sbd:StandardBusinessDocumentHeader>
<sbd:HeaderVersion>1.0</sbd:HeaderVersion>
<sbd:Sender>
<sbd:Identifier Authority="{countryCode}">SENDER-TAXID</sbd:Identifier>
</sbd:Sender>
<sbd:Receiver>
<sbd:Identifier Authority="{countryCode}">RECEIVER-TAXID</sbd:Identifier>
<sbd:ContactInformation>
<sbd:Contact/>
<sbd:EmailAddress/>
<sbd:FaxNumber/>
<sbd:TelephoneNumber/>
<sbd:ContactTypeIdentifier/>
</sbd:ContactInformation>
</sbd:Receiver>
<sbd:DocumentIdentification>
<sbd:Standard>urn:oasis:names:specification:ubl:schema:xsd:Invoice-2</sbd:Standard>
<sbd:TypeVersion>2.1</sbd:TypeVersion>
<sbd:InstanceIdentifier>100002</sbd:InstanceIdentifier>
<sbd:Type>Invoice</sbd:Type>
<sbd:MultipleType>false</sbd:MultipleType>
<sbd:CreationDateAndTime>2023-10-31T00:00:00Z</sbd:CreationDateAndTime>
</sbd:DocumentIdentification>
<sbd:BusinessScope>
<sbd:Scope>
<sbd:Type>Country</sbd:Type>
<sbd:InstanceIdentifier/>
<sbd:Identifier>{countryCode}</sbd:Identifier>
</sbd:Scope>
<sbd:Scope>
<sbd:Type>CompanyCode</sbd:Type>
<sbd:InstanceIdentifier/>
<sbd:Identifier>SENDER-TAXID</sbd:Identifier>
</sbd:Scope>
<sbd:Scope>
<sbd:Type>SenderDocumentId</sbd:Type>
<sbd:InstanceIdentifier/>
<sbd:Identifier>SENDER-DOCUMENT-ID</sbd:Identifier>
</sbd:Scope>
<sbd:Scope>
<sbd:Type>SenderSystemId</sbd:Type>
<sbd:InstanceIdentifier/>
<sbd:Identifier>SystemERP</sbd:Identifier>
</sbd:Scope>
<sbd:Scope>
<sbd:Type>ProcessType</sbd:Type>
<sbd:InstanceIdentifier/>
<sbd:Identifier>Outbound</sbd:Identifier>
</sbd:Scope>
<sbd:Scope>
<sbd:Type>BusinessProcess</sbd:Type>
<sbd:InstanceIdentifier/>
<sbd:BusinessService>
<sbd:BusinessServiceName>eDelivery</sbd:BusinessServiceName>
</sbd:BusinessService>
</sbd:Scope>
<sbd:Scope>
<sbd:Type>BusinessCategory</sbd:Type>
<sbd:InstanceIdentifier/>
<sbd:Identifier>B2B</sbd:Identifier>
</sbd:Scope>
<sbd:Scope>
<sbd:Type>Version</sbd:Type>
<sbd:InstanceIdentifier/>
<sbd:Identifier>3.0</sbd:Identifier>
</sbd:Scope>
</sbd:BusinessScope>
</sbd:StandardBusinessDocumentHeader>
Step 2: Supplier sends the SBD to Sovos
The supplier sends a POST request to the /documents endpoint to send the SBD to Sovos.
To make this request, set the following request body parameters:
Name | Type | Required | Description |
---|---|---|---|
data | string | Yes | The Base64-encoded SBD created in step 1. |
dataEncoding | string | Yes | Enter "base64". |
Request sample:
curl --location --request POST 'https://api-test.sovos.com/v1/documents' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer TOKEN' \
--header 'x-correlationId: SET-TO-UNIQUE-VALUE' \
--data-raw '{
"data": "PD9...de4=",
"dataEncoding" : "base64"
}'
Response sample:
{
"timestamp": 1605282724079,
"status": 202,
"success": true,
"message": "Document Received",
"data": {
"documentId": "3add2b7104dc0049ff0bf410f57e0a19afaf"
}
}
Step 3: Validation
Sovos performs the necessary semantic, syntactic, and legal validations. In addition, Sovos performs a schema validation to ensure the XML file conforms to the expected nd legal validations. Additionally, Sovos performs a schema validation to ensure the XML file conforms to the expected structure by comparing it with the official schema.
If the validation fails, you'll see an error when you retrieve application responses.
Step 4: Mapping
Once the XML passes Sovos' validations, Sovos maps the document to the appropriate PEPPOL format (Business Interoperability Specifications (BIS) 3 or PEPPOL International (PINT)). If the mapping fails, you'll see an error when you retrieve application responses.
Step 5: Generate and transmit the document
Sovos generates the document and sends it to the buyer's PEPPOL. If the buyer doesn't have a registered PEPPOL, you'll see an error when retrieving application responses.
Step 6: PEPPOL processes the document
After receiving the document, the buyer's PEPPOL will process (validate) it and make it available for the buyer to retrieve. It will also send a response back to Sovos.
Step 7: PEPPOL sends the response
Sovos receives the response from the buyer's PEPPOL and then generates notifications for the supplier to retrieve, so they can understand the flow's state.
Step 8: Supplier retrieves the application responses
As a response to the initial sending of the document, the client will receive a JSON response message with an HTTP status code of 202 (asynchronous transaction). This means that the supplier must retrieve the application responses that become available during the transaction. These responses provide status information and also include a URL to access the documents once these have become available during the process.
To complete a transaction, the supplier must retrieve application responses until the SCIResponseCode
in the response has the value of either "AP", "CA", "PD", or "RE", which indicates that the transaction has finished.
Possible application responses:
# | SCICloudStatusCode | SCIResponseCode | Sample |
---|---|---|---|
1 | 102 | AP | Document validated successfully
|
2 | 108 | UQ | Document being processed by the recipient
|
3 | 108 | IP | Document being processed by the recipient
|
Document being processed by the recipient
| |||
4 | 203 | AP | Document accepted/acknowledged by the counterparty
|
5 | 210 | CA | Document conditionally accepted by the recipient
|
6 | 211 | PD | Document payment sent by the recipient
|
7 | 401 | RE | Error processing document
|
8 | 405 | RE | Document rejected by the counterparty
|
The supplier can use the following Indirect Tax API endpoints to retrieve application responses:
-
GET /notifications/{countryCode}
-
GET /documents/{countryCode}/{documentId}/notifications
You need to use the country code from the supplier's company.
GET /notifications/{countryCode}
The supplier can use this endpoint to retrieve application responses that match the set search criteria. This endpoint allows setting the following query parameters:
Name | Type | Required | Default | Description |
---|---|---|---|---|
taxId | string | No | Include only notifications related to the specified taxId . This value relates to the CompanyCode from the SBDH. | |
page | integer | No | 1 | Enter the page to be returned, ranging from "1" to "10". |
perPage | integer | No | 10 |
|
sourceSystemId | string | Yes | Include only notifications related to documents that originate from the given source system. This value is related to the SenderSystemId in the SBDH. | |
includeAcknowledged | boolean | No | false | "true" to include previously acknowledged notifications in the result. |
orgId | string | No | Unique identifier for the organization. When provided, restricts the notifications listed to documents associated with this organization ID (only applicable for Worskspace tenants). | |
senderDocumentId | string | No | Unique identifier for the sender's document. When provided, restricts the notifications listed to this sender document ID (only applicable if the scope SenderDocumentId has been provided in the POST /v1/documents endpoint). |
Request sample:
curl --location --request GET 'https://api-test.sovos.com/v1/notifications/{countryCode}?page=1&perPage=2&includeAcknowledged=true&taxId={taxId}&sourceSystemId={sourceSystemId}&includeBinaryData=true&processType=0&orgId=0000000-0000-0000-0000000000001&senderDocumentId=0000000A' \
--header 'Content-Type: application/json' \
--header 'x-correlationId: SET-TO-UNIQUE-VALUE' \
--header 'Authorization: Bearer TOKEN'
Response sample:
{
"status": 200,
"message": "Notifications Listed",
"success": true,
"timestamp": 1708537586642,
"data": {
"pageState": {
"page": 1,
"perPage": 2,
"totalEntries": 1,
"totalPages": 1
},
{
"notificationId": "b0a9c81a-...9b29-e7a693da0ecd",
"correlationId": "rrt-...-21916838-1",
"appPrefix": "sph",
"metadata": {
"productId": "aa_edelivery__1.0",
"documentId": "DOCUMENT-ID",
"erpDocumentId": "ERP-DOCUMENT-ID",
"erpSystemId": "SystemERP",
"processType": "0",
"taxId": "999999999",
"sciCloudStatusCode": "209",
"sciResponseCode": "AP",
"sciStatusAction": "NOA"
},
"content": "PD..g==",
"createdDate": 1708008887925
}
]
}
}
GET /documents/{countryCode}/{documentId}/notifications
The supplier can send a request using this endpoint to retrieve application responses related to a single document.
To make this request, set the following parameters:
Name | Type | Required | Parameter type | Default | Description |
---|---|---|---|---|---|
documentId | string | Yes | Path | The ID of the document returned in step 2 | |
includeAcknowledged | boolean | No | Query | false | "true" to include previously acknowledged notifications in the result. |
Request sample:
curl --location --request GET 'https://api-test.sovos.com/v1/documents/{countryCode}/{documentId}/notifications?includeAcknowledged=true&includeBinaryData=true' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer TOKEN' \
--header 'x-correlationId: SET-TO-UNIQUE-VALUE'
Response sample:
{
"timestamp": 1633687728708,
"status": 200,
"success": true,
"message": "Notifications Listed",
"data": {
"pageState": {
"page": 1,
"perPage": 2,
"totalPages": 1,
"totalEntries": 1
},
"notifications": [
{
"createdDate": 1629824492,
"metadata": {
"productId": "aa_edelivery__1.0",
"documentId": "3add2b7104dc0049ff0bf410f57e0a19afaf",
"erpDocumentId": "80257087",
"erpSystemId": "SystemERP",
"processType": "0",
"taxId": "999999999",
"sciCloudStatusCode": "200",
"sciResponseCode": "AP",
"sciStatusAction": "NOA"
},
"appPrefix": "SPH",
"notificationId": "da3095da-f974-420c-bce2-e33682692276",
"content": "PEF...c2U+"
}
]
}
}
Step 9: Supplier marks the application responses as acknowledged
After retrieving application responses, the supplier must process them and mark them as read. This can be done by sending a PUT request to the /notifications/{countryCode} endpoint.
To make this request, set the following request body parameters:
Name | Type | Required | Description |
---|---|---|---|
status | string | Yes | Enter "read". |
notificationId | string | Yes | The ID of the notification that must be marked as acknowledged. |
Multiple notificationId
values can be acknowledged via one Indirect Tax API call by including them in a single request.
Request sample:
curl --location --request PUT 'https://api-test.sovos.com/v1/notifications/{countryCode}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer TOKEN' \
--header 'x-correlationId: SET-TO-UNIQUE-VALUE' \
--data-raw '[
{
"status": "read",
"notificationId": "51341d39-fd3e-4dcf-aea3-a73d73e0de76"
}
]'
Response sample:
{
"timestamp": 1601673284,
"status": 200,
"success": true,
"message": "Notifications acknowledged successfully."
}
Error handling
When handling errors, the client application must follow the Indirect Tax API's error handling principles, as specified in the Error handling documentation.
In general, all error codes in the 400 range are client errors, which you need to analyze. After fixing the error, you can resend the request. Error codes 408 and 429 are exceptions: in these cases, you should wait at least 60 seconds before retrying. Error codes in the 500 range are server errors. In that case, resend the request according to the instructions given on the error handling documentation, which also includes a full list of error codes the Indirect Tax API can return.