France E-Invoice & E-Reporting Factur-X
How to get “API Key” from Portal ?
To obtain the API key to be used in the request body of the login endpoint, navigate to Settings > ERP Management > API Management in the Portal and use the "Generate" button.
Login and Authorization Configuration
Technical Details
| Property | Value |
|---|---|
| Endpoint | /auth/login |
| Method | POST |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | None (Initial access) |
Request Body (JSON)
The following fields are used to define login criteria:
| Field | Type | Description |
|---|---|---|
| apiKey | String | A unique key assigned specifically to the user for portal access, verifying the system identity. (it is explained in previous section “How to get API Key from portal”) |
| String | The registered email address in the system belonging to the authorized user performing the operation. |
Response Details
Upon a successful request, a 200 OK code is returned with the following details:
| Field | Type | Description |
|---|---|---|
| jwt | — | The secure session token that must be used as a 'R-Auth' API Key in all subsequent API calls. |
| expirationDate | DateTime | Indicates the exact time the session key will expire; the ERP system can use this data to manage automatic re-login processes. |
The JWT token successfully obtained during the authentication step (auth/login) acts as a key to access the secure endpoints of the APIs. After the first successful login, the JWT token obtained from the response of a successful login is used as the R-Auth value in the authorization section of other queries. This configuration ensures that every data exchange between the ERP and the portal occurs over an authenticated and secure channel.
Technical Details
| Property | Value |
|---|---|
| Key | Enter R-Auth in the Key field. |
| Value | {{apiKey}} or {{jwt}} (Copy the jwt string returned from the login endpoint.) |
| Header Setting | Navigate to the "Headers" tab of the request to be sent. |
Chorus Pro Test SIREN Guide
This guide explains how to create test SIREN numbers for the Docnova stage environment.
To view the PDF version of the guide, click the button below.
Open PDF Guide
EDI / iDoc - FR Invoices Standard Mappings
1. Introduction
This guide is structured to allow development teams to incorporate portal features into their business workflows with minimum effort and maximum compliance.
2. Authentication POST
Purpose of Use: This endpoint is utilized by ERP systems to obtain the session key (JWT Token) required to establish a secure connection and initiate data exchange with the docnova portal.
An enterprise ERP system must trigger this endpoint to receive a valid authentication token before performing actions such as transmitting invoices or querying compliance reports via the portal. The acquired token is then provided in the "Authorization" header for all subsequent API requests. This mechanism ensures that data traffic between the ERP and the portal is conducted via a secure, time-bound key rather than transmitting sensitive user credentials for every transaction.
Endpoint Information
| Property | Value |
|---|---|
| URL | /auth/login |
| Method | POST |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | Not required (public endpoint) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/auth/login' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--data-raw '{
"apiKey": "{{your_api_key}}",
"email": "user@example.com"
}'
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| String | Optional | User's registered email address | |
| apiKey | String | Yes | Obtained from the portal, via the settings > ERP Management > API Management menu. |
Responses
200 - Login Successful
Full Response (AccountInfo)
{
"id": "a1b2c3d4-e5f6-7890-abcd-...",
"superAdmin": false,
"companies": [
{
"id": "60ccd1a7-5348-47b2-9ef6-...",
"name": "Example Company Ltd.",
"taxNumber": "1234567890",
"vatNumber": "DE123456789",
"email": "info@examplecompany.com",
"website": "https://www.examplecompany.com",
"address": "Example Street No: 1",
"city": "Berlin",
"state": "Berlin",
"country": "DE",
"postalCode": "10115",
"phoneNumber": "+49 30 1234567",
"credit": 1000,
"userCount": 5,
"portalType": "RECHNUNG",
"mailLanguage": "DE",
"currencyCode": "EUR",
"sftp": false,
"isSubCompany": false,
"featureAllowed": true,
"participants": [
{
"id": "participant-uuid",
"peppolId": "0088:1234567890"
}
]
}
],
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expirationDate": "2026-01-30T10:30:00.000Z",
"refreshToken": "refresh-token-string",
"refreshTokenExpiration": "2026-02-28T10:30:00.000Z",
"user": {
"id": "user-uuid",
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"phoneNumber": "+49 170 1234567",
"photoUrl": "https://example.com/photo.jpg",
"mailLang": "EN",
"isSuperAdmin": false,
"lastLoginTime": "2026-01-29T10:30:00",
"featureAllowed": true
},
"mfaEnabled": false,
"mfaType": null,
"secretImageUri": null,
"lastCompanyId": "60ccd1a7-5348-47b2-9ef6-...",
"requiresRecaptchaV2": false,
"message": null,
"active": true,
"isAppLogin": false
}
Basic Response (JwtBasicResponse)
{
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expirationDate": "2026-01-30T10:30:00.000Z"
}
Response Fields
Account Information Fields
| Field | Type | Description |
|---|---|---|
| id | String | User unique identifier |
| superAdmin | Boolean | Whether user has super admin privileges |
| companies | Array<AuthorizedCompany> | List of companies user is authorized to access |
| jwt | String | JWT access token. Used in R-Auth header for API requests |
| expirationDate | DateTime | JWT token expiration date |
| refreshToken | String | Refresh token for obtaining new access tokens |
| refreshTokenExpiration | DateTime | Refresh token expiration date |
| user | Object | User detail information |
| mfaEnabled | Boolean | Whether multi factor authentication is enabled |
| mfaType | Enum | MFA type (GOOGLE, WHATSAPP) |
| secretImageUri | String | Google Authenticator QR code URI |
| lastCompanyId | String | Last selected company ID |
| requiresRecaptchaV2 | Boolean | Whether reCAPTCHA v2 verification is required |
| message | String | Status message (e.g., "MFA required") |
| active | Boolean | Whether user account is active |
| isAppLogin | Boolean | Whether this is a mobile app login |
Parameter Values Reference Table
currentCountry Values (Sample List)
| Value | Description |
|---|---|
| DE | Germany |
| AT | Austria |
| RO | Romania |
| KZ | Kazakhstan |
| TR | Turkey |
| FI | Finland |
| FR | France |
| IT | Italy |
| NL | Netherlands |
| ES | Spain |
| SE | Sweden |
| PL | Poland |
| BE | Belgium |
| DK | Denmark |
| NO | Norway |
| MY | Malaysia |
| SG | Singapore |
| AU | Australia |
| NZ | New Zealand |
| JP | Japan |
| EG | Egypt |
| RS | Serbia |
| GLOBAL | Global (default) |
Company Information Fields
| Field | Type | Description |
|---|---|---|
| id | String | Company unique identifier |
| name | String | Company name |
| taxNumber | String | Tax number |
| vatNumber | String | VAT number |
| String | Company email address | |
| website | String | Company website |
| address | String | Address |
| city | String | City |
| state | String | State or Region |
| country | Enum | Country code |
| postalCode | String | Postal code |
| phoneNumber | String | Phone number |
| faxNumber | String | Fax number |
| credit | Integer | Available credit |
| userCount | Integer | Total user count |
| portalType | Enum | Portal type |
| mailLanguage | Enum | Email language |
| currencyCode | String | Currency code |
| sftp | Boolean | Whether SFTP integration is active |
| isSubCompany | Boolean | Whether it's a sub company |
| featureAllowed | Boolean | Whether feature access is granted |
| participants | Array | Peppol participant information |
User Information Fields
| Field | Type | Description |
|---|---|---|
| id | String | User unique identifier |
| String | User email address | |
| firstName | String | User first name |
| lastName | String | User last name |
| phoneNumber | String | User phone number |
| photoUrl | String | User photo URL |
| mailLang | Enum | User email language |
| isSuperAdmin | Boolean | Whether user has super admin privileges |
| lastLoginTime | DateTime | Last login time |
| featureAllowed | Boolean | Whether feature access is granted |
Enum Values Reference Table
mfaType Values
| Value | Description |
|---|---|
| Google Authenticator verification | |
| WhatsApp verification |
portalType Values
| Value | Description |
|---|---|
| DEFAULT | Default portal |
| RECHNUNG | Germany main portal |
| KZ | Kazakhstan portal |
| RO | Romania portal |
| AU | Australia portal |
| AT | Austria portal |
| BE | Belgium portal |
| DK | Denmark portal |
| EG | Egypt portal |
| FI | Finland portal |
| FR | France portal |
| IT | Italy portal |
| MY | Malaysia portal |
| NL | Netherlands portal |
| NO | Norway portal |
| PL | Poland portal |
| RS | Serbia portal |
| SE | Sweden portal |
| SG | Singapore portal |
mailLanguage Values
| Value | Description |
|---|---|
| DE | German |
| EN | English |
| TR | Turkish |
| RO | Romanian |
| PL | Polish |
| FR | French |
| IT | Italian |
| ES | Spanish |
| NL | Dutch |
200 - Login Successful
Basic Response (JwtBasicResponse)
{
"jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expirationDate": "2026-01-30T10:30:00.000Z"
}
401 - Unauthorized
{
"timestamp": "2026-01-29T10:30:00.000Z",
"status": 401,
"error": "Unauthorized",
"message": "Invalid email or password"
}
403 - MFA Required
{
"id": "user-uuid",
"mfaEnabled": true,
"mfaType": "GOOGLE",
"message": "MFA verification required",
"jwt": null
}
429 - Too Many Requests
{
"timestamp": "2026-01-29T10:30:00.000Z",
"status": 429,
"error": "Too Many Requests",
"message": "Too many failed login attempts. Please try again later.",
"requiresRecaptchaV2": true
}
3. Search Processing History POST
Purpose of Use: The POST /invoice/document-process/search endpoint serves as the central monitoring and querying interface for all document processing activities within the system. Every document whether it is an invoice, credit note, or waybill that enters or leaves the platform passes through an asynchronous processing pipeline. This endpoint provides full visibility into that pipeline.
Endpoint Information
| Property | Value |
|---|---|
| URL | /invoice/document-process/search |
| Method | POST |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
| Required Authority | ADMIN, INCOMING_INVOICE_DISPLAY, or OUTGOING_INVOICE_DISPLAY (at least one) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/invoice/document-process/search?page=0&size=20&sort=createdAt,desc' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: <JWT_TOKEN>' \
--data '{
"companyId": "<COMPANY_UUID>",
"createdAt": {
"from": "2024-01-01",
"to": "2026-02-28"
}
}'
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| companyId | UUID | Yes | Unique identifier of the company to search |
| direction | String (Enum) | No | Document direction filter (INCOMING or OUTGOING) |
| source | String (Enum) | No | Source system filter |
| filename | String | No | Exact match filter by filename |
| status | String (Enum) | No | Document processing status filter |
| createdAt | Object (DateRange) | No | Creation date range filter |
| createdAt.from | String (LocalDate) | No | Start date (inclusive). Format: yyyy-MM-dd. Must be past or present |
| createdAt.to | String (LocalDate) | No | End date (inclusive). Format: yyyy-MM-dd. Must be past or present |
Query Parameters (Pagination)
| Field | Type | Default | Description |
|---|---|---|---|
| page | Integer | 0 | Page number (0 indexed) |
| size | Integer | 20 | Number of records per page (max 100) |
| sort | String | createdAt,desc | Sort field and direction. Format: field,asc|desc |
Enum Value Reference
direction Values (Document Direction)
| Value | Description |
|---|---|
| INCOMING | Incoming document |
| OUTGOING | Outgoing document |
status Values (Processing Status)
| Value | Description |
|---|---|
| PENDING | Queued and waiting for processing |
| PROCESSING | Currently being processed |
| COMPLETED | Successfully completed |
| FAILED | Processing failed (retriable) |
| SENDING_FAILED | Failed at the sending stage |
| PERMANENT_FAILED | Permanently failed (will not be retried) |
source Values (Source and Target System)
| Value | Description |
|---|---|
| ERP | ERP integration |
| PORTAL | Web portal |
| PORTAL_OCR | Portal upload via OCR |
| EMAIL_OCR | OCR via email |
| PEPPOL | Peppol network |
| SFTP | SFTP connection |
| KSEF | Poland KSeF system |
| ANAF | Romania ANAF system |
| LHDNM | Malaysia LHDNM system |
| NEMHANDEL | Denmark NemHandel |
| RS_API | Serbia API |
| ETA | Egypt ETA system |
| ERACUN | eRacun system |
| HARVEST | Harvest integration |
| SHOPIFY | Shopify integration |
| AMAZON_SP | Amazon SP API |
| EBAY | eBay integration |
| HUBSPOT | HubSpot integration |
| LAZADA | Lazada integration |
| STRIPE | Stripe integration |
| SERVICE | Internal service |
documentType Values (Document Format)
| Value | Description |
|---|---|
| PEPPOL_BIS | Peppol BIS 3.0 |
| XRECHNUNG_CII | XRechnung (CII) |
| ZUGFERD | ZUGFeRD |
| FACTUR_X | Factur X |
| CII | Cross Industry Invoice |
| CID | CID format |
| RO_EFACTURA | Romania e Factura |
| MY_INVOIS | Malaysia MyInvois |
| MY_PINT | Malaysia PINT |
| DK_OIOUBL | Denmark OIOUBL |
| EG_INVOICE | Egypt invoice |
| HR_INVOICE | Croatia invoice |
| UAE_PINT | UAE PINT |
| KZ_ESF_V2 | Kazakhstan ESF v2 |
| KSEF | Poland KSeF |
| KSEF_OFFLINE | Poland KSeF (offline) |
waybillType Values (Waybill Type)
| Value | Description |
|---|---|
| RS_WAYBILL_DESPATCH | Serbia despatch waybill |
| RS_WAYBILL_RECEIPT | Serbia receipt waybill |
| RS_APPLICATION_RESPONSE | Serbia application response |
| RO_ETRANSPORT | Romania e Transport |
Responses
200 - Successful Response
{
"content": [
{
"trackingId": "a1b2c3d4-...",
"companyId": "60ccd1a7-...",
"direction": "INCOMING",
"documentType": "XRECHNUNG",
"waybillType": null,
"source": "ERP",
"target": "PEPPOL",
"status": "COMPLETED",
"filename": "invoice_2024_001.xml",
"invoiceNumber": "INV-2024-001",
"documentId": "f5e6d7c8-...",
"sendingResult": "OK",
"errorType": null,
"errors": null,
"additionalData": null,
"createdAt": "2024-06-15T10:30:00",
"statusUpdatedAt": "2024-06-15T10:30:45",
"completedAt": "2024-06-15T10:31:00"
}
],
"totalElements": 150,
"totalPages": 8,
"number": 0,
"size": 20
}
Response Fields
| Field | Type | Description |
|---|---|---|
| content | Array<Object> | Page content (document processing records) |
| content[].trackingId | UUID | Processing tracking identifier |
| content[].companyId | UUID | Company identifier |
| content[].direction | String (Enum) | Document direction (INCOMING / OUTGOING) |
| content[].documentType | String (Enum) | Document format (see documentType enum table) |
| content[].waybillType | String (Enum) | null | Waybill type (only for waybill documents) |
| content[].source | String (Enum) | Source system of the document |
| content[].target | String (Enum) | null | Target system for the document |
| content[].status | String (Enum) | Current processing status |
| content[].filename | String | Original filename |
| content[].invoiceNumber | String | null | Invoice number |
| content[].documentId | UUID | null | Associated document identifier |
| content[].sendingResult | String | null | Sending result message |
| content[].errorType | String (Enum) | null | Error type code (on failed processes) |
| content[].errors | Object | null | Error details (validation errors, message list, or text) |
| content[].additionalData | Object | null | Country or document type specific metadata |
| content[].createdAt | String (DateTime) | Creation timestamp. Format: yyyy-MM-ddTHH:mm:ss |
| content[].statusUpdatedAt | String (DateTime) | Last status update timestamp |
| content[].completedAt | String (DateTime) | null | Completion timestamp (only when COMPLETED) |
| totalElements | Long | Total number of matching records |
| totalPages | Integer | Total number of pages |
| number | Integer | Current page number (0-indexed) |
| size | Integer | Number of records per page |
400 - Bad Request
Trigger: When the companyId field is sent as null in the request body (@NotNull validation) or when required fields are missing.
Scenario: Sending a request without providing companyId.
{
"errorMessage": "Document process required fields: companyId",
"errorType": "DOCUMENT_PROCESS_REQUIRED_FIELDS",
"errorTitle": "BAD_REQUEST",
"errorId": "corr-8f2a1b3c",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/document-process/search"
}
400 - Bad Request
Trigger: When the request body JSON format is malformed, an invalid enum value is sent, or the date format is incorrect.
Scenario: Sending a value like "UNKNOWN_STATUS" that is not defined in the enum for the status field, or sending an invalid date like "2024-13-45" for the createdAt.from field.
{
"errorMessage": "Invalid request. Cannot deserialize value of type `DocumentProcessStatus` from String \"UNKNOWN_STATUS\"",
"errorType": "INVALID_REQUEST",
"errorTitle": "BAD_REQUEST",
"errorId": "corr-4d5e6f7a",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/document-process/search"
}
401 - Unauthorized
Trigger: When the R-Auth header is not provided or the JWT token signature is invalid. This error is caught at the Spring Security filter chain and does not reach the RestExceptionHandler.
Scenario: Sending a request without the header or with a corrupted/tampered token.
{
"error": "Unauthorized",
"message": "Full authentication is required to access this resource",
"status": 401
}
401 - Unauthorized
Trigger: When the JWT token is valid but the user does not have any of the ADMIN, INCOMING_INVOICE_DISPLAY, or OUTGOING_INVOICE_DISPLAY authorities on the specified companyId. Thrown by AuthorizationService.checkAnyAuthorityByCompanyAndUser().
Scenario: Performing a search with a companyId for which the user has no access permissions.
{
"errorMessage": "User is not authorized for this operation",
"errorType": "AUTHORIZATION_FAILED",
"errorTitle": "UNAUTHORIZED",
"errorId": "corr-9a8b7c6d",
"status": 401,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/document-process/search"
}
404 - Not Found
Trigger: When the provided companyId value is not found in the database. A NotFoundException is thrown by CompanyService.
Scenario: Sending a UUID as companyId that has been deleted or never existed.
{
"errorMessage": "Company not found!",
"errorType": "COMPANY_NOT_FOUND",
"errorTitle": "NOT_FOUND",
"errorId": "corr-1b2c3d4e",
"status": 404,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/document-process/search"
}
498 - Token Expired
Trigger: When the JWT token has expired. Returned by CustomAuthenticationEntryPoint at the Spring Security filter level.
Scenario: Sending a request with an expired JWT token.
{
"errorMessage": "Your session has expired. Please login again.",
"errorType": "TOKEN_EXPIRED",
"errorTitle": "UNAUTHORIZED",
"status": null,
"timestamp": null,
"path": null
}
Note: Since this response is generated at the Security filter level, the timestamp, path, and status fields are not populated by enrichResponse and return null. A custom HTTP status code of 498 is used.
500 - Internal Server Error
Trigger: When an unexpected error occurs on the server side (database connection failure, NullPointerException, etc.). Caught by the RestExceptionHandler catch-all handler.
Scenario: Database access failure, unexpected runtime exception.
{
"errorMessage": "An unexpected error occurred",
"errorType": "SERVER_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"errorId": "corr-5e6f7a8b",
"status": 500,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/document-process/search"
}
Response Structure Reference (ExceptionResponse)
| Field | Type | Description | Inclusion Condition |
|---|---|---|---|
| errorMessage | String | Human readable error description | Always |
| errorType | String | Machine readable error code (ErrorType enum name) | Always |
| errorTitle | String (HttpStatus) | HTTP status description (BAD_REQUEST, UNAUTHORIZED, etc.) | Always |
| errorId | String | Correlation ID (for log tracing) | If present in ThreadContext |
| status | Integer | HTTP status code (numeric) | Always |
| timestamp | String (DateTime) | Timestamp when the error occurred | By RestExceptionHandler |
| path | String | URI of the request | By RestExceptionHandler |
| data | String | Additional data information | If present (@JsonInclude NON_NULL) |
| details | Map<String, Object> | Additional detail information | If present (@JsonInclude NON_NULL) |
| validationErrors | Array<ValidationError> | Field level validation errors | If present (@JsonInclude NON_NULL) |
Note: The ExceptionResponse class uses @JsonInclude(JsonInclude.Include.NON_NULL). Therefore, fields with null values are excluded from the JSON response.
4. Send Document Async POST
Purpose of Use: This endpoint enables ERP systems to transmit e-invoice data to the docnova portal asynchronously. It is designed to enhance system responsiveness and efficiently manage the process queue during high-volume data transfers.
After generating an invoice in compliance with German legal standards (XRechnung or ZUGFeRD), the ERP system converts the document into base64 format and transmits it to the portal. Since this method operates asynchronously, the ERP system receives a tracking ID (trackingId) without waiting for the full processing of the document. This prevents delays in ERP-side workflows, and the final status of the document can be queried later using the provided tracking ID.
Endpoint Information
| Property | Value |
|---|---|
| URL | /invoice/send-document-async |
| Method | POST |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | JWT Token (R-Auth header) or API Key |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/invoice/send-document-async' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: {{jwt_token}}' \
--data-raw '{
"apiKey": "{{your_api_key}}",
"base64Document": "{{base64_encoded_xml}}",
"base64Pdf": "{{base64_encoded_pdf}}",
"businessType": "B2B",
"compId": "{{company_uuid}}",
"invoiceSource": "PORTAL",
"invoiceType": "ZUGFERD",
"receiverEmails": [
"recipient@example.com"
],
"mailTemplateId": "{{template_id}}"
}'
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| compId | String (UUID) | Conditional* | Company unique identifier. Required if apiKey is not provided. |
| apiKey | String | Conditional* | API key. Required if compId is not provided. |
| base64Document | String | Conditional** | Base64-encoded XML document. Required if base64Pdf is not provided. |
| base64Pdf | String | Conditional** | Base64-encoded PDF document. Required if base64Document is not provided. |
| invoiceType | Enum | Conditional*** | Invoice format type. Required if waybillType is not provided. |
| waybillType | Enum | Conditional*** | Waybill format type. Required if invoiceType is not provided. |
| businessType | Enum | No | Business model type (B2B, B2C, B2G). |
| invoiceSource | Enum | No | Document source. |
| receiverEmails | Array<String> | No | List of recipient email addresses. |
| mailTemplateId | String | No | Email template identifier. |
Note:
- (*) At least one of compId or apiKey must be provided.
- (**) At least one of base64Document or base64Pdf must be provided.
- (***) At least one of invoiceType or waybillType must be provided.
businessType Values
| Value | Description |
|---|---|
| B2B | Business to Business |
| B2C | Business to Consumer |
| B2G | Business to Government |
invoiceSource Values
| Value | Description |
|---|---|
| PORTAL | Submission via web portal |
| PORTAL_OCR | Portal with OCR processing |
| Via email | |
| EMAIL_OCR | Email with OCR processing |
| ERP | ERP system integration |
| PEPPOL | Via Peppol network |
| LHDNM | Malaysia LHDNM system |
| NEMHANDEL | Denmark NemHandel |
| SERVICE | Service integration |
| HARVEST | Harvest integration |
| SHOPIFY | Shopify integration |
| AMAZON_SP | Amazon SP-API integration |
| EBAY | eBay integration |
| HUBSPOT | HubSpot integration |
| ANAF | Romania ANAF system |
| LAZADA | Lazada integration |
| SFTP | Via SFTP |
| KSEF | Poland KSeF system |
| RS_API | Serbia API |
| ETA | Egypt ETA system |
| ERACUN | Indonesia e-Racun |
| STRIPE | Stripe integration |
invoiceType Values
| Value | Group | Description |
|---|---|---|
| PEPPOL_BIS | XRECHNUNG | Peppol BIS 3.0 format |
| XRECHNUNG | XRECHNUNG | German XRechnung format |
| RO_EFACTURA | XRECHNUNG | Romania e-Factura format |
| ZUGFERD | ZUGFERD | ZUGFeRD format (PDF/A-3 with XML) |
| FACTUR_X | ZUGFERD | Factur-X format (France) |
| XRECHNUNG_CII | ZUGFERD | XRechnung CII profile |
| CII | ZUGFERD | Cross Industry Invoice format |
| CID | ZUGFERD | CID format |
| ZUGFERD | PDF format | |
| MY_INVOIS | Country-Specific | Malaysia MyInvois format |
| MY_PINT | Country-Specific | Malaysia PINT format |
| DK_OIOUBL | Country-Specific | Denmark OIOUBL format |
| EG_INVOICE | Country-Specific | Egypt e-Invoice format |
| HR_INVOICE | Country-Specific | Croatia e-Invoice format |
| UAE_PINT | Country-Specific | UAE PINT format |
| KZ_ESF_V2 | Kazakhstan | Kazakhstan ESF v2 |
| KSEF | Poland | Poland KSeF format |
| KSEF_OFFLINE | Poland | Poland KSeF offline |
waybillType Values
| Value | Description |
|---|---|
| RS_WAYBILL_DESPATCH | Serbia despatch waybill |
| RS_WAYBILL_RECEIPT | Serbia receipt waybill |
| RS_APPLICATION_RESPONSE | Serbia application response |
| RO_ETRANSPORT | Romania e-Transport |
Responses
200 - Successful Response
{
"trackingId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": "PENDING",
"message": "Document queued for processing"
}
Response Fields
| Field | Type | Description |
|---|---|---|
| trackingId | UUID | Unique process tracking identifier. This ID can be used to query the processing status. |
| status | Enum | Current status of the process. |
| message | String | Descriptive message about the status. |
status Values
| Value | Description |
|---|---|
| PENDING | Process queued, not yet started |
| PROCESSING | Process in progress |
| COMPLETED | Process completed successfully |
| FAILED | Process failed |
| SENDING_FAILED | Sending failed |
| PERMANENT_FAILED | Permanent failure, will not be retried |
400 - Bad Request
{
"trackingId": null,
"status": "FAILED",
"message": "Either invoiceType or waybillType must be provided"
}
401 - Unauthorized
{
"timestamp": "2026-01-29T10:30:00.000Z",
"status": 401,
"error": "Unauthorized",
"message": "Invalid or expired token"
}
500 - Internal Server Error
{
"trackingId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "FAILED",
"message": "An unexpected error occurred"
}
5. Send Document Async JSON POST
Purpose of Use: This endpoint allows invoice data compliant with UBL 2.1 / PEPPOL BIS standards to be submitted asynchronously as a JSON object (ublDto). No base64-encoded file upload is required; all invoice details are provided directly in a structured JSON format.
When the request is accepted, the document is placed in the processing queue and a trackingId is returned. The processing status can be queried at any time using this ID via the /invoice/document-status/{trackingId} endpoint.
Endpoint Information
| Property | Value |
|---|---|
| URL | /invoice/send-document-async-json |
| Method | POST |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/invoice/send-document-async-json' \
--header 'accept: */*' \
--header 'R-Auth: eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJNTU0iLCJzdWIiOiJsYmxyRWNuT2JZUVN3KzNtQ29yM1RJSGFLOFQ4UmlwTGlwai9QREtkVk9pNktPazNSOEhldEdES0FQNzJoQStwV00rZUJLREtLWmpZWXBEN1pzK3JCZz09IiwiY2xhaW0iOiJJU0dXSXIvb2F3elUrdnVPK1FleWx4UzUrL280NnhNR3lFdXE2ZDVyaEpuRjNVRW1xVFRya01uUTRzZng5ZmhQWklyOW1Qb3lIUVV4RnpYMU82WkpndkVoVkRoTElWV2F4L1JCNUVVY0xUaz0iLCJ1c2VyVHlwZSI6IkNMSUVOVCIsImV4cCI6MTc4MjIxNzIyMX0.gg4J1DZ8URY5DrFApiPZ81Pb_QmLMn9W16PppRA1dv7syxbmRQakPYs8w4Op-WVf64SgPtBDCaoNL1d2bZ3O0g' \
--header 'Content-Type: application/json' \
--data-raw '{
"apiKey": "tBhGHW7gREjwJ0AGcAK5GNO8pWORIjw4",
"businessType": "B2B",
"ublDto": {
"UBLVersionID": {
"Value": "2.1",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
},
"CustomizationID": {
"Value": "urn:cen.eu:en16931:2017#compliant#urn:peppol:france:billing:cius:1.0::2.1",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
},
"ProfileID": {
"Value": "B1",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
},
"ID": {
"Value": "35000205577",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
},
"IssueDate": {
"Value": "2025-01-17"
},
"DueDate": {
"Value": "2025-01-17"
},
"InvoiceTypeCode": {
"Value": "380",
"listAgencyID": "",
"listID": "",
"listVersionID": "",
"name": ""
},
"Note": [
{
"Value": "BANQUE POPULAIRE AUVERGNE RHÔNE ALPES IBAN : FR76 1680 7004 0082 0722 9721 667 SWIFT : CCBPFRPPGRE"
}
],
"TaxPointDate": {
"Value": "2026-06-17"
},
"DocumentCurrencyCode": {
"Value": "EUR",
"listAgencyID": "",
"listID": "",
"listVersionID": "",
"name": ""
},
"CompanyId": "b7844db0-57a1-4f5d-af65-...",
"Format": "EASY_INVOICE",
"Type": "FR_UBL_CIUS",
"ProfileType": "EN16931",
"IsPeppolParticipant": false,
"PeppolParticipantId": "",
"OrderReference": {
"ID": {
"Value": "969118",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
},
"SalesOrderID": {
"Value": "0000969118",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
}
},
"AccountingSupplierParty": {
"Party": {
"EndpointID": {
"Value": "271688503",
"schemeID": "0002",
"schemeAgencyID": "",
"schemeAgencyName": ""
},
"PartyName": [
{
"Name": {
"Value": "Kerakoll France"
}
}
],
"PostalAddress": {
"StreetName": {
"Value": "Avenue de l'\''industrie"
},
"BuildingNumber": {
"Value": "25"
},
"CityName": {
"Value": "Corbas Cedex"
},
"PostalZone": {
"Value": "69964"
},
"Country": {
"IdentificationCode": {
"Value": "FR",
"listAgencyID": "",
"listID": "",
"listVersionID": ""
}
}
},
"PartyTaxScheme": [
{
"CompanyID": {
"Value": "FR99271688503",
"schemeID": "",
"schemeAgencyID": "",
"schemeAgencyName": ""
},
"TaxScheme": {
"ID": {
"Value": "VAT",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
}
}
}
],
"PartyLegalEntity": [
{
"RegistrationName": {
"Value": "Kerakoll France"
},
"CompanyID": {
"Value": "FR99271688503",
"schemeID": "",
"schemeAgencyID": "",
"schemeAgencyName": ""
},
"CompanyLegalForm": null
}
],
"Contact": {
"Name": {
"Value": "Kerakoll France"
},
"ElectronicMail": null,
"Telephone": null
}
}
},
"AccountingCustomerParty": {
"Party": {
"EndpointID": {
"Value": "142057869",
"schemeID": "0002",
"schemeAgencyID": "",
"schemeAgencyName": ""
},
"PartyName": [
{
"Name": {
"Value": "PLATTARD CARRELAGES-VILLEFRANCHE"
}
}
],
"PostalAddress": {
"StreetName": {
"Value": "3027008449225"
},
"AdditionalStreetName": null,
"CityName": {
"Value": "VILLEFRANCHE SUR SAONE"
},
"PostalZone": {
"Value": "69654"
},
"Country": {
"IdentificationCode": {
"Value": "FR",
"listAgencyID": "",
"listID": "",
"listVersionID": ""
}
}
},
"PartyTaxScheme": [
{
"CompanyID": {
"Value": "FR99142057869",
"schemeID": "",
"schemeAgencyID": "",
"schemeAgencyName": ""
},
"TaxScheme": {
"ID": {
"Value": "VAT",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
}
}
}
],
"PartyLegalEntity": [
{
"RegistrationName": {
"Value": "PLATTARD CARRELAGES-VILLEFRANCHE"
},
"CompanyID": null,
"CompanyLegalForm": null
}
],
"Contact": {
"Name": {
"Value": "PLATTARD CARRELAGES-VILLEFRANCHE"
},
"Telephone": {
"Value": "0478801221"
},
"ElectronicMail": {
"Value": "jeremy-gandois@plattard.com"
}
}
}
},
"PaymentMeans": [
{
"PaymentMeansCode": {
"Value": "42",
"listAgencyID": "",
"listID": "",
"listVersionID": "",
"name": ""
},
"PayeeFinancialAccount": null
}
],
"TaxTotal": [
{
"TaxAmount": {
"Value": "15.76",
"currencyID": "EUR"
},
"TaxSubtotal": [
{
"TaxableAmount": {
"Value": "78.81",
"currencyID": "EUR"
},
"TaxAmount": {
"Value": "15.76",
"currencyID": "EUR"
},
"TaxCategory": {
"ID": {
"Value": "S",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
},
"Percent": {
"Value": "20",
"format": ""
},
"TaxScheme": {
"ID": {
"Value": "VAT",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
}
}
}
}
]
}
],
"LegalMonetaryTotal": {
"LineExtensionAmount": {
"Value": "78.81",
"currencyID": "EUR"
},
"TaxExclusiveAmount": {
"Value": "78.81",
"currencyID": "EUR"
},
"TaxInclusiveAmount": {
"Value": "94.57",
"currencyID": "EUR"
},
"AllowanceTotalAmount": {
"Value": "",
"currencyID": "EUR"
},
"ChargeTotalAmount": {
"Value": "",
"currencyID": "EUR"
},
"PrepaidAmount": {
"Value": "",
"currencyID": "EUR"
},
"PayableAmount": {
"Value": "94.57",
"currencyID": "EUR"
}
},
"InvoiceLine": [
{
"ID": {
"Value": "10",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
},
"InvoicedQuantity": {
"Value": "12.000",
"unitCode": "KGM"
},
"LineExtensionAmount": {
"Value": 41.86,
"currencyID": "EUR"
},
"Item": {
"Name": {
"Value": "K0001E.01"
},
"Description": null,
"ClassifiedTaxCategory": [
{
"ID": {
"Value": "S",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
},
"Percent": {
"Value": "20",
"format": ""
},
"TaxScheme": {
"ID": {
"Value": "VAT",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
}
}
}
]
},
"Price": {
"PriceAmount": {
"Value": "3.4883",
"currencyID": "EUR"
},
"BaseQuantity": null
}
},
{
"ID": {
"Value": "20",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
},
"InvoicedQuantity": {
"Value": "12.000",
"unitCode": "KGM"
},
"LineExtensionAmount": {
"Value": 36.95,
"currencyID": "EUR"
},
"Item": {
"Name": {
"Value": "K0001I.01"
},
"Description": null,
"ClassifiedTaxCategory": [
{
"ID": {
"Value": "S",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
},
"Percent": {
"Value": "20",
"format": ""
},
"TaxScheme": {
"ID": {
"Value": "VAT",
"schemeAgencyID": "",
"schemeAgencyName": "",
"schemeID": ""
}
}
}
]
},
"Price": {
"PriceAmount": {
"Value": "3.0792",
"currencyID": "EUR"
},
"BaseQuantity": null
}
}
],
"BillingReference": null,
"AdditionalDocumentReference": null,
"AllowanceCharge": null,
"Delivery": null,
"BuyerReference": null,
"PartnerUuid": "e960da1f-4240-44d0-9070-...",
"DraftUuid": "",
"ExternalInvoiceId": "",
"InvoiceUuid": "",
"OcrUuid": "",
"LeitwegId": "",
"ehfNorwayForetaksregisteret": false,
"ehfNorwayPaymentAccountKind": "BBAN"
}
}
'
Request Parameters
Body Parameters
Root Object
| Field Name | Type | Required | Description |
|---|---|---|---|
| apiKey | string | Conditional | API key used to identify the company. Required if ublDto.CompanyId is not provided. |
| ublDto | object (UBLDto) | Yes | UBL 2.1 compliant invoice data structure containing all invoice details. |
ublDto — Document Object
| Field Name | Type | Required | Description |
|---|---|---|---|
| ublDto.Type | string (enum) | Optional | Document format type. E.g.: PEPPOL_BIS, XRECHNUNG, ZUGFERD. See Parameter Values Reference table for full list. |
| ublDto.IsPeppolParticipant | boolean | Optional | Indicates whether the recipient is registered on the Peppol network. If true, the document is routed via Peppol. |
| ublDto.CompanyId | string (UUID) | Conditional | UUID of the sending company. Required if apiKey is not provided. |
| ublDto.ProfileType | string (enum) | Optional | ZUGFeRD / Factur-X profile type. Default: EN16931. |
| ublDto.CustomizationID.Value | string | Optional | Invoice customization identifier (urn value). Specifies PEPPOL / EN16931 compliance. |
| ublDto.ID.Value | string | Optional | Invoice number / unique document identifier. |
| ublDto.IssueDate.Value | string (ISO 8601) | Optional | Invoice issue date. Format: YYYY-MM-DD. |
| ublDto.DueDate.Value | string (ISO 8601) | Optional | Invoice due date. Format: YYYY-MM-DD. |
| ublDto.InvoiceTypeCode.Value | string | Optional | UN/CEFACT invoice type code. E.g.: 380 = Commercial Invoice, 381 = Credit Note, 384 = Corrected Invoice. |
| ublDto.Note[].Value | string | Optional | Free-text note attached to the invoice. |
| ublDto.DocumentCurrencyCode.Value | string | Optional | Invoice currency code (ISO 4217). E.g.: EUR, USD, GBP. |
| ublDto.BuyerReference.Value | string | Optional | Buyer reference number (Buyer Reference / Leitweg-ID). |
| ublDto.OrderReference.ID.Value | string | Optional | Purchase order number. |
| ublDto.OrderReference.SalesOrderID.Value | string | Optional | Sales order number. |
| ublDto.AccountingSupplierParty | object | Optional | Supplier / seller information. The Party object contains EndpointID (Peppol ID), PartyName, PostalAddress, PartyTaxScheme, PartyLegalEntity, and Contact sub-objects. |
| ublDto.AccountingSupplierParty.Party.EndpointID.Value | string | Optional | Supplier's Peppol Endpoint ID value. |
| ublDto.AccountingSupplierParty.Party.EndpointID.schemeID | string | Optional | Endpoint ID scheme code. E.g.: 9930 = German Tax No, 0088 = GLN. |
| ublDto.AccountingCustomerParty | object | Optional | Customer / buyer information. The Party object contains EndpointID, PartyName, PostalAddress, PartyTaxScheme, PartyLegalEntity, and Contact sub-objects. |
| ublDto.Delivery[].ActualDeliveryDate.Value | string (ISO 8601) | Optional | Actual delivery date. Format: YYYY-MM-DD. |
| ublDto.Delivery[].DeliveryLocation.Address | object | Optional | Delivery address. Contains StreetName, CityName, PostalZone, and Country sub-fields. |
| ublDto.PaymentMeans[].PaymentMeansCode.Value | string | Optional | Payment method code. E.g.: 58 = SEPA Credit Transfer, 30 = Credit Transfer, 49 = Direct Debit. |
| ublDto.PaymentMeans[].PayeeFinancialAccount.ID.Value | string | Optional | Payee bank account IBAN number. |
| ublDto.PaymentMeans[].PayeeFinancialAccount.Name.Value | string | Optional | Bank account holder name. |
| ublDto.PaymentTerms[].Note[].Value | string | Optional | Free-text description of payment terms. |
| ublDto.TaxTotal[].TaxAmount.Value | number | Optional | Total tax amount. |
| ublDto.TaxTotal[].TaxAmount.currencyID | string | Optional | Currency code for the tax amount (ISO 4217). |
| ublDto.TaxTotal[].TaxSubtotal[].TaxableAmount.Value | number | Optional | Taxable base amount. |
| ublDto.TaxTotal[].TaxSubtotal[].TaxCategory.ID.Value | string | Optional | Tax category code. E.g.: S = Standard, Z = Zero Rated, E = Exempt, AE = Reverse Charge. |
| ublDto.TaxTotal[].TaxSubtotal[].TaxCategory.Percent.Value | number | Optional | Tax rate percentage. E.g.: 19, 7, 10. |
| ublDto.LegalMonetaryTotal.LineExtensionAmount.Value | number | Optional | Sum of invoice line net amounts (excluding tax). |
| ublDto.LegalMonetaryTotal.TaxExclusiveAmount.Value | number | Optional | Total amount excluding VAT. |
| ublDto.LegalMonetaryTotal.TaxInclusiveAmount.Value | number | Optional | Total amount including VAT. |
| ublDto.LegalMonetaryTotal.PayableAmount.Value | number | Optional | Net payable amount. |
| ublDto.InvoiceLine[].ID.Value | string | Optional | Invoice line sequence number. |
| ublDto.InvoiceLine[].InvoicedQuantity.Value | number | Optional | Invoiced quantity. |
| ublDto.InvoiceLine[].InvoicedQuantity.unitCode | string | Optional | Unit of measure code (UN/ECE Rec. 20). E.g.: MTQ = Cubic Metre, C62 = Each, KGM = Kilogram. |
| ublDto.InvoiceLine[].LineExtensionAmount.Value | number | Optional | Invoice line net amount (excluding tax). |
| ublDto.InvoiceLine[].Item.Name.Value | string | Optional | Product / service name. |
| ublDto.InvoiceLine[].Item.SellersItemIdentification.ID.Value | string | Optional | Seller's item/product code. |
| ublDto.InvoiceLine[].Price.PriceAmount.Value | number | Optional | Unit price. |
| ublDto.InvoiceLine[].Price.BaseQuantity.Value | number | Optional | Base quantity the price applies to. Typically 1. |
| receiverEmails | array (string) | Optional | Recipient email addresses for sending the invoice via email after processing. |
| mailTemplateId | string | Optional | Custom mail template ID to be used for email delivery. |
| businessType | string (enum) | Optional | Business model type: B2B, B2C, or B2G. |
Notes:
- At least one of apiKey or ublDto.CompanyId must be provided. Both cannot be null simultaneously.
- When ublDto.CompanyId is not provided, the system resolves the company via the apiKey.
- For AccountingSupplierParty and AccountingCustomerParty, the EndpointID.schemeID uses Peppol Participant Identifier Scheme codes (e.g.: 9930 = German Tax No, 0088 = GLN, 0184 = Danish CVR).
- InvoiceLine[].InvoicedQuantity.unitCode uses UN/ECE Recommendation 20 unit codes (e.g.: MTQ = Cubic Metre, C62 = Each, KGM = Kilogram, LTR = Litre).
Responses
200 - Successful Response
Request accepted successfully. The document has been placed in the processing queue. Use the returned trackingId to query processing status at /invoice/document-status/{trackingId}.
Response body (AsyncERPResponse)
{
"trackingId": "{{entity_uuid}}",
"status": "PENDING",
"message": "Document process started successfully"
}
Response Fields
| Field | Type | Description |
|---|---|---|
| trackingId | string (UUID) | Document processing tracking ID. Used in the /invoice/document-status/{trackingId} endpoint. |
| status | string (enum) | Immediate processing status of the document. Returns PENDING initially. |
| message | string | Informational message about the process initiation. |
Parameter Value Reference
Document Format Type (ublDto.Type)
| Value | Description |
|---|---|
| PEPPOL_BIS | PEPPOL BIS Billing 3.0 format (UBL-based) |
| XRECHNUNG | Germany XRechnung format (UBL-based) |
| ZUGFERD | ZUGFeRD format (PDF/A-3 + embedded XML) |
| FACTUR_X | France Factur-X format (PDF/A-3 + embedded XML) |
| XRECHNUNG_CII | Germany XRechnung CII format |
| CII | UN/CEFACT Cross Industry Invoice format |
| CID | Cross Industry Document format |
| MY_INVOIS | Malaysia MyInvois format |
| MY_PINT | Malaysia PINT format |
| DK_OIOUBL | Denmark OIOUBL format |
| RO_EFACTURA | Romania e-Invoice format |
| UAE_PINT | UAE PINT format |
| HR_INVOICE | Croatia invoice format |
| EG_INVOICE | Egypt invoice format |
| KSEF | Poland KSeF format |
Profile Type (ublDto.ProfileType)
| Value | Description |
|---|---|
| EN16931 | EN 16931 compliant profile (default) |
| EXTENDED | Extended profile |
| BASIC | Basic profile |
Business Model Type (businessType)
| Value | Description |
|---|---|
| B2B | Business to Business |
| B2C | Business to Consumer |
| B2G | Business to Government |
400 - Bad Request
Trigger: When both apiKey and ublDto.CompanyId are null.
Response body:
{
"errorMessage": "apiKey or companyId field is required",
"errorType": "DOCUMENT_PROCESS_REQUIRED_FIELDS",
"errorTitle": "BAD_REQUEST",
"status": 400,
"errorId": "{{correlation_id}}",
"timestamp": "2026-01-15T12:00:00",
"path": "/invoice/send-document-async-json"
}
An IllegalArgumentException is thrown when both apiKey and ublDto.CompanyId are null, returning a 400 Bad Request response.
Trigger: When the provided apiKey does not match any record in the system.
Response body:
{
"errorMessage": "Api Key Didnt Match",
"errorType": "API_ERROR",
"errorTitle": "BAD_REQUEST",
"status": 400,
"errorId": "{{correlation_id}}",
"timestamp": "2026-01-15T12:00:00",
"path": "/invoice/send-document-async-json"
}
An IllegalArgumentException is thrown when the apiKey provided does not match any registered company, returning a 400 Bad Request response.
401 - Unauthorized
Trigger: When the JWT token is invalid or expired, or the user is not authorized for the specified company.
Response body:
{
"errorMessage": "Not authorized for this action",
"errorType": "NOT_AUTHORITY",
"errorTitle": "UNAUTHORIZED",
"status": 401,
"errorId": "{{correlation_id}}",
"timestamp": "2026-01-15T12:00:00",
"path": "/invoice/send-document-async-json"
}
An AuthorizationServiceException is thrown when the JWT token in the R-Auth header is invalid/expired or when the authenticated user does not have access to the specified company, returning a 401 Unauthorized response.
500 - Internal Server Error
Trigger: When an unexpected server error occurs.
Response body:
{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"status": 500,
"errorId": "{{correlation_id}}",
"timestamp": "2026-01-15T12:00:00",
"path": "/invoice/send-document-async-json"
}
Returns a 500 Internal Server Error when an unexpected server-side error occurs.
6. Document Status GET
Purpose of Use: The GET /invoice/document-status/{trackingId} endpoint is used to query the processing status of documents (invoices, waybills, etc.) that were submitted asynchronously.
When a document is submitted through any of the send-document-async, send-document-async-json, send-by-file-async, or send-portal-new-async endpoints, the system immediately returns a trackingId and begins processing the document in the background.
Polling stops when the status becomes COMPLETED or FAILED.
Endpoint Information
| Property | Value |
|---|---|
| URL | /invoice/document-status/{trackingId} |
| Method | GET |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/invoice/document-status/{trackingId}' \
--header 'Accept: */*' \
--header 'R-Auth: {JWT_TOKEN}'
}'
Request Parameters
Path Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| trackingId | UUID | Yes | The tracking identifier returned from an asynchronous document submission. This is the trackingId value included in the response of send-document-async, send-document-async-json, send-by-file-async, or send-portal-new-async endpoints. |
Responses
200 - Successful Response
{
"trackingId": "e20a112a-fcb2-4da2-9efd-...",
"companyId": "a1b2c3d4-e5f6-7890-abcd-...",
"direction": "OUTGOING",
"documentType": "FR_UBL_CIUS",
"waybillType": null,
"source": "ERP",
"target": null,
"status": "COMPLETED",
"filename": "invoice_2025.xml",
"invoiceNumber": "INV-2025-001234",
"documentId": "f47ac10b-58cc-4372-a567-...",
"sendingResult": "SUCCESS",
"errorType": null,
"errors": null,
"additionalData": null,
"createdAt": "2025-06-15T10:30:00",
"statusUpdatedAt": "2025-06-15T10:30:45",
"completedAt": "2025-06-15T10:30:45"
}
Success Response Field Descriptions
| Field | Type | Description |
|---|---|---|
| trackingId | UUID | Unique tracking identifier for the document processing |
| companyId | UUID | Unique identifier of the company the document belongs to |
| direction | String (Enum) | Document direction: INCOMING or OUTGOING |
| documentType | String (Enum) | Document format (e.g., XRECHNUNG, UBL, ZUGFERD) |
| waybillType | String (Enum) | Waybill type. Only populated for waybill operations |
| source | String (Enum) | Source platform the document was submitted from (e.g., ERP, PORTAL) |
| target | String (Enum) | null | Target platform for the document |
| status | String (Enum) | Current processing status: PENDING, PROCESSING, COMPLETED, FAILED, SENDING_FAILED, PERMANENT_FAILED |
| filename | String | Name of the processed file |
| invoiceNumber | String | null | Invoice number assigned to the document. Populated when processing completes |
| documentId | UUID | null | Unique system identifier of the created document. Populated when processing completes |
| sendingResult | String | null | Sending result (e.g., SUCCESS, SENT_TO_PEPPOL). Populated when processing completes |
| errorType | String (Enum) | null | Error category when an error occurs. Null for successful operations |
| errors | Object | null | Error details. Variable type: can be List<ValidationError>, List<String>, or String |
| additionalData | Object | Country specific additional metadata. Structure varies by country/document type (e.g., Poland KSeF: ksefNumber, Romania: submissionId) |
| createdAt | DateTime | Timestamp when the processing record was created (ISO 8601) |
| statusUpdatedAt | DateTime | Timestamp when the status was last updated (ISO 8601) |
| completedAt | DateTime | null | Timestamp when processing completed. Null while processing is ongoing |
Parameter Value Reference
DocumentProcessStatus — Possible Status Values
| Value | Description |
|---|---|
| PENDING | Document is queued, processing has not started yet |
| PROCESSING | Document is actively being processed (conversion, validation, sending, etc.) |
| COMPLETED | Document processing completed successfully |
| FAILED | An error occurred during document processing (may be retried) |
| SENDING_FAILED | Document was created but failed during the sending phase |
| PERMANENT_FAILED | Document processing permanently failed (will not be retried) |
DocumentType — Document Direction
| Value | Description |
|---|---|
| INCOMING | Incoming document |
| OUTGOING | Outgoing document |
DataType — Document Format
| Value | Description |
|---|---|
| PEPPOL_BIS | Peppol BIS 3.0 UBL format |
| XRECHNUNG | XRechnung (Germany) UBL format |
| RO_EFACTURA | Romania eFactura format |
| MY_INVOIS | Malaysia MyInvois format |
| MY_PINT | Malaysia PINT format |
| DK_OIOUBL | Denmark OIOUBL format |
| EG_INVOICE | Egypt e-Invoice format |
| HR_INVOICE | Croatia e-Invoice format |
| UAE_PINT | UAE PINT format |
| ZUGFERD | ZUGFeRD format |
| FACTUR_X | Factur-X (France) format |
| XRECHNUNG_CII | XRechnung CII format |
| CII | UN/CEFACT CII format |
| Unstructured PDF (paper invoices, images, etc.) | |
| KSEF | Poland KSeF format |
| KSEF_OFFLINE | Poland KSeF Offline format |
| KZ_ESF_V2 | Kazakhstan ESF v2 format |
InvoiceSource — Document Source
| Value | Description |
|---|---|
| ERP | Submitted via ERP integration |
| PORTAL | Submitted via web portal |
| PEPPOL | Received via Peppol network |
| Received via email | |
| SFTP | Transferred via SFTP |
| KSEF | Via KSeF system |
| ANAF | Via ANAF system (Romania) |
| ERACUN | Via eRacun system (Croatia) |
| Others | PORTAL_OCR, EMAIL_OCR, LHDNM, NEMHANDEL, SERVICE, HARVEST, SHOPIFY, AMAZON_SP, EBAY, HUBSPOT, LAZADA, RS_API, ETA, STRIPE |
WaybillDataType — Waybill Type
| Value | Description |
|---|---|
| RS_WAYBILL_DESPATCH | Serbia despatch waybill |
| RS_WAYBILL_RECEIPT | Serbia receipt waybill |
| RS_APPLICATION_RESPONSE | Serbia application response |
| RO_ETRANSPORT | Romania eTransport waybill |
ErrorType — Error Types Specific to This Endpoint
| Value | Message |
|---|---|
| INVOICE_PROCESS_NOT_FOUND | Tracking ID not found |
| VALIDATION_FAILED | Validation failed! |
| INVOICE_NULL_COULD_NOT_SAVE | Invoice is NULL and/or could not be saved! |
| ZUGFERD_VALIDATION_ERROR | ZUGFeRD validation error |
| INVOICE_CREATION_FAILED | Invoice creation failed! |
| INVOICE_SENDING_FAILED | Invoice sending failed: {details} |
401 - Unauthorized
Returned when the R-Auth header is missing, contains an invalid JWT token, or the token has expired.
{
"status": 401,
"error": "Unauthorized",
"message": "Full authentication is required to access this resource"
}
| Detail | Description |
|---|---|
| HTTP Status | 401 Unauthorized |
| Trigger | JWT token is missing, malformed, expired, or signature verification failed |
| Resolution | Send a valid, non-expired JWT token in the R-Auth header |
404 - Not Found
Returned when the provided trackingId does not exist in the database.
Response Body: null (body is empty)
| Detail | Description |
|---|---|
| HTTP Status | 404 Not Found |
| Response Body | null (body is empty) |
| Trigger | No DocumentProcessEntity record matches the given trackingId in the database |
| Internal Error Type | INVOICE_PROCESS_NOT_FOUND — "Tracking ID not found" |
| Resolution | Verify the trackingId value is correct. Use the value returned in the response of the async submission endpoint |
500 - Internal Server Error
Returned when an unexpected server error occurs during the status query.
Response Body: null (body is empty)
| Detail | Description |
|---|---|
| HTTP Status | 500 Internal Server Error |
| Response Body | null (body is empty) |
| Trigger | Database connection failure, entity conversion error, or other unexpected runtime exceptions |
| Resolution | Check server logs. Contact the support team if the issue persists |
Status-Based Response Examples
PENDING — Queued for Processing
{
"trackingId": "e20a112a-fcb2-4da2-9efd-...",
"companyId": "a1b2c3d4-e5f6-7890-abcd-...",
"direction": null,
"documentType": "XRECHNUNG",
"status": "PENDING",
"documentId": null,
"invoiceNumber": null,
"sendingResult": null,
"errorType": null,
"errors": null,
"createdAt": "2025-06-15T10:30:00",
"statusUpdatedAt": "2025-06-15T10:30:00",
"completedAt": null
}
PROCESSING — Currently Processing
{
"trackingId": "e20a112a-fcb2-4da2-9efd-...",
"companyId": "a1b2c3d4-e5f6-7890-abcd-...",
"direction": "OUTGOING",
"documentType": "XRECHNUNG",
"status": "PROCESSING",
"documentId": "f47ac10b-58cc-4372-a567-...",
"invoiceNumber": "INV-2025-001234",
"sendingResult": null,
"errorType": null,
"errors": null,
"createdAt": "2025-06-15T10:30:00",
"statusUpdatedAt": "2025-06-15T10:30:20",
"completedAt": null
}
FAILED — Processing Failed (Validation Error)
{
"trackingId": "e20a112a-fcb2-4da2-9efd-...",
"companyId": "a1b2c3d4-e5f6-7890-abcd-...",
"direction": null,
"documentType": "ZUGFERD",
"status": "FAILED",
"documentId": null,
"invoiceNumber": null,
"sendingResult": null,
"errorType": "VALIDATION_FAILED",
"errors": [
{
"field": "invoiceNumber",
"message": "Invoice number is required"
},
{
"field": "issueDate",
"message": "Issue date format is invalid"
}
],
"createdAt": "2025-06-15T10:30:00",
"statusUpdatedAt": "2025-06-15T10:30:15",
"completedAt": "2025-06-15T10:30:15"
}
FAILED — Processing Failed (General Error)
{
"trackingId": "e20a112a-fcb2-4da2-9efd-...",
"companyId": "a1b2c3d4-e5f6-7890-abcd-...",
"direction": "OUTGOING",
"documentType": "XRECHNUNG",
"status": "FAILED",
"documentId": null,
"invoiceNumber": null,
"sendingResult": null,
"errorType": "INVOICE_NULL_COULD_NOT_SAVE",
"errors": [
"Invoice is NULL and/or could not be saved! XML parsing error at line 42"
],
"createdAt": "2025-06-15T10:30:00",
"statusUpdatedAt": "2025-06-15T10:30:12",
"completedAt": "2025-06-15T10:30:12"
}
SENDING_FAILED — Sending Failed
{
"trackingId": "e20a112a-fcb2-4da2-9efd-...",
"companyId": "a1b2c3d4-e5f6-7890-abcd-...",
"direction": "OUTGOING",
"documentType": "PEPPOL_BIS",
"status": "SENDING_FAILED",
"documentId": "f47ac10b-58cc-4372-a567-...",
"invoiceNumber": "INV-2025-001234",
"sendingResult": null,
"errorType": "INVOICE_SENDING_FAILED",
"errors": [
"Invoice sending failed: Peppol access point unreachable"
],
"createdAt": "2025-06-15T10:30:00",
"statusUpdatedAt": "2025-06-15T10:31:00",
"completedAt": "2025-06-15T10:31:00"
}
COMPLETED — With Country-Specific Metadata (Poland KSeF)
{
"trackingId": "e20a112a-fcb2-4da2-9efd-...",
"companyId": "a1b2c3d4-e5f6-7890-abcd-...",
"direction": "OUTGOING",
"documentType": "KSEF",
"status": "COMPLETED",
"documentId": "f47ac10b-58cc-4372-a567-...",
"invoiceNumber": "FA/2025/06/001",
"sendingResult": "SUCCESS",
"errorType": null,
"errors": null,
"additionalData": {
"sessionReferenceNumber": "20250615-SE-ABC123",
"invoiceReferenceNumber": "20250615-IR-DEF456",
"ksefNumber": "1234567890-20250615-..."
},
"createdAt": "2025-06-15T10:30:00",
"statusUpdatedAt": "2025-06-15T10:31:30",
"completedAt": "2025-06-15T10:31:30"
}
7. Retrieve Doc by ID and Type GET
Purpose of Use: The GET /invoice/get-document/{documentId}/{documentTypes} endpoint allows downloading a previously stored invoice or document in a specific format such as PDF, XML, or JSON.
The client provides the document UUID (documentId) and the desired output format (documentTypes). The API returns the document content as Base64 encoded data. This is mainly used in ERP integrations to programmatically fetch, view, archive, or store invoice documents.
When the requested format is pdf, the API returns the printable or viewable PDF file content as Base64 encoded data.
Endpoint Information
| Property | Value |
|---|---|
| URL | /invoice/get-document//{documentTypes} |
| Method | GET |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/invoice/get-document/{documentId}/pdf' \
--header 'Accept: */*' \
--header 'R-Auth: {auth-token}'
}'
Request Parameters
Path Parameters
| Field Name | Type | Required | Description |
|---|---|---|---|
| documentId | String (UUID) | Yes | Unique identifier of the document. Must be in UUID v4 format. Example: 550e8400-e29b-41d4-a716-... |
| documentTypes | String (Enum) | Yes | Requested document format type. Multiple types can be separated by hyphen -. Example: PDF, XML |
Header Parameters
| Field Name | Type | Required | Description |
|---|---|---|---|
| R-Auth | String (JWT) | Yes | Authentication token. JWT signed with HS512 algorithm. |
| Accept | String | No | Accepted response media type. Default: / |
documentTypes Parameter Values
| Value | Format Type | Description |
|---|---|---|
| FormatType.PDF | Returns Base64-encoded PDF representation of the invoice | |
| XML | FormatType.XML | Returns Base64-encoded UBL XML content of the invoice |
| JSON | FormatType.JSON | Returns Base64-encoded UBL DTO JSON content of the invoice |
| PDF-XML | Multiple formats | Multiple formats can be requested simultaneously using hyphen separator |
| XML-PDF-JSON | Multiple formats | All three formats can be requested at once |
Note: JSON format is only supported for invoices processed by OCR (OCR_PARSED) or completed by MelAI (COMPLETED_BY_MELAI_AI).
Responses
200 - Successful Response
{
"documents": [
{
"file_type": "PDF",
"data": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PC..."
}
]
}
Successful Response Field Descriptions
| Field Name | Type | Description |
|---|---|---|
| documents | List<Document> | List of documents in requested formats. Contains one Document object per format. |
| documents[].file_type | String (Enum) | Document format type. Possible values: PDF, XML, JSON |
| documents[].data | String (Base64) | Base64-encoded content of the document. When decoded for PDF, produces a valid PDF file. |
Multi-Format Response Example
{
"documents": [
{
"file_type": "XML",
"data": "PD94bWwgdmVy... (base64)"
},
{
"file_type": "PDF",
"data": "JVBERi0xLjQK... (base64)"
}
]
}
400 - Bad Request
Returned when an invalid documentTypes value is provided.
{
"errorMessage": "Unsupported document type: DOCX",
"errorType": "INVALID_ARGUMENT",
"errorTitle": "BAD_REQUEST",
"errorId": "corr-def456",
"status": 400,
"timestamp": "2026-02-11T14:31:00",
"path": "/invoice/get-document/af6e8982-b791-4704-bc06-.../docx"
}
| Field | Description |
|---|---|
| errorMessage | Specifies the unsupported document type and which type was invalid. |
| errorType | INVALID_ARGUMENT An invalid parameter was provided. |
| status | 400 |
400 - Bad Request
Returned when the document's OCR processing has not yet completed (waiting state).
{
"errorMessage": "Invoice is waiting for MelaAIParser. Please try again later",
"errorType": "INVALID_ARGUMENT",
"errorTitle": "BAD_REQUEST",
"errorId": "corr-ghi789",
"status": 400,
"timestamp": "2026-02-11T14:32:00",
"path": "/invoice/get-document/af6e8982-b791-4704-bc06-.../json"
}
| Field | Description |
|---|---|
| errorMessage | Indicates the invoice has not been processed by MelaAI yet and should be retried later. |
| errorType | INVALID_ARGUMENT The invoice is not in a processable state currently. |
| status | 400 |
401 - Unauthorized
Returned when an invalid or missing R-Auth token is provided.
{
"errorMessage": "Authentication is required. Please complete the authentication process.",
"errorType": "AUTHENTICATION_REQUIRED",
"errorTitle": "UNAUTHORIZED",
"errorId": "corr-abc123",
"status": 401,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/get-document/af6e8982-b791-4704-bc06-.../pdf"
}
| Field | Description |
|---|---|
| errorMessage | Indicates that the authentication process must be completed. |
| errorType | AUTHENTICATION_REQUIRED Token is missing, expired, or invalid. |
| status | 401 |
404 - Not Found
Returned when no document matches the provided UUID. Specifically occurs when JSON format is requested and the invoice is not found.
{
"errorMessage": "af6e8982-b791-4704-bc06-d4655faa4b4c Invoice not found!",
"errorType": "NOT_FOUND_INVOICE",
"errorTitle": "NOT_FOUND",
"errorId": "corr-jkl012",
"status": 404,
"timestamp": "2026-02-11T14:33:00",
"path": "/invoice/get-document/af6e8982-b791-4704-bc06-.../json"
}
| Field | Description |
|---|---|
| errorMessage | Returns a not found message along with the document UUID. |
| errorType | NOT_FOUND_INVOICE No matching invoice record exists in the database. |
| status | 404 |
500 - Internal Server Error
Returned when an unexpected error occurs (e.g., file cannot be retrieved from S3, PDF conversion fails).
{
"errorMessage": "Internal server error",
"errorType": "SERVER_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"errorId": "corr-mno345",
"status": 500,
"timestamp": "2026-02-11T14:34:00",
"path": "/invoice/get-document/af6e8982-b791-4704-bc06-.../pdf"
}
| Field | Description |
|---|---|
| errorMessage | Generic server error message. |
| errorType | SERVER_ERROR An unexpected error occurred. |
| status | 500 |
Common Error Response Field Descriptions
| Field Name | Type | Description |
|---|---|---|
| errorMessage | String | Human readable description of the error |
| errorType | String | Programmatic classification code of the error |
| errorTitle | String (HttpStatus) | Text representation of the HTTP status code |
| errorId | String | Request correlation ID (for log tracking) |
| status | Integer | HTTP status code (numeric) |
| timestamp | String (ISO 8601) | Timestamp when the error occurred |
| path | String | Endpoint path where the error occurred |
| details | Map<String, Object> | Additional error details (if available) |
| validationErrors | List<ValidationError> | List of validation errors (if available) |
8. Search Document with Filter POST
Purpose of Use: The POST /invoice/search-documents endpoint is used to search for invoices and documents belonging to a specific company using various filtering criteria.
This API enables users to list documents associated with their company by applying filters such as date range, document direction (incoming or outgoing), invoice status, and document format (ZUGFERD, XRECHNUNG, etc.). Results are returned with pagination support, and each page includes the total document count, tax exclusive total amount, and tax inclusive total amount.
Endpoint Information
| Property | Value |
|---|---|
| URL | /invoice/search-documents |
| Method | POST |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
Example Request
{
curl --location 'https://api-fr-stage.docnova.ai/invoice/search-documents' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: <JWT_TOKEN>' \
--data '{
"companyId": "<COMPANY_UUID>",
"documentType": "OUTGOING",
"endDate": "2026-01-31",
"page": 0,
"size": 10,
"startDate": "2026-01-01",
"status": "SAVED_AS_ZUGFERD",
"type": "ZUGFERD"
}'
}
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| companyId | UUID | Yes | Unique identifier of the company to search documents for |
| documentType | String (Enum) | No | Document direction filter. Used to filter incoming or outgoing documents |
| status | String (Enum) | No | Invoice status filter. Returns invoices in a specific status |
| type | String (Enum) | No | Document format type filter. Filters by invoice format |
| startDate | String (ISO Date) | No | Search start date. Format: YYYY-MM-DD |
| endDate | String (ISO Date) | No | Search end date. Format: YYYY-MM-DD |
| tin | String | No | Tax Identification Number filter |
| uit | String | No | UIT identifier filter |
| referenceDocument | String | No | Search by reference document number |
| page | Integer | No | Page number (0-based). Default: 0 |
| size | Integer | No | Number of records per page. Default: 50 |
Parameter Values
documentType Values
| Value | Description |
|---|---|
| INCOMING | Incoming documents (invoices sent by suppliers) |
| OUTGOING | Outgoing documents (invoices sent to customers) |
type Values
| Value | Group | Description |
|---|---|---|
| MY_INVOIS | MY_INVOIS | Malaysian MyInvois format |
| MY_PINT | MY_PINT | Malaysian PINT format |
| DK_OIOUBL | DK_OIOUBL | Danish OIOUBL format |
| EG_INVOICE | EG_INVOICE | Egyptian e-Invoice format |
| HR_INVOICE | HR_INVOICE | Croatian eRacun format |
| UAE_PINT | UAE_PINT | UAE PINT format |
| ZUGFERD | ZUGFERD | ZUGFeRD format (PDF + embedded XML) |
| FACTUR_X | ZUGFERD | French Factur-X format |
| XRECHNUNG_CII | ZUGFERD | XRechnung CII format |
| CII | ZUGFERD | UN/CEFACT CII format |
| CID | ZUGFERD | CID format |
| ZUGFERD | Unstructured invoices (paper, images, etc.) | |
| KSEF | KSEF | Polish KSeF format |
| KSEF_OFFLINE | KSEF_OFFLINE | Polish KSeF offline format |
| KZ_ESF_V2 | KZ_ESF_V2 | Kazakhstan e-Invoice v2 format |
Note: When using the type filter on the search-documents endpoint, only XRECHNUNG, ZUGFERD, and FACTUR_X values actively filter results. Other values return an empty result set.
status Values
| Category | Value | Description |
|---|---|---|
| General | CREATED | Invoice created |
| PENDING | Awaiting processing | |
| CANCELED | Cancelled | |
| DELETED | Deleted | |
| SENT_VIA_EMAIL | Sent via email | |
| Saved | SAVED_AS_UBL | Saved as UBL |
| SAVED_AS_ZUGFERD | Saved as ZUGFeRD | |
| SAVED_AS_FACTUR_X | Saved as Factur-X | |
| SAVED_AS_CII | Saved as CII | |
| SAVED_AS_CID | Saved as CID | |
| SAVED_AS_KSEF | Saved as KSeF | |
| SAVED_AS_PDF | Saved as PDF | |
| OCR | OCR_WAITING | OCR processing pending |
| OCR_PARSED | OCR completed successfully | |
| OCR_FAILED | OCR processing failed | |
| OCR_PARSED_PENDING_PAYMENT | OCR completed, payment pending | |
| OCR_WAITING_TOKEN | OCR waiting for token | |
| COMPLETED_BY_MELA_AI | Completed by Mela AI | |
| Peppol | SENT_TO_PEPPOL | Sent to Peppol network |
| SENT_TO_ACCESS_POINT | Sent to Access Point | |
| SUCCESS | Successfully delivered | |
| TRANSPORT_ERROR | Transport error | |
| INVALID_PARAMETERS | Invalid parameters | |
| NO_SIGNAL_MESSAGE_RECEIVED | No signal message received | |
| AS4_ERROR_MESSAGE_RECEIVED | AS4 error message received | |
| INVALID_SIGNAL_MESSAGE_RECEIVED | Invalid signal message received | |
| INCOMING_RESPONSE_ACKNOWLEDGED | Incoming response acknowledged (MLR/MLS) | |
| INCOMING_RESPONSE_REJECTED | Incoming response rejected | |
| INCOMING_RESPONSE_ACCEPTED | Incoming response accepted | |
| OUTGOING_RESPONSE_ACKNOWLEDGED | Outgoing response acknowledged (MLR/MLS) | |
| OUTGOING_RESPONSE_REJECTED | Outgoing response rejected | |
| OUTGOING_RESPONSE_ACCEPTED | Outgoing response accepted | |
| Romania (ANAF) | SENT_TO_ANAF | Sent to ANAF |
| PORTAL_OKAY | Portal approved | |
| PORTAL_ERROR | Portal error | |
| PORTAL_ERRORS | Portal multiple errors | |
| PORTAL_SYSTEM_ERROR | Portal system error | |
| PORTAL_IN_PROCESS | Portal processing | |
| Poland (KSeF) | KSEF_PENDING | KSeF processing |
| KSEF_ACCEPTED | KSeF accepted | |
| KSEF_REJECTED | KSeF rejected | |
| KSEF_DUPLICATE | KSeF duplicate record | |
| Malaysia (LHDNM) | LHDNM_SUBMITTED | Submitted to LHDNM |
| LHDNM_VALID | LHDNM valid | |
| LHDNM_INVALID | LHDNM invalid | |
| LHDNM_CANCELLED | LHDNM cancelled | |
| LHDNM_REJECT_REQUESTED | LHDNM rejection requested | |
| LHDNM_REJECTED | LHDNM rejected | |
| LHDNM_ERROR | LHDNM error | |
| Egypt (ETA) | ETA_SUBMITTED | Submitted to ETA |
| Croatia (eRacun) | ERACUN_ERROR | eRacun error |
| ERACUN_PENDING | eRacun pending | |
| ERACUN_WAITING_TO_SEND | eRacun waiting to send | |
| ERACUN_SENT | eRacun sent | |
| ERACUN_RECEIVED | eRacun received | |
| ERACUN_APPROVED | eRacun approved | |
| ERACUN_REJECTED | eRacun rejected | |
| ERACUN_FULLY_PAID | eRacun fully paid | |
| ERACUN_PARTIALLY_PAID | eRacun partially paid | |
| ERACUN_DELIVERY_FAILED | eRacun delivery failed | |
| Denmark | SENT_TO_NEMHANDEL | Sent to Nemhandel |
| Other | CREDIT_BLOCKED | Credit blocked (returns masked data) |
Responses
200 - Successful Response
{
"totalCount": 2,
"netTotal": 1500.00,
"total": 1785.00,
"invoiceList": [
{
{
"id": "a1b2c3d4-e5f6-7890-abcd-...",
"companyId": "60ccd1a7-5348-47b2-9ef6-...",
"userId": "user-uuid",
"customerName": "Muster GmbH",
"supplierName": "Lieferant AG",
"supplierId": "supplier-uuid",
"supplierVat": "DE123456789",
"status": "SAVED_AS_ZUGFERD",
"invoiceNumber": "INV-2026-001",
"taxExclusiveAmount": 750.00,
"taxInclusiveAmount": 892.50,
"lineExtensionAmount": 750.00,
"payableAmount": 892.50,
"allowanceTotalAmount": 0.00,
"currency": "EUR",
"createdTime": "2026-01-15T10:30:00",
"localCreatedTime": "2026-01-15T11:30:00",
"issueDate": "2026-01-15",
"deliveryDate": "2026-01-20",
"dueDate": "2026-02-15",
"supplierCountryCode": "DE",
"supplierEndpoint": "0204:DE123456789",
"customerId": "customer-uuid",
"customerVat": "DE987654321",
"customerEndpoint": "0204:DE987654321",
"customerCountryCode": "DE",
"typeCode": "380",
"documentType": "OUTGOING",
"errorMessage": null,
"lastUpdatedTime": "2026-01-15T10:30:00",
"localLastUpdatedTime": "2026-01-15T11:30:00",
"type": "ZUGFERD",
"source": "PORTAL",
"sendViaPeppol": false,
"statusTime": "2026-01-15T10:30:00",
"localStatusTime": "2026-01-15T11:30:00",
"fileName": "invoice_001.pdf",
"ocrParser": null,
"paymentDetails": null,
"profileType": "EN16931",
"isActive": true,
"countrySpecificData": null
}
]
}
}
Successful Response Field Descriptions
Top-Level Fields
| Field | Type | Description |
|---|---|---|
| totalCount | Long | Total number of documents matching the filters |
| netTotal | Double | Tax-exclusive total amount (excludes CREDIT_BLOCKED) |
| total | Double | Tax-inclusive total amount (excludes CREDIT_BLOCKED) |
| invoiceList | Array<Invoice> | List of invoice objects |
Invoice Object Fields
| Field | Type | Description |
|---|---|---|
| id | String (UUID) | Unique identifier of the invoice |
| companyId | String (UUID) | Company ID the invoice belongs to |
| userId | String (UUID) | User ID who created the invoice |
| customerName | String | Customer (buyer) name |
| supplierName | String | Supplier (seller) name |
| supplierId | String | Supplier ID |
| supplierVat | String | Supplier VAT number |
| status | String (Enum) | Current invoice status |
| invoiceNumber | String | Invoice number |
| taxExclusiveAmount | Double | Tax-exclusive amount |
| taxInclusiveAmount | Double | Tax-inclusive amount |
| lineExtensionAmount | Double | Line items total amount |
| payableAmount | Double | Amount payable |
| allowanceTotalAmount | Double | Total allowance/discount amount |
| currency | String | Currency code (ISO 4217: EUR, USD, TRY, etc.) |
| createdTime | String (DateTime) | Creation timestamp (UTC) |
| localCreatedTime | String (DateTime) | Creation timestamp (local time) |
| issueDate | String (Date) | Invoice issue date |
| deliveryDate | String (Date) | Delivery date |
| dueDate | String (Date) | Due date |
| supplierCountryCode | String | Supplier country code (ISO 3166-1 alpha-2) |
| supplierEndpoint | String | Supplier Peppol endpoint |
| customerId | String | Customer ID |
| customerVat | String | Customer VAT number |
| customerEndpoint | String | Customer Peppol endpoint |
| customerCountryCode | String | Customer country code |
| typeCode | String | Invoice type code (e.g., 380=Invoice, 381=Credit Note) |
| documentType | String (Enum) | Document direction: INCOMING or OUTGOING |
| errorMessage | String | Error message (if any) |
| lastUpdatedTime | String (DateTime) | Last update timestamp (UTC) |
| localLastUpdatedTime | String (DateTime) | Last update timestamp (local time) |
| type | String (Enum) | Document format type (DataType) |
| source | String (Enum) | Invoice source (PORTAL, ERP, PEPPOL, EMAIL, etc.) |
| sendViaPeppol | Boolean | Whether sent via Peppol |
| statusTime | String (DateTime) | Status change timestamp (UTC) |
| localStatusTime | String (DateTime) | Status change timestamp (local time) |
| fileName | String | File name |
| ocrParser | String (Enum) | OCR parser type |
| paymentDetails | Object | Payment details (null for certain statuses) |
| profileType | String (Enum) | ZUGFeRD profile type: BASIC, EN16931, EXTENDED |
| isActive | Boolean | Whether the invoice is active |
| countrySpecificData | Object | Country-specific additional data |
Note: Invoices with CREDIT_BLOCKED status are masked — only id, companyId, documentType, type,invoiceNumber ,supplierName,supplierVat , status and isActive fields are returned; all other fields are null.
400 - Bad Request
Returned when an invalid parameter value is provided (e.g., incorrect enum value, malformed UUID format).
{
"errorMessage": "Invalid value 'INVALID_STATUS' for parameter 'status'",
"errorType": "ILLEGAL_ARGUMENT",
"errorTitle": "BAD_REQUEST",
"errorId": "corr-abc123-def456",
"status": 400,
"timestamp": "2026-01-15T10:30:00",
"path": "/invoice/search-documents"
}
Error Response Fields
| Field | Type | Description |
|---|---|---|
| errorMessage | String | Human-readable error description |
| errorType | String | Error type code |
| errorTitle | String | HTTP status name |
| errorId | String | Correlation ID (for log tracing) |
| status | Integer | HTTP status code |
| timestamp | String (DateTime) | Error occurrence time |
| path | String | Request path |
401 - Unauthorized
Returned when an invalid, expired, or missing JWT token is provided.
{
"errorMessage": "Not authorized for this action",
"errorType": "NOT_AUTHORITY",
"errorTitle": "UNAUTHORIZED",
"errorId": "corr-abc123-def456",
"status": 401,
"timestamp": "2026-01-15T10:30:00",
"path": "/invoice/search-documents"
}
Unauthorized Error Response Fields
| Field | Type | Description |
|---|---|---|
| errorMessage | String | Authorization error description |
| errorType | String | Fixed value: NOT_AUTHORITY |
| errorTitle | String | HTTP status name: UNAUTHORIZED |
| errorId | String | Correlation ID |
| status | Integer | 401 |
| timestamp | String (DateTime) | Error occurrence time |
| path | String | Request path |
500 - Internal Server Error
Returned in case of database connection errors, unexpected runtime exceptions, or other server-side failures.
{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"errorId": "corr-abc123-def456",
"status": 500,
"timestamp": "2026-01-15T10:30:00",
"path": "/invoice/search-documents"
}
Server Error Response Fields
| Field | Type | Description |
|---|---|---|
| errorMessage | String | General error message |
| errorType | String | RUNTIME_ERROR, IO_ERROR, or SERVER_ERROR |
| errorTitle | String | HTTP status name: INTERNAL_SERVER_ERROR |
| errorId | String | Correlation ID (for log tracing) |
| status | Integer | 500 |
| timestamp | String (DateTime) | Error occurrence time |
| path | String | Request path |
9. Merge PDF and XML POST
Purpose of Use: This endpoint is used to merge a PDF invoice document with a ZUGFeRD/Factur-X compliant XML invoice data to create a ZUGFeRD-compliant PDF/A-3 document.
Detailed Description:
- Combines the visual PDF invoice with the structured XML invoice data into a single file intended for the recipient.
- The XML data is embedded into the PDF document as an attachment named factur-x.xml.
- Before merging, the XML data is validated against the ZUGFeRD schema. If validation fails, an error is returned.
- The result is a hybrid e-invoice document that is both human-readable (PDF) and machine-processable (embedded XML).
- This endpoint is specifically designed for producing ZUGFeRD/Factur-X standard-compliant documents used in German (DE) e-invoicing processes.
Endpoint Information
| Property | Value |
|---|---|
| URL | POST /invoice/merge-zugferd-pdf-xml |
| Method | POST |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authentication | R-Auth header (JWT Token) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/invoice/merge-zugferd-pdf-xml' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: <JWT_TOKEN>' \
--data '{
"base64Pdf": "<BASE64_ENCODED_PDF>",
"base64Xml": "<BASE64_ENCODED_XML>"
}'
Request Body Parameters
| Field Name | Type | Required | Description |
|---|---|---|---|
| base64Pdf | String | Yes | Base64-encoded PDF document to be merged. Must contain a valid PDF file. |
| base64Xml | String | Yes | Base64-encoded ZUGFeRD/Factur-X XML invoice data to be merged. Must conform to the ZUGFeRD schema (EN 16931). |
Parameter Value Constraints
| Parameter | Accepted Value | Constraint | Source |
|---|---|---|---|
| base64Pdf | Valid Base64 String | Must be a Base64 encoding of a valid PDF document. Invalid Base64 or corrupted PDF returns an error. | ErpController.java |
| base64Xml | Valid Base64 String | Must be XML conforming to ZUGFeRD EN 16931:2017 schema. Validated by Mustang ZUGFeRDValidator. | ValidationService.java |
| file_type (response) | PDF, XML, SIGN, JSON, GPDF, HTML | This endpoint always returns PDF. | FormatType.java |
Responses
200 - Successful Response
{
"file_type": "PDF",
"data": "<BASE64_ENCODED_MERGED_PDF>"
}
Successful Response Field Descriptions
| Field Name | Type | Description |
|---|---|---|
| file_type | String | Format of the returned file. Always PDF for this endpoint. |
| data | String | Base64-encoded merged ZUGFeRD PDF document. Contains the XML data embedded as factur-x.xml. |
400 - Bad Request
Returned when the base64Pdf or base64Xml is not a valid Base64 string or the decoded data is corrupted.
{
"errorMessage": "Illegal base64 character ...",
"errorType": "API_ERROR",
"errorTitle": "BAD_REQUEST",
"status": 400,
"errorId": "<CORRELATION_ID>",
"timestamp": "2026-02-11T10:30:00",
"path": "/invoice/merge-zugferd-pdf-xml"
}
| Field Name | Type | Description |
|---|---|---|
| errorMessage | String | Detailed description of the error |
| errorType | String | Error classification. API_ERROR in this case |
| errorTitle | String | HTTP status code name: BAD_REQUEST |
| status | Integer | HTTP status code: 400 |
| errorId | String | Request tracking identifier (Correlation ID) |
| timestamp | String (ISO 8601) | Time when the error occurred |
| path | String | Request URL path |
400 - Bad Request
Returned when the XML data does not conform to the schema, along with validation errors.
{
"errorMessage": "Validation failed!",
"errorType": "VALIDATION_FAILED",
"errorTitle": "BAD_REQUEST",
"status": 400,
"errorId": "<CORRELATION_ID>",
"timestamp": "2026-02-11T10:30:00",
"path": "/invoice/merge-zugferd-pdf-xml",
"validationErrors": [
{
"field": "/rsm:CrossIndustryInvoice/rsm:ExchangedDocument/ram:ID",
"code": "BR-02",
"message": "An Invoice shall have an Invoice number."
}
]
}
validationErrors Array Field Descriptions
| Field Name | Type | Description |
|---|---|---|
| field | String | XML XPath location where the error was found |
| code | String | ZUGFeRD/EN 16931 business rule code (e.g., BR-02, BR-CO-15) |
| message | String | Detailed description of the validation error |
400 - Bad Request
Returned when the validation result cannot be parsed.
{
"errorMessage": "JAXBException occurred: ...",
"errorType": "VALIDATION_FAILED",
"errorTitle": "BAD_REQUEST",
"status": 400,
"errorId": "<CORRELATION_ID>",
"timestamp": "2026-02-11T10:30:00",
"path": "/invoice/merge-zugferd-pdf-xml"
}
401 - Unauthorized
Returned when the R-Auth header is missing, the JWT token is expired, or the token is invalid.
{
"errorMessage": "Unauthorized",
"errorType": "UNAUTHORIZED",
"errorTitle": "UNAUTHORIZED",
"status": 401,
"errorId": "<CORRELATION_ID>",
"timestamp": "2026-02-11T10:30:00",
"path": "/invoice/merge-zugferd-pdf-xml"
}
500 - Internal Server Error
Returned when an unexpected error occurs during PDF merging (corrupted PDF structure, memory issues, etc.).
{
"errorMessage": "An unexpected error occurred during PDF merging",
"errorType": "API_ERROR",
"errorTitle": "BAD_REQUEST",
"status": 400,
"errorId": "<CORRELATION_ID>",
"timestamp": "2026-02-11T10:30:00",
"path": "/invoice/merge-zugferd-pdf-xml"
}
Note: The "catch (Exception e)" block in the controller throws all exceptions as ApiError, which defaults to HTTP 400. However, errors caught at the Spring framework level (e.g., JSON parse errors) may return HTTP 500.
10. Generate PDF POST
Purpose of Use: This API endpoint generates a human-readable PDF invoice document from structured XML invoice data (ZUGFeRD, Factur-X, XRechnung, etc.). The submitted Base64-encoded XML data is first transformed into HTML via XSLT templates, then converted into a professionally formatted PDF file using the iText 7 library. For ZUGFeRD/Factur-X/CII formats, the original XML data is embedded within the PDF file (PDF/A-3 compliant), creating a hybrid invoice. Optionally, the country and vatNumber fields can be used to match company records, enabling company logo placement and country-specific language settings on the PDF. It is specifically designed for invoice visualization, printing, and archiving processes in ERP integrations (SAP, etc.).
Endpoint Information
| Property | Value |
|---|---|
| URL | /invoice/generate/pdf |
| Method | POST |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authentication | R-Auth header (JWT Bearer Token) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/invoice/generate/pdf' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJNTU0iLCJzdWIiOiJwNjR9.IpGPX...' \
--data '{
"base64XML": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KC...",
"country": "DE",
"type": "ZUGFERD",
"vatNumber": "DE777111222"
}
Request Parameters
| Field Name | Type | Required | Description |
|---|---|---|---|
| base64XML | String | Yes | Base64-encoded invoice XML data. Must be a valid XML in UBL 2.1, CrossIndustryInvoice (CII), or the relevant country-specific format. |
| type | Enum (DataType) | Yes | Invoice format type. Specifies the standard of the provided XML. Valid values are listed in the table below. |
| country | Enum (Country) | No | Country code of the invoice (ISO 3166-1 alpha-2). When used together with vatNumber, company matching is performed to add logo and language settings to the PDF. |
| vatNumber | String | No | VAT number of the invoicing company. When used together with country, it matches against the company record in the system. |
Valid Values for type Parameter
UBL-Based Formats
| Value | Description | XSLT Group |
|---|---|---|
| XRECHNUNG | German XRechnung standard (EN 16931 compliant) | XRECHNUNG |
| PEPPOL_BIS | PEPPOL BIS 3.0 standard | XRECHNUNG |
| RO_EFACTURA | Romania e-Factura format | XRECHNUNG |
| MY_INVOIS | Malaysia MyInvois format | MY_INVOIS |
| MY_PINT | Malaysia PINT format | MY_PINT |
| DK_OIOUBL | Denmark OIOUBL format | DK_OIOUBL |
| EG_INVOICE | Egypt invoice format | EG_INVOICE |
| HR_INVOICE | Croatia invoice format | HR_INVOICE |
| UAE_PINT | UAE PINT format | UAE_PINT |
CII / ZUGFeRD-Based Formats
| Value | Description | XSLT Group |
|---|---|---|
| ZUGFERD | ZUGFeRD 2.x format (XML-embedded PDF) | ZUGFERD |
| FACTUR_X | French Factur-X format | ZUGFERD |
| XRECHNUNG_CII | XRechnung CII format | ZUGFERD |
| CII | UN/CEFACT CrossIndustryInvoice | ZUGFERD |
| CID | CrossIndustryDocument format | ZUGFERD |
| Unstructured invoice (paper invoices, images, etc.) | ZUGFERD |
Other Formats
| Value | Description | XSLT Group |
|---|---|---|
| KZ_ESF_V2 | Kazakhstan ESF v2 format | KZ_ESF_V2 |
| KSEF | Poland KSeF format | KSEF |
| KSEF_OFFLINE | Poland KSeF offline format | KSEF_OFFLINE |
country Parameter
| Country Code | Country | PDF Language |
|---|---|---|
| DE | Germany | German (DE) |
| AT | Austria | German (DE) |
| FR | France | French (FR) |
| IT | Italy | Italian (IT) |
| NL | Netherlands | Dutch (NL) |
| RO | Romania | Romanian (RO) |
| ES | Spain | Spanish (ES) |
| TR | Turkey | Turkish (TR) |
| KZ | Kazakhstan | Kazakh (KK) |
| MY | Malaysia | Malay (MS) |
| BN | Brunei | Malay (MS) |
| All others | — | English (EN) |
Responses
200 - Successful Response
| Property | Value |
|---|---|
| HTTP Status | 200 |
| Content-Type | application/octet-stream |
| Body | Binary PDF data (byte array) |
%PDF-1.7
%����
1 0 obj
<<
/Pages 2 0 R
/Type /Catalog
/Names 21 0 R
/Metadata 27 0 R
>>
endobj
5 0 obj
<<
400 - Bad Request
Trigger Condition: When the XML data is invalid, Base64 cannot be decoded, XSLT transformation fails, or any error occurs during iText PDF generation.
{
"errorMessage": "PDF convert error: [detail message]",
"errorType": "PDF_CONVERT_ERROR",
"errorTitle": "BAD_REQUEST",
"errorId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/generate/pdf"
}
Possible Detail Messages:
- PDF convert error: PDF conversion failed due to an unexpected error — XSLT template not found or unexpected error during HTML-to-PDF conversion
- PDF convert error: Illegal base64 character — The base64XML field is not in valid Base64 format
- PDF convert error: [XSLT transformation error]` — XML structure does not match the expected format
400 - Bad Request — Invalid Parameter
Trigger Condition: When an invalid enum value is sent for the type field or required fields are missing.
{
"errorMessage": "Invalid argument! Argument: type",
"errorType": "INVALID_ARGUMENT",
"errorTitle": "BAD_REQUEST",
"errorId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/generate/pdf"
}
400 - Bad Request — Invalid PDF Type
Trigger Condition: When the submitted type value is an unsupported format for PDF conversion.
{
"errorMessage": "Invalid PDF type",
"errorType": "INVALID_PDF_TYPE",
"errorTitle": "BAD_REQUEST",
"errorId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/generate/pdf"
}
400 - Bad Request — Empty XML Data
Trigger Condition: When the base64XML field is sent as null or empty.
{
"errorMessage": "Data XML cannot be NULL!",
"errorType": "NULL_DATA_XML",
"errorTitle": "BAD_REQUEST",
"errorId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/generate/pdf"
}
401 - Unauthorized
Trigger Condition: When the R-Auth header is missing, the JWT token has expired, or an invalid token is provided.
{
"errorMessage": "Not authorized for this action",
"errorType": "NOT_AUTHORITY",
"errorTitle": "UNAUTHORIZED",
"errorId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": 401,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/generate/pdf"
}
500 - Internal Server Error
Trigger Condition: When an unexpected server error occurs (XSLT file cannot be loaded, insufficient memory, etc.).
{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"errorId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": 500,
"timestamp": "2026-02-11T14:30:00",
"path": "/invoice/generate/pdf"
}
Error Codes and Response Details
The following errors are specific to this endpoint. All error responses follow the ExceptionResponse format:
Error Response Structure
| Field Name | Type | Description |
|---|---|---|
| errorMessage | String | Detailed description of the error |
| errorType | String | Error type identifier |
| errorTitle | String | HTTP status name (BAD_REQUEST, INTERNAL_SERVER_ERROR, etc.) |
| errorId | String | Correlation ID (for log tracing) |
| status | Integer | HTTP status code (400, 500, etc.) |
| timestamp | String (ISO 8601) | Time when the error occurred |
| path | String | Requested URL path |
11. Send Invoice via E-mail POST
Purpose of Use This API endpoint enables sending invoices to recipients via email. Users can select one or more invoices and send them in the desired format (PDF, XML, etc.) to specified email addresses. Invoice files are automatically converted to the requested format and attached to the email. Before sending, the user’s authorization is verified; only users with ADMIN or OUTGOING_INVOICE_SEND_EMAIL authority can perform this operation. Email delivery is first attempted via AWS SES; if that fails, an SMTP fallback mechanism is activated. Upon successful delivery, the invoice status is updated to SENT_VIA_EMAIL and the action is logged in the invoice history.
Endpoint Information
| Property | Value |
|---|---|
| URL | /email/send |
| Method | POST |
| Content-Type | multipart/form-data |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authentication | R-Auth header (JWT token) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/email/send' \
--header 'Content-Type: multipart/form-data' \
--header 'Accept: */*' \
--header 'R-Auth: <JWT_TOKEN>' \
--form 'invoiceIdList="<INVOICE_UUID>"' \
--form 'companyId="<COMPANY_UUID>"' \
--form 'body="Your Invoice is attached."' \
--form 'subject="2026_006"' \
--form 'formatTypes="PDF"' \
--form 'toList="recipient@example.com"'
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| invoiceIdList | List<UUID> | Yes | List of invoice IDs to be sent. Multiple invoices can be included. |
| companyId | UUID | Yes | The company ID that the invoices belong to. |
| formatTypes | List<FormatType> | Yes | Format(s) in which invoice attachments will be generated. Multiple formats can be specified. |
| toList | List<String> | No | List of recipient email addresses. |
| ccList | List<String> | No | List of CC (Carbon Copy) recipient email addresses. |
| bccList | List<String> | No | List of BCC (Blind Carbon Copy) recipient email addresses. |
| subject | String | No | Email subject line. If omitted, a template or default subject is used. |
| body | String | No | Email body text. If omitted, a template or default content is used. |
| attachments | List<MultipartFile> | No | Additional file attachments (beyond the auto-generated invoice files). |
FormatType Values
| Value | Description |
|---|---|
| Invoice attached in PDF format | |
| XML | Invoice attached in XML (UBL/CII) format |
| SIGN | Signed invoice file attached |
| JSON | Invoice attached in JSON format |
| GPDF | Invoice attached in graphic PDF format |
| HTML | Invoice attached in HTML format |
Attachment Constraints
| Constraint | Value |
|---|---|
| Maximum file count | 3 |
| Maximum file size (per file) | 5 MB |
| Allowed content types | application/pdf, application/xml, text/xml, image/png, image/jpg, image/jpeg, message/rfc822, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
Responses
200 - Successful Response
| Field | Type | Value | Description |
|---|---|---|---|
| HTTP Status | Integer | 200 | Operation successful |
| Body | Boolean | true | Email sent successfully |
true
400 - Bad Request
Condition: invoiceIdList field is empty or not provided.
{
"errorMessage": "Validation failed",
"errorType": "VALIDATION_ERROR",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/email/send",
"validationErrors": [
{
"field": "invoiceIdList",
"message": "must not be empty"
}
]
}
400 - Bad Request — Validation Error (companyId null)
Condition: companyId field is not provided.
{
"errorMessage": "Validation failed",
"errorType": "VALIDATION_ERROR",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/email/send",
"validationErrors": [
{
"field": "companyId",
"message": "must not be null"
}
]
}
400 - Bad Request — Validation Error (formatTypes empty)
Condition: formatTypes field is empty or not provided.
{
"errorMessage": "Validation failed",
"errorType": "VALIDATION_ERROR",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/email/send",
"validationErrors": [
{
"field": "formatTypes",
"message": "must not be empty"
}
]
}
400 - Bad Request — Invoice Not Found
Condition: No invoice found matching the provided invoiceIdList and companyId combination.
{
"errorMessage": "Invoices not found with id list [d2fc7bb5-4ffe-44ab-b9e9-92a833df65ec]",
"errorType": "INVALID_ARGUMENT",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/email/send"
}
400 - Bad Request — Invoice Attachment Generation Failed
Condition: Invoice file could not be generated in the requested format (e.g., file not found in S3).
{
"errorMessage": "Attachments not found with invoice id list [d2fc7bb5-4ffe-44ab-b9e9-92a833df65ec]",
"errorType": "INVALID_ARGUMENT",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/email/send"
}
400 - Bad Request — Attachment Count Exceeded
Condition: More than 3 additional files were uploaded.
{
"errorMessage": "Maximum 3 files are allowed, found 5",
"errorType": "EMAIL_ATTACHMENT_COUNT_EXCEED",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/email/send"
}
400 - Bad Request — Attachment File Size Exceeded
Condition: An attachment exceeds the 5 MB limit.
{
"errorMessage": "Maximum 5MB file size is allowed, report.pdf file size is 8MB",
"errorType": "EMAIL_ATTACHMENT_FILE_SIZE_EXCEED",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/email/send"
}
400 - Bad Request — Attachment Content Type Not Allowed
Condition: The uploaded file's content type is not in the allowed list.
{
"errorMessage": "Allowed content types are [application/pdf, application/xml, text/xml, image/png, image/jpg, image/jpeg, message/rfc822, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet], malware.exe file content type is application/octet-stream",
"errorType": "EMAIL_ATTACHMENT_CONTENT_TYPE_NOT_ALLOWED",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/email/send"
}
400 - Bad Request — Email Sending Failed
Condition: Email could not be sent via both AWS SES and SMTP.
{
"errorMessage": "Failed to send email: Connection refused",
"errorType": "EMAIL_SENDING_FAILED",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-02-11T14:30:00",
"path": "/email/send"
}
401 - Unauthorized
Condition: Invalid or expired JWT token provided in the R-Auth header.
{
"errorMessage": "Unauthorized",
"errorType": "UNAUTHORIZED",
"errorTitle": "UNAUTHORIZED",
"status": 401,
"timestamp": "2026-02-11T14:30:00",
"path": "/email/send"
}
403 - Forbidden
Condition: The user does not have ADMIN or OUTGOING_INVOICE_SEND_EMAIL authority.
{
"errorMessage": "Access denied",
"errorType": "FORBIDDEN",
"errorTitle": "FORBIDDEN",
"status": 403,
"timestamp": "2026-02-11T14:30:00",
"path": "/email/send"
}
12. Peppol - Get MLR GET
Purpose of Use This endpoint is used to query Message Level Response (MLR) records for invoices sent or received through the Peppol network.
MLR is a message level response mechanism in the Peppol infrastructure that indicates whether a document was successfully delivered, accepted, or rejected by the receiving party.
With this API you can:
- List all MLR responses belonging to a specific company
- Query MLR status for a specific invoice (invoiceId) or document (documentId)
- Filter by the counterpart’s Peppol participant identifier (counterpartParticipantId)
- Perform time based searches by specifying a date range (fromDate, toDate)
- Returned responses include detail lines for each MLR record (error field, status reason, description)
This enables developers to programmatically track the final status of the invoice delivery process and take necessary actions in case of errors.
Endpoint Information
| Property | Value |
|---|---|
| URL | /peppol/search-mlr |
| Method | GET |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
Example Request
{
curl --location 'https://api-fr-stage.docnova.ai/peppol/search-mlr?companyId={companyId}&counterpartParticipantId={counterpartParticipantId}&documentId={documentId}&fromDate={fromDate}&invoiceId={invoiceId}&toDate={toDate}' \
--header 'Accept: */*' \
--header 'R-Auth: {jwt_token}'
}
Request Parameters
| Field | Type | Required | Format | Description |
|---|---|---|---|---|
| companyId | String (UUID) | Yes | xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | Unique identifier of the company to query |
| documentId | String (UUID) | No | xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | Peppol document identifier (instance identifier) |
| counterpartParticipantId | String | No | {scheme}:{identifier} (e.g., 9930:de111222777) | Counterpart’s Peppol participant identifier |
| invoiceId | String | No | Free text | Invoice number or identifier |
| fromDate | String (ISO Date) | No | yyyy-MM-dd (e.g., 2025-09-09) | Search start date (inclusive) |
| toDate | String (ISO Date) | No | yyyy-MM-dd (e.g., 2026-09-09) | Search end date (inclusive) |
Request Headers
| Header | Type | Required | Description |
|---|---|---|---|
| R-Auth | String (JWT) | Yes | User authentication token. JWT signed with HS512 algorithm |
| Accept | String | No | Default /. Response is returned as application/json |
Parameter Values
counterpartParticipantId Format
| Scheme | Description | Example |
|---|---|---|
| 9930 | Germany VAT number | 9930:de111222777 |
| 0204 | Leitweg-ID | 0204:1234567890123 |
| 0088 | EAN location code | 0088:1234567890123 |
responseType Response Type Enum Values
| Value | Description |
|---|---|
| ACCEPTANCE | Document was accepted by the counterpart |
| ACKNOWLEDGING | Document was acknowledged (received) by the counterpart |
| REJECTION | Document was rejected by the counterpart |
statusReasonCode Status Reason Code Enum Values
| Value | Description |
|---|---|
| BUSINESS_RULE_VIOLATION_FATAL | Business rule violation. Critical error. Document was not processed |
| BUSINESS_RULE_VIOLATION_WARNING | Business rule violation. Warning. Document can still be processed |
| SYNTAX_VIOLATION | Syntax error. Document format is invalid |
Responses
200 - Successful Response
Type: List<SearchMLRResponse>
{
[
{
"id": "a1b2c3d4-e5f6-7890-abcd-...",
"companyId": "60ccd1a7-5348-47b2-9ef6-...",
"documentId": "8fa4606f-94f2-45e1-a8cb-...",
"responseType": "ACCEPTANCE",
"receivedTime": "2026-01-15T14:30:00",
"counterpartParticipantId": "9930:de111222777",
"invoiceId": "2026_007_peppol",
"responseLines": [
{
"id": "f1e2d3c4-b5a6-7890-abcd-...",
"errorField": null,
"responseCode": "ACCEPTANCE",
"description": "Document successfully processed",
"statusReasonCode": null
}
]
}
]
}
Response Fields
| Field | Type | Description |
|---|---|---|
| id | UUID | Unique identifier of the MLR record |
| companyId | String | Identifier of the related company |
| documentId | String | Peppol document identifier |
| responseType | Enum (MessageLevelResponseType) | Overall response type: ACCEPTANCE, ACKNOWLEDGING, REJECTION |
| receivedTime | DateTime (ISO 8601) | Date and time the MLR response was received |
| counterpartParticipantId | String | Counterpart’s Peppol participant identifier |
| invoiceId | String | Related invoice number |
| responseLines | List<SearchMLRLineResponse> | MLR detail lines |
Response Detail Lines
| Field | Type | Description |
|---|---|---|
| id | UUID | Unique identifier of the detail line |
| errorField | String (nullable) | The field / XPath expression where the error occurred |
| responseCode | Enum (MessageLevelResponseType) | Line level response code: ACCEPTANCE, ACKNOWLEDGING, REJECTION |
| description | String (nullable) | Error or status description |
| statusReasonCode | Enum (MLRStatusReasonCode) (nullable) | Status reason code: BUSINESS_RULE_VIOLATION_FATAL, BUSINESS_RULE_VIOLATION_WARNING, SYNTAX_VIOLATION |
400 - Bad Request
Occurs when the required companyId parameter is missing or when the date format is invalid.
{
"errorMessage": "Required request parameter 'companyId' for method parameter type String is not present",
"errorType": "BAD_REQUEST",
"errorTitle": "BAD_REQUEST",
"status": 400,
"errorId": "corr-xxx-xxx",
"timestamp": "2026-01-15T14:30:00",
"path": "/peppol/search-mlr"
}
Description: The companyId parameter is mandatory and Spring framework automatically returns this error when it is missing. Additionally, if fromDate or toDate parameters do not conform to the yyyy-MM-dd ISO format, the same error code is returned.
401 - Unauthorized
Occurs when the JWT token is invalid, expired, or the R-Auth header is missing. Also returned when the user is not associated with the specified companyId.
{
"errorMessage": "Not authorized for this action",
"errorType": "NOT_AUTHORITY",
"errorTitle": "UNAUTHORIZED",
"status": 401,
"errorId": "corr-xxx-xxx",
"timestamp": "2026-01-15T14:30:00",
"path": "/peppol/search-mlr"
}
Description: The authorizationService.checkIfCompanyUser(companyId, userId) method verifies that the user identity in the JWT token matches the specified companyId. If they do not match, an AuthorizationServiceException is thrown. This error is also returned when the token is expired or its signature is invalid.
500 - Internal Server Error
Returned in case of database access errors, unexpected runtime exceptions, or other server-side failures.
{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"status": 500,
"errorId": "corr-xxx-xxx",
"timestamp": "2026-01-15T14:30:00",
"path": "/peppol/search-mlr"
}
Description: Returned in case of database connection errors, JPA/Hibernate query failures, or unexpected internal server errors. The errorId (correlation id) field can be used to trace detailed error information from log records.
Error Response General Format
| Field | Type | Description |
|---|---|---|
| errorMessage | String | Human readable description of the error |
| errorType | String | Error classification code (e.g., NOT_AUTHORITY, RUNTIME_ERROR) |
| errorTitle | String (HttpStatus) | HTTP status code name (e.g., BAD_REQUEST, UNAUTHORIZED, INTERNAL_SERVER_ERROR) |
| status | Integer | HTTP status code numeric value (e.g., 400, 401, 500) |
| errorId | String (nullable) | Correlation ID used for log tracing |
| data | String (nullable) | Additional data (if available) |
| details | Map<String, Object> (nullable) | Detailed error information (if available) |
| validationErrors | List<ValidationError> (nullable) | Field level validation errors (if available) |
| timestamp | DateTime (ISO 8601) | Time when the error occurred |
| path | String | Endpoint path where the error occurred |
13. Peppol - Send MLR POST
Purpose of Use The POST /peppol/send-mlr endpoint is used to send a Message Level Response (MLR) within the Peppol infrastructure.
An MLR is the official response given by the receiving party to an e-invoice received through Peppol. This response communicates to the sender whether the invoice was successfully received and accepted, is being processed (acknowledged), or has been rejected. The receiver can inform the sender in detail by specifying errors in the invoice (IBAN error, syntax error, business rule violation, etc.).
After the MLR is sent, the related invoice status is automatically updated.
Endpoint Information
| Property | Value |
|---|---|
| URL | /peppol/send-mlr |
| Method | POST |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authentication | R-Auth header (JWT token) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/peppol/send-mlr' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: <JWT_TOKEN>' \
--data '{
"errorLines": [
{
"description": "The IBAN number provided in the payment instructions is invalid or missing",
"errorField": "PaymentMeans/PayeeFinancialAccount/ID",
"responseCode": "ACKNOWLEDGING",
"statusReasonCode": "BUSINESS_RULE_VIOLATION_WARNING"
}
],
"invoiceId": "<INVOICE_UUID>",
"responseCode": "ACCEPTANCE"
}'
Request Parameters
Root Level Parameters
| Field Name | Type | Required | Description |
|---|---|---|---|
| invoiceId | String (UUID) | Yes | Unique identifier of the invoice to send the MLR for (UUID format) |
| responseCode | Enum (MessageLevelResponseType) | Yes | Overall response code for the invoice |
| errorLines | Array<MLRErrorLine> | No | List of error details in the invoice. Can be left empty |
errorLines Array Element
| Field Name | Type | Required | Description |
|---|---|---|---|
| description | String | No | Human readable description of the error |
| errorField | String | No | UBL/XML field path where the error was detected (XPath-like) |
| responseCode | Enum (MessageLevelResponseType) | No | Response code specific to this error line |
| statusReasonCode | Enum (MLRStatusReasonCode) | No | Classification code of the error |
Allowed Parameter Values
MessageLevelResponseType (responseCode)
| Value | Description |
|---|---|
| ACCEPTANCE | Invoice accepted. It has been processed and approved |
| ACKNOWLEDGING | Invoice received. Receipt is confirmed but not yet fully processed |
| REJECTION | Invoice rejected. Not processed due to errors |
MLRStatusReasonCode (statusReasonCode)
| Value | Description |
|---|---|
| BUSINESS_RULE_VIOLATION_FATAL | Fatal business rule violation. A critical error that prevents the invoice from being processed |
| BUSINESS_RULE_VIOLATION_WARNING | Warning level business rule violation. The invoice can be processed but correction is recommended |
| SYNTAX_VIOLATION | Syntax error. Format or schema incompatibility in the XML/UBL structure |
Responses
200 - Successful Response
| Field | Type | Value | Description |
|---|---|---|---|
| HTTP Status | Integer | 200 | Operation successful |
| Body | String | "MLR sent successfully" | Response text returned from the Access Point service |
"MLR sent successfully"
400 - Bad Request
Trigger Condition: When an error occurs while forwarding the MLR to the Access Point service (connection error, timeout, Access Point rejection).
{
"errorMessage": "Failed to send MLR: <detailed error message>",
"errorType": "API_ERROR",
"errorTitle": "BAD_REQUEST",
"errorId": "<correlation-id>",
"status": 400,
"timestamp": "2026-02-12T14:30:00",
"path": "/peppol/send-mlr"
}
Description: The MLR was saved to the database but could not be forwarded to the Access Point. The error message contains the detail returned from the Access Point. Check your network connectivity and Access Point service availability.
400 - Bad Request — Invalid responseCode
Trigger Condition: When the responseCode field contains an invalid enum value (i.e., a value other than ACCEPTANCE, ACKNOWLEDGING, REJECTION).
{
"errorMessage": "Unknown response code: <invalid_value>",
"errorType": "API_ERROR",
"errorTitle": "BAD_REQUEST",
"errorId": "<correlation-id>",
"status": 400,
"timestamp": "2026-02-12T14:30:00",
"path": "/peppol/send-mlr"
}
Description: The responseCode field only accepts ACCEPTANCE, ACKNOWLEDGING, or REJECTION values. Verify the value you are sending.
400 - Bad Request — Invalid UUID Format
Trigger Condition: When the invoiceId field is not in a valid UUID format.
{
"errorMessage": "Invalid UUID string: <invalid_value>",
"errorType": "API_ERROR",
"errorTitle": "BAD_REQUEST",
"errorId": "<correlation-id>",
"status": 400,
"timestamp": "2026-02-12T14:30:00",
"path": "/peppol/send-mlr"
}
Description: : The invoiceId value must be a valid UUID in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
401 - Unauthorized
Trigger Condition: When the R-Auth header is missing, invalid, or contains an expired JWT token.
{
"errorMessage": "Not authorized for this action",
"errorType": "NOT_AUTHORITY",
"errorTitle": "UNAUTHORIZED",
"errorId": "<correlation-id>",
"status": 401,
"timestamp": "2026-02-12T14:30:00",
"path": "/peppol/send-mlr"
}
Description: The JWT token has expired or is malformed. Obtain a new token and retry.
404 - Not Found
Trigger Condition: When no invoice matching the provided invoiceId is found in the database.
{
"errorMessage": "<invoiceId> Invoice not found",
"errorType": "NOT_FOUND_INVOICE",
"errorTitle": "NOT_FOUND",
"errorId": "<correlation-id>",
"status": 404,
"timestamp": "2026-02-12T14:30:00",
"path": "/peppol/send-mlr"
}
Description: The invoiceId parameter contains an invalid or unregistered UUID in the database. Ensure the invoice ID is correct.
500 - Internal Server Error
Trigger Condition: When a database error, network error, or unexpected exception occurs.
{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"errorId": "<correlation-id>",
"status": 500,
"timestamp": "2026-02-12T14:30:00",
"path": "/peppol/send-mlr"
}
Description: An unexpected error occurred on the server side. Forward the errorId (correlation ID) value to the support team for detailed investigation.
Error Response Model (ExceptionResponse)
| Field Name | Type | Description |
|---|---|---|
| errorMessage | String | Detailed description of the error |
| errorType | String | Error classification code (e.g., NOT_FOUND_INVOICE, API_ERROR) |
| errorTitle | String (HttpStatus) | HTTP status name (e.g., NOT_FOUND, BAD_REQUEST) |
| errorId | String | Correlation identifier (for log tracing) |
| status | Integer | HTTP status code (e.g., 400, 404, 500) |
| data | String | Additional data (if available) |
| details | Map<String, Object> | Additional detail information (if available) |
| validationErrors | Array<ValidationError> | Validation error list (if available) |
| timestamp | String (ISO 8601) | Timestamp of when the error occurred |
| path | String | Endpoint path of the request |
14. Search SIREN number GET
Purpose of Use This endpoint queries the PPF (Plateforme Publique de Facturation) — France's official public e-invoicing platform — to retrieve basic directory information about a French legal entity using its 9-digit SIREN number from the Annuaire (Directory) system.
SIREN (Système d'Identification du Répertoire des Entreprises) is the unique 9-digit identifier assigned to French companies by INSEE. Through this endpoint, callers can retrieve the company's legal name, entity type (public/private), administrative status, and directory record details in a single request.
Typical use cases:
- Verifying that a SIREN is registered and active in the PPF Annuaire before sending an e-invoice to a French recipient
- Determining whether a company belongs to the public or private sector in order to select the correct e-invoicing channel
- Checking the diffusible (publishable) status of a legal entity during the onboarding flow
- Retrieving the company's PPF instance ID for use in subsequent directory queries
Endpoint Information
| Property | Value |
|---|---|
| URL | /annuaire/FR/siren/{siren} |
| Method | GET |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/annuaire/FR/siren/123456789' \
--header 'Accept: application/json' \
--header 'R-Auth: <JWT_TOKEN>'
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| siren | String | Yes | The 9-digit French SIREN number for the target legal entity |
Path Parameter Values
| Field | Rule | Valid Example | Invalid Example |
|---|---|---|---|
| siren | Exactly 9 digits; leading zeros are preserved | 271688503 | 271-685, 27168850, ABCDEFGHI, 2716885030 |
Responses
200 - Successful Response
{
"siren": "271688503",
"raisonSociale": "SIREN_271688503",
"typeEntite": "Privée assujettie",
"etatAdministratif": "A",
"diffusible": "O",
"historisation": {
"idInstance": 1003843,
"dateDebutEffet": null,
"dateDefinition": null,
"creePar": null,
"masque": null
}
}
400 - Bad Request
Returned when the SIREN parameter does not consist of exactly 9 digits.
{
"error": "VALIDATION_ERROR",
"message": "SIREN must be exactly 9 digits for French companies",
"code": "FR_SIREN_INVALID"
}
Description: The client has sent a value with fewer or more than 9 digits, or a non-numeric character. The SIREN format is validated against the regex pattern ^\d{9}$.
401 - Unauthorized
Returned when the JWT token in the R-Auth header cannot be verified.
{
"error": "UNAUTHORIZED",
"message": "Invalid or expired authentication token",
"code": "AUTH_TOKEN_INVALID"
}
Description: The token has expired, its signature is invalid, or the header is missing. The system internally attempts to obtain a new token; if that also fails, this error is propagated to the client. Token TTL is 50 minutes.
403 - Forbidden
Returned when the authenticated user does not have access rights to the requested SIREN record.
{
"error": "FORBIDDEN",
"message": "Access denied to this resource",
"code": "ACCESS_DENIED"
}
Description: Authentication succeeds, but the authorization layer rejects the request. This may result from PPF Annuaire access policies or user role restrictions.
404 - Not Found
Returned when the provided SIREN number is not registered in the PPF Annuaire.
{
"error": "NOT_FOUND",
"message": "No entity found for SIREN: 271688503",
"code": "COMPANY_NOT_FOUND"
}
Description: Even though the SIREN format is valid, no matching record exists in France's official directory. The company may not yet have registered with PPF, or the record may have been removed.
422 - Unprocessable Entity
Returned when the request is technically valid but cannot be processed due to business logic constraints.
{
"error": "UNPROCESSABLE_ENTITY",
"message": "PPF Annuaire registration failed. Please verify your company information and try again.",
"code": "FR_PPF_ONBOARD_FAILED"
}
Description: Typically triggered by data inconsistencies in the PPF system for the queried SIREN, or when the company is not marked as publishable (diffusible).
500 - Internal Server Error
Returned when an unexpected error occurs while communicating with the upstream PPF Annuaire service.
{
"error": "INTERNAL_SERVER_ERROR",
"message": "An unexpected error occurred while contacting PPF Annuaire",
"code": "GENERAL_ERROR"
}
Description: May be triggered by the upstream PPF API being unreachable, a timeout (default 15,000 ms), or an unexpected response format from the PPF Annuaire service.
15. Search SIRET number GET
Purpose of Use This endpoint queries the PPF (Plateforme Publique de Facturation) Annuaire to retrieve detailed information about a specific French business establishment using its 14-digit SIRET number.
SIRET (Système d'Identification du Répertoire des Établissements) is a unique 14-digit code that identifies a specific establishment (branch, headquarters, factory, etc.) of a French company. The first 9 digits are the company's SIREN number; the last 5 digits are the NIC (Numéro Interne de Classement) code that distinguishes the specific establishment.
Typical use cases:
- Verifying that a SIRET is registered and active in the PPF Annuaire before sending an e-invoice to a French establishment
- Retrieving the branch address (postal code, city, country) and establishment-level invoicing parameters
- Determining whether the establishment is publishable (diffusible) and its administrative status
- Obtaining the
idInstancevalue to use in onboarding or routing flows
Endpoint Information
| Property | Value |
|---|---|
| URL | /annuaire/FR/siret/{siret} |
| Method | GET |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/annuaire/FR/siret/27168850399286' \
--header 'Accept: application/json' \
--header 'R-Auth: <JWT_TOKEN>'
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| siret | String | Yes | The 14-digit French SIRET number for the target establishment |
Path Parameter Values
| Field | Rule | Valid Example | Invalid Example |
|---|---|---|---|
| siret | Exactly 14 digits; leading zeros are preserved. The first 9 digits must match the parent company's SIREN. | 27168850399286, 00000000000001 | 2716885039928 (13 digits), 271688503992860 (15 digits), 2716-8850-3992-86, ABCDEFGHIJKLMN |
Responses
200 - Successful Response
{
"siret": "27168850399286",
"siren": "271688503",
"denomination": "Valideur 27168850399286",
"typeEtablissement": "S",
"diffusible": "O",
"etatAdministratif": "A",
"adresse": {
"ligneAdresse1": "test street",
"ligneAdresse2": null,
"ligneAdresse3": null,
"codePostal": "75001",
"localite": "test city",
"codePays": "FR",
"libellePays": "France (la)",
"subDivisionPays": null
},
"historisation": {
"idInstance": 1015764,
"dateDebutEffet": null,
"dateDefinition": null,
"creePar": null,
"masque": null
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
| siret | String | The queried 14-digit SIRET number. |
| siren | String | The parent company's 9-digit SIREN number. |
| denomination | String | Official establishment name (may differ from parent company name). |
| typeEtablissement | String | Establishment type (e.g., 'S' = secondary, 'P' = principal). |
| diffusible | String | Publishability flag: "O" = Yes, "N" = No. |
| etatAdministratif | String | Administrative status enum (e.g., "A", "F"). |
| adresse | Object | Establishment address details. |
| historisation | Object | Audit metadata for the record (idInstance, dates, creator, mask). |
400 - Bad Request
Returned when the SIRET parameter does not consist of exactly 14 digits.
{
"error": "VALIDATION_ERROR",
"message": "Invalid SIRET: must be exactly 14 digits",
"code": "FR_SIRET_INVALID"
}
Description: The client has sent a value with fewer or more than 14 digits, or a non-numeric character. The SIRET format is validated against the regex pattern ^\d{14}$.
401 - Unauthorized
Returned when the JWT token in the R-Auth header cannot be verified.
{
"error": "UNAUTHORIZED",
"message": "Invalid or expired authentication token",
"code": "AUTH_TOKEN_INVALID"
}
403 - Forbidden
{
"error": "FORBIDDEN",
"message": "Access denied to this resource",
"code": "ACCESS_DENIED"
}
404 - Not Found
{
"error": "NOT_FOUND",
"message": "No establishment found for SIRET: 27168850399286",
"code": "COMPANY_NOT_FOUND"
}
422 - Unprocessable Entity
{
"error": "UNPROCESSABLE_ENTITY",
"message": "PPF Annuaire registration failed. Please verify your company information and try again.",
"code": "FR_PPF_ONBOARD_FAILED"
}
500 - Internal Server Error
{
"error": "INTERNAL_SERVER_ERROR",
"message": "An unexpected error occurred while contacting PPF Annuaire",
"code": "GENERAL_ERROR"
}
Description: May be triggered by the upstream PPF API being unreachable, a timeout (default 15,000 ms), or an unexpected response format returned by the PPF Annuaire service.
16. PPF Directory Line Instance Lookup GET
Purpose of Use: This endpoint is a live proxy to the PPF Annuaire API. When called, Docnova immediately forwards the request to the PPF's external /ligne-annuaire/id-instance:{idInstance} endpoint, returns the raw PPF response, and does not cache or store the result. The caller receives a real-time snapshot of the directory line as it currently exists in the national PPF Annuaire.
The PPF Annuaire (Portail Public de Facturation Directory) is France's central registry of all VAT-registered companies and their associated Plateformes Agréées, also known as approved e-invoicing platforms. Every company participating in the French e-invoicing mandate must have at least one ligne d'annuaire or directory line entry that specifies:
- Which PA (Plateforme Agréée) the company is connected to, and via which channel
- The company's addressing granularity (
SIREN,SIRET,SUFFIXE, orCODE_ROUTAGE) - The routing and addressing identifiers needed to deliver e-invoices to the company
- Validity dates, effect start and end dates, and historisation metadata
An idInstance is a unique numeric identifier assigned by the PPF to each version of a directory line entry. Because a company's annuaire entry can change over time, for example when switching platforms or updating routing codes, each historical version is preserved and assigned its own idInstance.
This endpoint is used for the following purposes:
- Precise version lookup: Retrieve a specific historical version of a directory line using its immutable
idInstance, even after the entry has been superseded by a newer version. - Annuaire data verification: Verify that a directory line known to Docnova still matches the live PPF Annuaire record for the same instance number. This is used in onboarding diagnostics and reconciliation.
- Platform and routing detail retrieval: Fetch the full
plateforme,etablissement,uniteLegale, andcodeRoutagedetail blocks that are needed to construct valid Peppol / PPF delivery addresses for the target company. - Support and audit use cases: Support teams use this endpoint to inspect the exact PPF record for a given instance, diagnose routing failures, and confirm validity dates.
🔄 Live PPF proxy — no caching: This endpoint makes a real-time call to the PPF Annuaire API on every request. The response reflects the current state of the PPF directory, not a Docnova-stored snapshot. Availability and latency depend on the PPF Annuaire API.
Server-Side Flow
| Step | Process | Description |
|---|---|---|
| 1 | Authentication | The R-Auth JWT is validated by the Spring Security filter chain. The authenticated user principal is extracted. |
| 2 | Input validation | idInstance is checked to be non-blank. A blank value throws a validation error and returns 400. |
| 3 | PPF availability check | If PPF integration is disabled in the Docnova configuration, the service returns null immediately and maps the response to 404 or 503, depending on environment configuration. |
| 4 | External PPF call | Docnova builds the URL /ligne-annuaire/id-instance:{idInstance} and makes an authenticated GET request to the PPF Annuaire API using a cached Bearer token stored in Redis. If the PPF returns 401, Docnova invalidates the cached token, re-authenticates, and retries the request once. |
| 5 | PPF 404 handling | If the PPF returns 404, meaning the instance was not found, Docnova returns null, and the response maps to 404. |
| 6 | Response | Returns HTTP 200 OK with the full AnnuaireLigneAnnuaireResponse JSON object mapped from the PPF response. |
Endpoint Information
| Property | Value |
|---|---|
| URL | /annuaire/FR/directory-line/instance/{idInstance} |
| Method | GET |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
| Integration Type | Live PPF Proxy |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/annuaire/FR/directory-line/instance/{idInstance}' \
--header 'Accept: */*' \
--header 'R-Auth: <jwt-token>'
This endpoint has no query parameters and no request body. The only inputs are the
idInstancepath variable and the authentication token.
Request Parameters
Header Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| R-Auth | string (JWT) | Yes | User session JWT token. Sent without a Bearer prefix. Signed with HS512; sub carries the encrypted user ID, claim carries authorization data, and userType holds CLIENT or ADMIN. |
| Accept | string | No | */* or application/json. Defaults to JSON if omitted. |
Path Parameters
| Parameter | Type | Required | Format / Example | Description |
|---|---|---|---|---|
| idInstance | string (numeric) | Yes | 1013330 | The PPF-assigned unique numeric instance identifier of the directory line entry to retrieve. Assigned by the PPF when a ligne d'annuaire is created or updated. Each historical version of a directory line has a distinct idInstance. Must be non-blank; numeric string format is expected. No UUID format is required. |
Responses
200 - Successful Response
Returns HTTP 200 OK with an AnnuaireLigneAnnuaireResponse object. The structure is nested: top-level addressing fields are accompanied by embedded plateforme, uniteLegale, etablissement, historisation, and codeRoutage objects.
{
"identifiantAdressage": "123456789",
"matriculePlateforme": "0001",
"identifiantRoutage": "0009:0001",
"siren": "123456789",
"siret": "12345678900014",
"suffixeAdressage": null,
"dateFinEffet": null,
"dateFinEffective": null,
"historisation": {
"idInstance": 1013330,
"dateDebutEffet": "2026-01-01",
"dateDefinition": "2025-12-20T09:00:00Z",
"creePar": "DOCNOVA_PA",
"masque": false
},
"plateforme": {
"typePlateforme": "PA",
"matriculePlateforme": "0001",
"raisonSocialePlateforme": "Melasoft SAS",
"nomCommercialPlateforme": "Docnova",
"contactOuUrlPlateforme": "https://docnova.ai",
"statutPlateforme": "ACTIF"
},
"uniteLegale": {
"siren": "123456789",
"raisonSociale": "ACME FRANCE SAS",
"typeEntite": "PM",
"etatAdministratif": "A",
"diffusible": "O"
},
"etablissement": {
"siret": "12345678900014",
"siren": "123456789",
"denomination": "ACME FRANCE SAS - SIEGE",
"typeEtablissement": "SIEGE",
"diffusible": "O",
"etatAdministratif": "A",
"adresse": {
"ligneAdresse1": "10 RUE DE LA PAIX",
"ligneAdresse2": null,
"ligneAdresse3": null,
"codePostal": "75001",
"localite": "PARIS",
"codePays": "FR",
"libellePays": "France",
"subDivisionPays": null
},
"donneesB2gComplementaires": null
},
"codeRoutage": null
}
Response Body — Top-Level Fields
| Field | Type | Nullable | Description |
|---|---|---|---|
| identifiantAdressage | string | Yes | The primary addressing identifier of the company in the PPF Annuaire. Contains the SIREN (9 digits) when maille is SIREN, SIRET (14 digits) when maille is SIRET, or the routing code value for CODE_ROUTAGE. |
| matriculePlateforme | string | Yes | PPF registration code of the Plateforme Agréée that handles this company's e-invoices. Used as the network address of the PA in Peppol routing. |
| identifiantRoutage | string | Yes | Full routing identifier in the format {schemeId}:{value}, for example 0009:0001. Used by the PPF to route incoming e-invoices to the correct PA endpoint. |
| siren | string (9) | Yes | The 9-digit SIREN of the company this directory line belongs to. |
| siret | string (14) | Yes | The 14-digit SIRET of the specific establishment, if this entry is registered at SIRET granularity. null for SIREN-level entries. |
| suffixeAdressage | string | Yes | Suffix appended to the SIRET for sub-unit identification. Populated only when the annuaire maille is SUFFIXE. |
| dateFinEffet | LocalDate | Yes | The planned end date of this directory line's validity. null if the entry is open-ended and still active. |
| dateFinEffective | LocalDate | Yes | The actual effective end date as confirmed by the PPF. May differ from dateFinEffet if the closure was processed at a different time. |
| historisation | object | Yes | Version and audit metadata assigned by the PPF to this specific instance. See historisation below. |
| plateforme | object | Yes | Full detail of the Plateforme Agréée associated with this directory line. See plateforme below. |
| uniteLegale | object | Yes | Legal entity (SIREN-level) details of the company. See uniteLegale below. |
| etablissement | object | Yes | Establishment (SIRET-level) details including address and B2G configuration. See etablissement below. |
| codeRoutage | object | Yes | Routing code detail block. Populated only when the annuaire maille is CODE_ROUTAGE. null for SIREN, SIRET, and SUFFIXE entries. See codeRoutage below. |
historisation — Version & Audit Metadata
| Field | Type | Nullable | Description |
|---|---|---|---|
| idInstance | integer | No | The PPF-assigned unique instance number of this directory line version. Matches the idInstance supplied in the request path. |
| dateDebutEffet | LocalDate | Yes | The date from which this directory line version became effective in the PPF. |
| dateDefinition | OffsetDateTime | Yes | The exact date-time when this instance was defined, created, or updated in the PPF Annuaire. ISO 8601 with timezone offset. |
| creePar | string | Yes | Identifier of the actor, PA matricule or PPF internal identifier, that created this instance. |
| masque | boolean | Yes | If true, this directory line has been hidden or masked in the PPF Annuaire. A masked entry is not visible to other PAs for routing purposes. |
plateforme — Associated Plateforme Agréée
| Field | Type | Nullable | Description |
|---|---|---|---|
| typePlateforme | string | Yes | Platform type code. Typically PA (Plateforme Agréée) or PPF (Portail Public de Facturation itself). |
| matriculePlateforme | string | Yes | The PPF-assigned registration number of the platform. Used as the routing endpoint identifier in e-invoice transmission. |
| raisonSocialePlateforme | string | Yes | Legal company name of the platform operator. |
| nomCommercialPlateforme | string | Yes | Commercial or brand name of the platform, for example Docnova. |
| contactOuUrlPlateforme | string | Yes | Contact email address or URL of the platform for support or integration queries. |
| statutPlateforme | string | Yes | Administrative status of the platform in the PPF registry. Common values: ACTIF (active), SUSPENDU (suspended), FERME (closed). |
uniteLegale — Legal Entity (SIREN Level)
| Field | Type | Nullable | Description |
|---|---|---|---|
| siren | string (9) | Yes | 9-digit SIREN of the legal entity. |
| raisonSociale | string | Yes | Legal company name registered with INSEE. |
| typeEntite | string | Yes | Entity type: PM (Personne Morale / legal person) or PP (Personne Physique / natural person). |
| etatAdministratif | string | Yes | Administrative status from INSEE: A (Actif / active) or C (Cessé / ceased). |
| diffusible | string | Yes | INSEE diffusion flag: O (diffusible / public) or N (non-diffusible / private). Non-diffusible entities have restricted access in public directories. |
etablissement — Establishment (SIRET Level)
| Field | Type | Nullable | Description |
|---|---|---|---|
| siret | string (14) | Yes | 14-digit SIRET of the establishment. |
| siren | string (9) | Yes | Parent SIREN of the establishment. |
| denomination | string | Yes | Establishment name or designation. May include branch suffix, for example - SIEGE. |
| typeEtablissement | string | Yes | Type of establishment: SIEGE (registered head office) or SECONDAIRE (secondary establishment). |
| diffusible | string | Yes | INSEE diffusion flag: O or N. |
| etatAdministratif | string | Yes | Administrative status: A (active) or F (fermé / closed). |
| adresse | object | Yes | Postal address of the establishment. See etablissement.adresse fields below. |
| donneesB2gComplementaires | object | Yes | B2G (Business-to-Government) supplementary data. null for purely B2B companies. See donneesB2gComplementaires below. |
etablissement.adresse — Postal Address
| Field | Type | Nullable | Description |
|---|---|---|---|
| ligneAdresse1 | string | Yes | First address line, including street number and name. |
| ligneAdresse2 | string | Yes | Second address line, for example building, floor, or additional location information. |
| ligneAdresse3 | string | Yes | Third address line for additional details. |
| codePostal | string | Yes | French postal code, 5 digits. |
| localite | string | Yes | City or locality name. |
| codePays | string (2) | Yes | ISO 3166-1 alpha-2 country code, for example FR. |
| libellePays | string | Yes | Full country name in French. |
| subDivisionPays | string | Yes | Country subdivision code (ISO 3166-2). Rare; mostly null for French addresses. |
etablissement.donneesB2gComplementaires — B2G Supplementary Data
| Field | Type | Nullable | Description |
|---|---|---|---|
| gestionEngagementJuridique | boolean | Yes | Whether legal commitment management is enabled for this entity in the B2G context. |
| gestionStatutMiseEnPaiement | boolean | Yes | Whether payment status management is active. |
| gestionCodeService | boolean | Yes | Whether service code management is enabled. |
| moaUniquement | boolean | Yes | If true, this entity operates as buyer (MOA — Maître d'Ouvrage) only in B2G flows. |
| gestionEngagementJuridiqueOuService | boolean | Yes | Combined flag indicating whether legal commitment or service code management is enabled. |
| moa | boolean | Yes | Whether this entity is designated as MOA (project owner / buyer) in the B2G procurement flow. |
codeRoutage — Routing Code Detail (CODE_ROUTAGE Maille Only)
| Field | Type | Nullable | Description |
|---|---|---|---|
| identifiantRoutage | string | Yes | The routing code identifier assigned to this sub-unit. |
| typeIdentifiantRoutage | string | Yes | Type of the routing identifier, also known as the scheme. |
| libelleCodeRoutage | string | Yes | Human-readable label for the routing code. |
| gestionEngagementJuridique | boolean | Yes | B2G legal commitment flag at routing code level. |
| etatAdministratif | string | Yes | Administrative status of this routing code: A (active) or F (closed). |
| adresse | object | Yes | Postal address associated with this routing code. Same structure as etablissement.adresse. |
Enum Values
FrancePpfMaille — Annuaire Addressability Granularity
Determines which of the nested objects is populated and which top-level identifier is used.
| Value | identifiantAdressage Contains | Populated Nested Object | Description |
|---|---|---|---|
| SIREN | 9-digit SIREN | uniteLegale | Company is registered at SIREN level. All invoices addressed to this company, regardless of establishment, are routed to the same PA. |
| SIRET | 14-digit SIRET | etablissement | Company is registered at establishment level. Different SIRET numbers may route to different PAs. |
| SUFFIXE | SIRET + suffix | etablissement + suffixeAdressage | Sub-unit of an establishment identified by an additional suffix. Used for large organizations with complex internal routing. |
| CODE_ROUTAGE | routing code value | codeRoutage | Custom routing code; used by large corporate groups where neither SIREN nor SIRET granularity is sufficient. |
All error responses share the following structure:
{
"errorMessage": "<human-readable message>",
"errorType": "<error type key>",
"errorTitle": "<HTTP status name>",
"status": 404,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/annuaire/FR/directory-line/instance/1013330"
}
400 - Bad Request
Returned when the idInstance path variable is present but empty or blank.
{
"errorMessage": "idInstance must not be blank",
"errorType": "BAD_REQUEST",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/annuaire/FR/directory-line/instance/"
}
Condition: The idInstance path variable is present but empty or blank, for example /instance/ or /instance/ .
Server behavior: FranceAnnuaireApiService.validateNotBlank() throws IllegalArgumentException; RestExceptionHandler maps it to 400.
401 - Unauthorized
Returned when the R-Auth header is missing, malformed, or the JWT token is expired.
{
"errorMessage": "Not authorized for this action",
"errorType": "NOT_AUTHORITY",
"errorTitle": "UNAUTHORIZED",
"status": 401,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/annuaire/FR/directory-line/instance/1013330"
}
Condition: The R-Auth header is missing, malformed, or the JWT exp claim has passed.
Server behavior: Spring Security filter chain rejects the request before the controller is reached.
404 - Not Found
Returned when the PPF Annuaire API returns 404.
{
"errorMessage": "Not Found",
"errorType": "NOT_FOUND",
"errorTitle": "NOT_FOUND",
"status": 404,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/annuaire/FR/directory-line/instance/1013330"
}
Condition: The PPF Annuaire API returned 404, meaning no directory line exists for the given idInstance, or the instance number has never been assigned by the PPF.
Server behavior: FranceAnnuaireApiService.doGetAttempt() receives a 404 from PPF and returns null; the controller's toResponse(null) maps to a 404 HTTP response.
500 - Internal Server Error
Returned when an unexpected exception occurs while communicating with the PPF Annuaire API.
{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"status": 500,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/annuaire/FR/directory-line/instance/1013330"
}
Condition: An unexpected exception occurred while communicating with the PPF Annuaire API, such as network timeout, malformed PPF response, or an unhandled HTTP error status from the PPF.
Server behavior: The try/catch in doGetAttempt() catches the exception and rethrows it as a RuntimeException; RestExceptionHandler maps it to 500.
503 - Service Unavailable
Returned when the PPF Annuaire integration is disabled in the Docnova server configuration.
{
"errorMessage": "PPF integration is currently unavailable",
"errorType": "SERVER_ERROR",
"errorTitle": "SERVICE_UNAVAILABLE",
"status": 503,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/annuaire/FR/directory-line/instance/1013330"
}
Condition: The PPF Annuaire integration is disabled in the Docnova server configuration (config.isEnabled() = false). This typically happens in maintenance or staging environments where the PPF connection is intentionally turned off.
Server behavior: The service returns null immediately without calling PPF; response mapping returns 404 or 503, depending on environment configuration.
17. Company Config Search GET
Purpose of Use: This endpoint returns the France e-invoicing module configuration for a company registered on the Docnova platform.
The French e-invoicing reform, mandatory from 01/09/2026, requires all VAT-registered companies (assujettis — taxable persons) to transmit B2B transaction and payment data to the PPF (Portail Public de Facturation — Public Invoicing Portal) via a Plateforme Agréée (PA — certified platform). This obligation covers both e-invoicing flows (Flux 1, 2, 6) and e-reporting flows (Flux 10).
This endpoint is used for the following purposes:
- Portal / UI: Populate the France module configuration screen and display the current status.
- Pre-submission validation: Verify that the module is enabled and the company's PPF registration is complete before initiating a report submission.
- PPF onboarding monitoring: Track the activation lifecycle using the
ppfStatusandppfActivationDatefields. - Dynamic EDI flow control: Read the per-company dynamic EDI transformation mode state via the
dynamicEdiEnabledfield.
Technical Notes
The reportingFrequency field is determined by the company's TVA regime (VAT filing regime) and maps as follows per Dossier Général v3.1, Table 12:
| TVA Regime | Transaction Report Frequency | Payment Report Frequency |
|---|---|---|
| Régime réel normal mensuel | Décadaire | Monthly |
| Régime réel normal trimestriel | Monthly | Monthly |
| Régime simplifié d'imposition | Monthly | Monthly |
| Franchise en base de TVA | Bi-monthly | Bi-monthly |
The declarantRoleCode field corresponds to the /ReportDocument/Issuer/RoleCode element in Flux 10, per Annexe 6 V1.9 rule G7.52. It accepts two values: SE (Vendeur — Seller / invoice issuer) or BY (Acheteur — Buyer / invoice recipient).
Endpoint Information
| Property | Value |
|---|---|
| URL | /reporting/FR/config/{companyId} |
| Method | GET |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/reporting/FR/config/{companyId}' \
--header 'Accept: application/json' \
--header 'R-Auth: <jwt-token>'
Request Parameters
Path Parameters
| Field | Type | Required | Format | Description |
|---|---|---|---|---|
| companyId | UUID | Yes | xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | The Docnova system UUID of the company to query. The France configuration is bound to this company identifier. |
Responses
200 - Successful ResponseA successful response returns HTTP 200 OK with the following JSON body.
"id": "a1b2c3d4-e5f6-7890-abcd-...",
"companyId": "b7844db0-57a1-4f5d-af65-...",
"siret": "12345678901234",
"vatRegime": "RRN_M",
"enabled": true,
"declarantRoleCode": "EM",
"dynamicEdiEnabled": false,
"ppfIdInstance": "PPF-FR-00123456",
"ppfActivationDate": "2024-09-01",
"ppfStatus": "ACTIVE",
"ppfMaille": "SIRET",
"createdTime": "2024-06-15T10:23:45",
"updatedTime": "2025-03-20T14:07:12"
Response Body — Configuration Record Fields
| Field | Type | Description |
|---|---|---|
| id | UUID | Unique system identifier of this configuration record. |
| companyId | UUID | The company UUID sent in the request; identifies the owner of this configuration. |
| siret | string (14) | The company's 14-digit SIRET number in the French tax system. Digits only. Cannot be changed after PPF activation. |
| vatRegime | FranceVatRegime | The company's VAT regime. Directly determines the reporting period and PPF submission deadline. |
| enabled | boolean | true means the France e-reporting module is active for this company. false blocks all report submissions. |
| declarantRoleCode | string (2-3) | Code representing the declarant's role as defined in the PPF Dossier Général, for example EM = Émetteur, MA = Mandataire. 2-3 characters. |
| dynamicEdiEnabled | boolean | true means dynamic EDI transformation mode is enabled for this company; EDI messages are processed through runtime-configured mappings. |
| ppfIdInstance | string | null | The instance identifier assigned to the company on PPF. Returns null if PPF onboarding has not been completed. |
| ppfActivationDate | LocalDate | null | The date the company became active on PPF. Format: YYYY-MM-DD. null if activation has not occurred. |
| ppfStatus | FrancePpfStatus | PPF registration status. |
| ppfMaille | FrancePpfMaille | null | PPF addressability granularity level; indicates at which level the company is registered in the annuaire. |
| createdTime | LocalDateTime | Timestamp when the configuration record was first created. ISO 8601, second precision. |
| updatedTime | LocalDateTime | null | Timestamp of the last update to the configuration record. May be null if no updates have been made. |
Enum Values
FranceVatRegime — VAT Regime
VAT regimes defined per France PPF Dossier Général v3.1, Table 12. Determines the reporting period.
| Value | Full Name | Reporting Period |
|---|---|---|
| RRN_M | Régime Réel Normal — Mensuel | Transaction reports: decadal; payment reports: monthly |
| RRN_T | Régime Réel Normal — Trimestriel | Transaction and payment reports: monthly |
| RSI | Régime Simplifié d'Imposition | Monthly e-reporting |
| FB | Franchise en Base de TVA | Bimonthly e-reporting |
FrancePpfStatus — PPF Registration Status
| Value | Description |
|---|---|
| PENDING | PPF onboarding has been initiated but not yet completed. Waiting for annuaire registration. |
| ACTIVE | Company is active on PPF; report submissions are permitted. |
| CLOSED | PPF registration has been closed; new report submissions are blocked. |
FrancePpfMaille — Addressability Granularity
| Value | Description |
|---|---|
| SIREN | Company is registered in the PPF annuaire at the SIREN level (9 digits). |
| SIRET | Company is registered at the establishment level via SIRET number (14 digits). |
| SUFFIXE | Company is identified with a suffix appended to its SIRET; used for specific sub-units. |
| CODE_ROUTAGE | Company is identified via a custom routing code (code de routage); used for large corporate groups. |
400 - Bad Request
Returned when no France configuration record exists in the database for the given companyId; either it was never created or has been deleted.
{
"errorMessage": "France configuration not found for company: b7844db0-57a1-4f5d-af65-f1e55b1e9beb",
"errorType": "BAD_REQUEST",
"status": "400 BAD_REQUEST",
"timestamp": "2025-06-20T14:23:00",
"path": "/reporting/FR/config/b7844db0-57a1-4f5d-af65-f1e55b1e9beb"
}
Condition: No France configuration record exists in the database for the given companyId.
Server behavior: The service layer throws an IllegalArgumentException; RestExceptionHandler maps it to 400 BAD_REQUEST.
Description: This endpoint returns 400 instead of 404 when no record exists. This is because the service uses IllegalArgumentException rather than a NotFoundException. Use POST /config to create the configuration first.
400 - Bad Request: Invalid UUID Format
Returned when the companyId path parameter does not conform to the UUID format.
{
"errorMessage": "Invalid request parameters",
"errorType": "VALIDATION_ERROR",
"status": "400 BAD_REQUEST",
"timestamp": "2025-06-20T14:23:00",
"path": "/reporting/FR/config/invalid-id"
}
Condition: The companyId path parameter does not conform to the UUID format, for example abc123 or an empty string.
Server behavior: Spring MVC type conversion failure is caught as a BindException; returns errorType: "VALIDATION_ERROR".
401 - Unauthorized
Returned when the R-Auth header is missing, malformed, or the JWT token is expired.
{
"errorMessage": "Not authorized for this action",
"errorType": "NOT_AUTHORITY",
"status": "401 UNAUTHORIZED",
"timestamp": "2025-06-20T14:23:00",
"path": "/reporting/FR/config/{companyId}"
}
Condition: The R-Auth header is missing, malformed, or the JWT token's exp claim has passed.
Server behavior: The Spring Security filter chain rejects the request before it reaches the service layer. An AuthorizationServiceException is thrown.
500 - Internal Server Error
Returned when an unexpected runtime exception occurs while processing the request.
{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"status": "500 INTERNAL_SERVER_ERROR",
"timestamp": "2025-06-20T14:23:00",
"path": "/reporting/FR/config/{companyId}"
}
Condition: An unexpected runtime exception occurs, such as database connectivity failure, JPA transaction error, or another server-side issue.
Server behavior: The RuntimeException or generic Exception handler is triggered and the error is logged server-side.
18. Company Config Update PUT
Purpose of Use: This endpoint updates an existing France e-invoicing module configuration record for a company registered on the Docnova platform. It is the write counterpart of GET /reporting/FR/config/{companyId} and must be called after the configuration has already been created via POST /reporting/FR/config.
The French e-invoicing reform, mandatory from 01/09/2026, requires all VAT-registered companies (assujettis) to transmit B2B transaction and payment data to the PPF (Portail Public de Facturation) via a Plateforme Agréée (PA). This endpoint allows operators to adjust a company's reporting parameters, such as VAT regime, declarant role, or module activation state, as the company's fiscal profile evolves.
This endpoint is used for the following purposes:
- Module activation / deactivation: Set
enabledtotrueorfalseto enable or suspend France e-reporting for the company. - VAT regime update: Adjust
vatRegimewhen the company's TVA filing regime changes, which directly affects reporting cadence and PPF submission deadlines. - Declarant role correction: Update
declarantRoleCodeto match the company's role in Flux 10 per Annexe 6 V1.9 rule G7.52. - SIRET assignment: Set or correct the 14-digit SIRET number. Note: once PPF onboarding is complete (
ppfIdInstanceis set), the SIRET field becomes immutable and any attempt to change it returns400. - Dynamic EDI mode toggle: Enable or disable per-company dynamic EDI transformation mode via
dynamicEdiEnabled.
Technical Notes
The vatRegime field determines the reportingFrequency returned in the response and maps as follows per Dossier Général v3.1, Table 12:
| TVA Regime | Transaction Report Frequency | Payment Report Frequency |
|---|---|---|
| Régime réel normal mensuel | Décadaire | Monthly |
| Régime réel normal trimestriel | Monthly | Monthly |
| Régime simplifié d'imposition | Monthly | Monthly |
| Franchise en base de TVA | Bi-monthly | Bi-monthly |
The declarantRoleCode field corresponds to /ReportDocument/Issuer/RoleCode in Flux 10, per Annexe 6 V1.9 rule G7.52. Accepted values: SE (Vendeur — Seller / invoice issuer) or BY (Acheteur — Buyer / invoice recipient).
If enabled transitions from false to true and ppfStatus is still PENDING, the server automatically triggers PPF annuaire onboarding for the company.
Endpoint Information
| Property | Value |
|---|---|
| URL | /reporting/FR/config/{companyId} |
| Method | PUT |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
Example Request
curl --location --request PUT 'https://api-fr-stage.docnova.ai/reporting/FR/config/{companyId}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'R-Auth: <jwt-token>' \
--data '{
"companyId": "<company-uuid>",
"siret": "12345678901234",
"vatRegime": "RSI",
"declarantRoleCode": "SE",
"enabled": true,
"dynamicEdiEnabled": false
}'
Request Parameters
Path Parameters
| Field | Type | Required | Format | Description |
|---|---|---|---|---|
| companyId | UUID | Yes | xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx | The Docnova system UUID of the company whose France configuration should be updated. Must match the companyId in the request body. |
Request Body
Content-Type: application/json
Body Field Definitions
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| companyId | string (UUID) | Yes | Valid UUID format | The Docnova system UUID of the company. Must match the companyId path parameter. |
| siret | string | No | Exactly 14 digits (\d{14}) | The company's 14-digit SIRET number. Cannot be changed once PPF onboarding is complete (ppfIdInstance is set). Attempting to change it after onboarding returns 400. |
| vatRegime | FranceVatRegime | Yes | Enum — see Enum Values | The company's TVA regime. Determines reporting cadence and PPF submission deadlines. |
| declarantRoleCode | string | No | 2-3 characters | Role code for the declarant in Flux 10 per Annexe 6 V1.9 rule G7.52. Accepted values: SE (Seller) or BY (Buyer). |
| enabled | boolean | Yes | true / false | Activates or deactivates the France e-reporting module for this company. Transitioning from false to true while ppfStatus is PENDING triggers PPF annuaire onboarding. |
| dynamicEdiEnabled | boolean | No | true / false | Enables or disables per-company dynamic EDI transformation mode. Defaults to false if omitted. |
⚠️ SIRET immutability: The
siretfield is locked after PPF onboarding (ppfIdInstanceis set). Any update request that changes the SIRET value at this stage will be rejected with400 BAD_REQUEST.
Responses
200 - Successful Response
A successful update returns HTTP 200 OK with the full updated configuration object.
Example Successful Response
{
"id": "a1b2c3d4-e5f6-7890-abcd-...",
"companyId": "5e570ac8-e7d4-4e5c-9d26-...",
"siret": "12345678901234",
"vatRegime": "RSI",
"enabled": true,
"declarantRoleCode": "SE",
"dynamicEdiEnabled": false,
"ppfIdInstance": "PPF-FR-00123456",
"ppfActivationDate": "2024-09-01",
"ppfStatus": "ACTIVE",
"ppfMaille": "SIRET",
"createdTime": "2024-06-15T10:23:45",
"updatedTime": "2026-06-20T14:07:12"
}
Response Body — Updated Configuration Record Fields
| Field | Type | Description |
|---|---|---|
| id | UUID | Unique system identifier of this configuration record. |
| companyId | UUID | The company UUID that owns this configuration. |
| siret | string (14) | The 14-digit SIRET number stored for this company. Immutable after PPF onboarding. |
| vatRegime | FranceVatRegime | The updated VAT regime. Governs reporting cadence and PPF deadlines. |
| enabled | boolean | true if the France e-reporting module is active for this company. |
| declarantRoleCode | string (2-3) | Declarant role in Flux 10. SE = Seller, BY = Buyer. |
| dynamicEdiEnabled | boolean | true if dynamic EDI transformation mode is active for this company. |
| ppfIdInstance | string | null | PPF-assigned instance identifier. null until onboarding is complete. |
| ppfActivationDate | LocalDate | null | Date the company became active on PPF. Format: YYYY-MM-DD. null if not yet activated. |
| ppfStatus | FrancePpfStatus | PPF registration status. |
| ppfMaille | FrancePpfMaille | null | PPF addressability level; the granularity at which the company is registered in the annuaire. |
| createdTime | LocalDateTime | Timestamp when the configuration was originally created. Does not change on update. |
| updatedTime | LocalDateTime | Timestamp of this update operation. ISO 8601, second precision. |
Enum Values
FranceVatRegime — VAT Regime
Per France PPF Dossier Général v3.1, Table 12. Determines reporting frequency.
| Value | Full Name | Transaction Frequency | Payment Frequency |
|---|---|---|---|
| RRN_M | Régime Réel Normal — Mensuel | Décadaire (10-day, 3x/month) | Monthly |
| RRN_T | Régime Réel Normal — Trimestriel | Monthly | Monthly |
| RSI | Régime Simplifié d'Imposition | Monthly | Monthly |
| FB | Franchise en Base de TVA | Bi-monthly | Bi-monthly |
declarantRoleCode — Declarant Role (Annexe 6 V1.9, rule G7.52)
| Value | French Term | Description |
|---|---|---|
| SE | Vendeur | Seller — the company issues invoices and submits Flux 10 transaction reports as the invoice sender. |
| BY | Acheteur | Buyer — the company receives invoices and reports as the invoice recipient. |
FrancePpfStatus — PPF Registration Status (read-only in response)
| Value | Description |
|---|---|
| PENDING | Onboarding initiated but not yet completed. Annuaire registration awaited. |
| ACTIVE | Company is active on PPF; report submissions are permitted. |
| CLOSED | PPF registration closed; new submissions are blocked. |
FrancePpfMaille — Addressability Granularity (read-only in response)
| Value | Description |
|---|---|
| SIREN | Registered in PPF annuaire at SIREN level (9 digits). |
| SIRET | Registered at establishment level via SIRET (14 digits). |
| SUFFIXE | Identified by a suffix appended to SIRET; used for specific sub-units. |
| CODE_ROUTAGE | Identified via a custom routing code; used for large corporate groups. |
The following error codes are specific to this endpoint. All error responses share the structure below:
{
"errorMessage": "<human-readable message>",
"errorType": "<error type key>",
"status": "<HTTP status string>",
"timestamp": "2026-06-20T14:23:00",
"path": "/reporting/FR/config/{companyId}"
}
400 - Bad Request
Returned when no France configuration record exists for the given companyId. The configuration must be created first via POST /reporting/FR/config.
{
"errorMessage": "France configuration not found for company: {companyId}",
"errorType": "BAD_REQUEST",
"status": "400 BAD_REQUEST",
"timestamp": "2026-06-20T14:23:00",
"path": "/reporting/FR/config/{companyId}"
}
Condition: No France configuration record exists for the given companyId.
Server behavior: Service throws IllegalArgumentException; mapped to 400 by RestExceptionHandler.
Description: Like the GET endpoint, this returns 400 instead of 404 when no config exists, because the service uses IllegalArgumentException.
400 - Bad Request: SIRET Cannot Be Changed After PPF Onboarding
Returned when the request provides a siret value that differs from the existing one, and ppfIdInstance is already set.
{
"errorMessage": "SIRET cannot be changed after PPF onboarding",
"errorType": "BAD_REQUEST",
"status": "400 BAD_REQUEST",
"timestamp": "2026-06-20T14:23:00",
"path": "/reporting/FR/config/{companyId}"
}
Condition: The request provides a siret value that differs from the existing one, and ppfIdInstance is already set, meaning PPF onboarding has been completed.
Server behavior: Service throws IllegalArgumentException with a specific SIRET immutability message.
400 - Bad Request: Body Field Validation Failure
Returned when a required field is missing or a field fails its validation constraint.
{
"errorMessage": "size must be between 14 and 14, must match \"\\d{14}\"",
"errorType": "VALIDATION_ERROR",
"status": "400 BAD_REQUEST",
"timestamp": "2026-06-20T14:23:00",
"path": "/reporting/FR/config/{companyId}"
}
Condition: A required field is missing (companyId, vatRegime) or a field fails its constraint, for example siret is not exactly 14 digits, or declarantRoleCode is outside the 2-3 character range.
Server behavior: Spring's @Valid annotation triggers a BindException; RestExceptionHandler collects all field error messages.
400 - Bad Request: Company VAT / SIREN Validation Failure
Returned when the company record on Docnova is missing its taxNumber (SIREN) or its vatNumber does not match the French format.
{
"errorMessage": "Company taxNumber (SIREN) is required for France configuration",
"errorType": "BAD_REQUEST",
"status": "400 BAD_REQUEST",
"timestamp": "2026-06-20T14:23:00",
"path": "/reporting/FR/config/{companyId}"
}
Condition: The company record on Docnova is missing its taxNumber (SIREN) or its vatNumber does not match the French format (FR + 2 alphanumeric + 9 digits).
Server behavior: validateCompanyForFrance() throws IllegalArgumentException.
400 - Bad Request: Invalid UUID Format
Returned when the companyId path parameter is not a valid UUID.
{
"errorMessage": "Invalid request parameters",
"errorType": "VALIDATION_ERROR",
"status": "400 BAD_REQUEST",
"timestamp": "2026-06-20T14:23:00",
"path": "/reporting/FR/config/invalid-id"
}
Condition: The companyId path parameter is not a valid UUID, for example abc123.
Server behavior: Spring MVC type conversion failure is caught as BindException.
401 - Unauthorized
Returned when the R-Auth header is missing, malformed, or the JWT token is expired.
{
"errorMessage": "Not authorized for this action",
"errorType": "NOT_AUTHORITY",
"status": "401 UNAUTHORIZED",
"timestamp": "2026-06-20T14:23:00",
"path": "/reporting/FR/config/{companyId}"
}
Condition: The R-Auth header is missing, malformed, or the JWT exp claim has passed.
Server behavior: Spring Security filter chain rejects the request before it reaches the service layer. AuthorizationServiceException is thrown.
500 - Internal Server Error
Returned when an unexpected runtime exception occurs while processing the request.
{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"status": "500 INTERNAL_SERVER_ERROR",
"timestamp": "2026-06-20T14:23:00",
"path": "/reporting/FR/config/{companyId}"
}
Condition: Unexpected runtime exception, such as database connectivity failure, JPA transaction error, or annuaire onboarding call failure.
Server behavior: RuntimeException or Exception handler fires; error is logged server-side.
19. Company Config Create POST
Purpose of Use: This endpoint creates the initial France e-invoicing module configuration record for a company on the Docnova platform. It is a one-time setup operation — a given company can only have one France configuration. Attempting to call this endpoint again for the same company returns 400; subsequent changes must go through PUT /reporting/FR/config/{companyId}.
The French e-invoicing reform, mandatory from 01/09/2026, requires all VAT-registered companies (assujettis) to transmit B2B transaction and payment data to the PPF (Portail Public de Facturation) via a Plateforme Agréée (PA — approved platform). This endpoint bootstraps the PPF participation lifecycle for the company.
This endpoint is used for the following purposes:
- Initial configuration bootstrapping: Registers the company's TVA regime, SIRET, declarant role, and module activation preference in the Docnova system.
- PPF status initialization: Automatically sets
ppfStatustoPENDINGon creation. This field transitions toACTIVEonce PPF onboarding completes. - Conditional PPF onboarding trigger: If
enabledis sent astrue, the server immediately triggers the PPF annuaire onboarding call (annuaireService.onboard()) after saving the record. Ifenabledisfalse, onboarding is deferred until the record is updated withenabled: true. - VAT regime assignment: The
vatRegimevalue drives the reporting cadence, including transaction and payment report frequency, for all subsequent PPF submissions. - Declarant role assignment: Sets the company's role in Flux 10 per Annexe 6 V1.9 rule G7.52 — either
SE(Vendeur / Seller) orBY(Acheteur / Buyer).
Server-side Execution Flow
| Step | Process | Description |
|---|---|---|
| 1 | Company lookup | Retrieves the company record by companyId. Returns 404 if not found. |
| 2 | Company validation | Checks that the company has a valid 9-digit SIREN (taxNumber) and a French-format VAT number (FR + 2 alphanumeric + 9 digits). Returns 400 if invalid. |
| 3 | Duplicate check | Verifies no France configuration already exists for this company. Returns 400 if one is found. |
| 4 | Record creation | Persists the new FranceCompanyConfigEntity with ppfStatus = PENDING and all request fields mapped. |
| 5 | Conditional onboarding | If enabled = true, calls annuaireService.onboard(companyId) to register the company in the PPF annuaire. |
| 6 | Response | Returns the freshly persisted configuration record, including system-assigned fields such as id, ppfStatus, and createdTime. |
Reporting Frequency by VAT Regime
Reporting frequency by VAT regime, per Dossier Général v3.1, Table 12:
| VatRegime | Full Name | Transaction Report | Payment Report |
|---|---|---|---|
| RRN_M | Régime Réel Normal — Mensuel | Décadaire (3 × 10-day / month) | Monthly |
| RRN_T | Régime Réel Normal — Trimestriel | Monthly | Monthly |
| RSI | Régime Simplifié d'Imposition | Monthly | Monthly |
| FB | Franchise en Base de TVA | Bi-monthly | Bi-monthly |
Endpoint Information
| Property | Value |
|---|---|
| URL | /reporting/FR/config |
| Method | POST |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/reporting/FR/config' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'R-Auth: <jwt-token>' \
--data '{
"companyId": "<company-uuid>",
"vatRegime": "RSI",
"declarantRoleCode": "SE",
"enabled": false,
"siret": "27168850399286"
}'
Request Parameters
Request Body
Content-Type: application/json
Body Field Definitions
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
| companyId | string (UUID) | Yes | Valid UUID | The Docnova system UUID of the company for which the France configuration is being created. The company must already exist in the system. |
| vatRegime | FranceVatRegime | Yes | Enum — see Enum Values | The company's TVA regime. Determines reporting cadence and PPF submission deadlines. |
| enabled | boolean | Yes | true / false | Activates or deactivates the France e-reporting module. If true, the server immediately triggers PPF annuaire onboarding after saving the record. If false, onboarding is deferred. |
| siret | string | No | Exactly 14 digits (\d{14}) | The company's 14-digit SIRET number (SIREN 9 digits + NIC 5 digits). Validated by format if provided. Can be set or corrected later via PUT, unless PPF onboarding has already completed. |
| declarantRoleCode | string | No | 2-3 characters | Role code for the declarant in Flux 10 per Annexe 6 V1.9 rule G7.52. Accepted values: SE (Seller) or BY (Buyer). The field accepts any 2-3 character string at the validation layer, but only SE and BY are valid per the PPF specification. |
| dynamicEdiEnabled | boolean | No | true / false | Enables per-company dynamic EDI transformation mode. Defaults to false if omitted. |
⚠️ One-time operation: Only one France configuration can exist per company. Calling this endpoint again for the same
companyIdreturns400 BAD_REQUESTwith the message"France configuration already exists for this company. Use update instead."
Responses
200 - Successful Response
A successful creation returns HTTP 200 OK with the full newly created configuration object.
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"companyId": "b7844db0-57a1-4f5d-af65-f1e55b1e9beb",
"siret": "27168850399286",
"vatRegime": "RSI",
"enabled": false,
"declarantRoleCode": "SE",
"dynamicEdiEnabled": false,
"ppfIdInstance": null,
"ppfActivationDate": null,
"ppfStatus": "PENDING",
"ppfMaille": null,
"createdTime": "2026-06-20T17:26:56",
"updatedTime": "2026-06-20T17:26:56"
}
Response Body — Created Configuration Record Fields
| Field | Type | Initial Value | Description |
|---|---|---|---|
| id | UUID | Auto-generated | Unique system identifier for this configuration record. |
| companyId | UUID | From request | The company UUID that owns this configuration. |
| siret | string (14) | null | From request | The 14-digit SIRET number. null if not provided in the request. |
| vatRegime | FranceVatRegime | From request | The assigned VAT regime. Governs all subsequent PPF reporting cadences. |
| enabled | boolean | From request | true if the France e-reporting module is active and PPF onboarding was triggered. |
| declarantRoleCode | string | null | From request | Declarant role in Flux 10. null if not provided. |
| dynamicEdiEnabled | boolean | false | Dynamic EDI mode flag. Always false unless explicitly set. |
| ppfIdInstance | string | null | null | PPF-assigned instance identifier. Always null on initial creation; populated after onboarding completes. |
| ppfActivationDate | LocalDate | null | null | Date the company became active on PPF. null on creation. |
| ppfStatus | FrancePpfStatus | PENDING | Always PENDING on creation, regardless of enabled. Transitions to ACTIVE once PPF onboarding is confirmed. |
| ppfMaille | FrancePpfMaille | null | null | PPF addressability granularity. null on creation; set by the PPF onboarding response. |
| createdTime | LocalDateTime | Now | Timestamp of this creation operation. ISO 8601, second precision. |
| updatedTime | LocalDateTime | Now | Equals createdTime on initial creation. |
Enum Values
FranceVatRegime — VAT Regime
Per France PPF Dossier Général v3.1, Table 12.
| Value | Full Name | Transaction Report Frequency | Payment Report Frequency |
|---|---|---|---|
| RRN_M | Régime Réel Normal — Mensuel | Décadaire (10-day, 3×/month) | Monthly |
| RRN_T | Régime Réel Normal — Trimestriel | Monthly | Monthly |
| RSI | Régime Simplifié d'Imposition | Monthly | Monthly |
| FB | Franchise en Base de TVA | Bi-monthly | Bi-monthly |
declarantRoleCode — Declarant Role (Annexe 6 V1.9, rule G7.52)
| Value | French Term | Description |
|---|---|---|
| SE | Vendeur | Seller — the company issues invoices and submits Flux 10 transaction reports as the invoice sender. |
| BY | Acheteur | Buyer — the company receives invoices and reports as the invoice recipient. |
FrancePpfStatus — PPF Registration Status (read-only in response)
| Value | Description |
|---|---|
| PENDING | Default on creation. Onboarding initiated but not yet confirmed by PPF. |
| ACTIVE | PPF onboarding complete; report submissions are permitted. |
| CLOSED | PPF registration closed; new submissions are blocked. |
FrancePpfMaille — Addressability Granularity (read-only in response)
| Value | Description |
|---|---|
| SIREN | Registered at SIREN level (9 digits) in PPF annuaire. |
| SIRET | Registered at establishment level via SIRET (14 digits). |
| SUFFIXE | Identified by a suffix appended to SIRET; for specific sub-units. |
| CODE_ROUTAGE | Identified via a custom routing code; for large corporate groups. |
All error responses share the following structure:
{
"errorMessage": "<human-readable message>",
"errorType": "<error type key>",
"errorTitle": "<HTTP status name>",
"errorId": "<trace UUID>",
"status": 404,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/reporting/FR/config"
}
400 - Bad Request
Returned when a France configuration record already exists for this companyId.
{
"errorMessage": "France configuration already exists for this company. Use update instead.",
"errorType": "BAD_REQUEST",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/reporting/FR/config"
}
Condition: A France configuration record already exists for this companyId. This endpoint is a one-time setup call; updates must use PUT /reporting/FR/config/{companyId}.
Server behavior: Service throws IllegalStateException; mapped to 400 by RestExceptionHandler.
400 - Bad Request: Body Field Validation Failure
Returned when a required field is missing or a field fails its validation constraint.
{
"errorMessage": "size must be between 14 and 14, must match \"\\d{14}\"",
"errorType": "VALIDATION_ERROR",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/reporting/FR/config"
}
Condition: A required field is missing (companyId, vatRegime) or a field fails its constraint — siret is not exactly 14 digits, or declarantRoleCode is outside the 2-3 character range.
Server behavior: Spring's @Valid annotation triggers a BindException; all field error messages are concatenated.
400 - Bad Request: Company SIREN / VAT Validation Failure
Returned when the company record in Docnova is missing its SIREN or VAT number is invalid.
{
"errorMessage": "Company taxNumber (SIREN) is required for France configuration",
"errorType": "BAD_REQUEST",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/reporting/FR/config"
}
Condition: The company record in Docnova is missing its taxNumber (SIREN must be 9 digits) or its vatNumber does not match the French format (FR + 2 alphanumeric + 9 digits). This validation runs before the config record is created.
Server behavior: validateCompanyForFrance() throws IllegalArgumentException; mapped to 400.
401 - Unauthorized
Returned when the R-Auth header is missing, malformed, or the JWT token is expired.
{
"errorMessage": "Not authorized for this action",
"errorType": "NOT_AUTHORITY",
"errorTitle": "UNAUTHORIZED",
"status": 401,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/reporting/FR/config"
}
Condition: The R-Auth header is missing, malformed, or the JWT exp claim has passed.
Server behavior: Spring Security filter chain rejects the request before reaching the controller. AuthorizationServiceException is thrown.
404 - Not Found
Returned when the companyId in the request body does not match any company record in the Docnova system.
{
"errorMessage": "Company not found!",
"errorType": "NOT_FOUND_COMPANY",
"errorTitle": "NOT_FOUND",
"errorId": "3c3904d7-0c6a-4f9b-a756-...",
"status": 404,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/reporting/FR/config"
}
Condition: The companyId in the request body does not match any company record in the Docnova system.
Server behavior: companyService.getCompany() throws NotFoundException; mapped to 404 by RestExceptionHandler.
500 - Internal Server Error
Returned when an unexpected runtime exception occurs while processing the request.
{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"status": 500,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/reporting/FR/config"
}
Condition: Unexpected runtime exception — database connectivity failure, JPA transaction error, or PPF annuaire onboarding call failure after the record has been saved.
Server behavior: RuntimeException or Exception handler fires; error is logged server-side with a stack trace.
20. Reporting Search Status GET
Purpose of Use: This endpoint fetches the full detail and current status snapshot of a single France PPF report record identified by its Docnova-assigned reportId. It is the primary single-record status lookup used by the Docnova frontend to display the detail view of a specific report, and can be called programmatically to poll for status changes after a report has been submitted.
Under the French e-invoicing mandate, mandatory from 01/09/2026, every B2B/B2C transaction data and payment report sent to the PPF (Portail Public de Facturation) passes through a multi-stage lifecycle. The PPF asynchronously returns an acknowledgement (accusé de réception) — either Ok, Error, Pending, or Processing. This endpoint exposes the most recently persisted version of that acknowledgement alongside the full report record.
This endpoint is used for the following purposes:
- Single-report detail view: The frontend calls this endpoint after a user clicks on a specific report in the reporting list to show its full detail, including PPF flow ID, rejection reason, and submission timeline.
- Status verification after submission: Integrations can poll this endpoint after a report submission to determine whether the PPF has accepted or rejected it without fetching the full list.
- PPF error diagnosis: When a report is
REJECTED, the response includesppfErrorCodeandppfErrorMessagepopulated from the PPF acknowledgement detail, allowing developers and support teams to understand the exact rejection reason. - Deadline monitoring: The
submissionDeadlinefield is returned, enabling client applications to display urgency indicators for reports not yet submitted.
Important: This endpoint reads the cached status stored in the Docnova database. It does not actively call the PPF API on each request. The PPF acknowledgement status is refreshed by a background scheduler (pollSingleReportStatus) that periodically queries the PPF and updates the stored record. To see the very latest PPF status, the background polling must have run since the last PPF state change.
Server-Side Flow
| Step | Process | Description |
|---|---|---|
| 1 | Authentication | The R-Auth JWT is validated by the Spring Security filter chain. The authenticated user's uid is extracted via @AuthenticationPrincipal JwtUser. |
| 2 | Report lookup | The service calls reportRepository.findById(reportId). If no record exists for this UUID, IllegalArgumentException("Report not found") is thrown and mapped to 400. |
| 3 | DTO mapping | The found FranceReportEntity is mapped to FranceReportResponse via toResponse(). All persisted fields, including PPF acknowledgement data, are included. |
| 4 | Response | Returns HTTP 200 OK with the full FranceReportResponse JSON object. |
🛰️ Background PPF polling (separate process): A scheduler (
pollSingleReportStatus) periodically calls the PPF's flow status API, maps the PPF acknowledgement (Ok → ACCEPTED,Error → REJECTED) and persists the updated status back to the database. This endpoint reads that persisted state.
Endpoint Information
| Property | Value |
|---|---|
| URL | /reporting/FR/status/{reportId} |
| Method | GET |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/reporting/FR/status/{reportId}' \
--header 'Accept: */*' \
--header 'R-Auth: <jwt-token>'
This endpoint has no query parameters and no request body. The only input is the
reportIdpath variable and the authentication token.
Request Parameters
Path Parameters
| Parameter | Type | Required | Format / Example | Description |
|---|---|---|---|---|
| reportId | UUID | Yes | 0034cdf6-3032-4fe1-b276-21a83191aeee | The Docnova system UUID of the specific France report record to retrieve. Obtained from the reportId field of the GET /reporting/FR/list response. |
Responses
200 - Successful Response
Returns HTTP 200 OK with a single FranceReportResponse JSON object.
{
"reportId": "0034cdf6-3032-4fe1-b276-...",
"status": "ACCEPTED",
"reportType": "TRANSACTION_B2C",
"source": "PORTAL",
"category": "SERVICE",
"senderSiren": "123456789",
"ppfFlowId": "FRR-10.3-20260609-00042",
"trackingId": "TRK-9988776655",
"invoiceId": "aaaabbbb-cccc-dddd-eeee-...",
"invoiceNumber": "INV-2026-00451",
"itemCount": 3,
"totalAmount": 4850.00,
"submittedTime": "2026-06-09T10:15:00",
"createdTime": "2026-06-09T10:14:32",
"submissionDeadline": "2026-06-19T23:59:59",
"ppfAckStatus": "Ok",
"ppfErrorMessage": null,
"ppfErrorCode": null,
"lastStatusCheckTime": "2026-06-09T10:16:00"
}
{
"reportId": "0034cdf6-3032-4fe1-b276-...",
"status": "REJECTED",
"ppfAckStatus": "Error",
"ppfErrorMessage": "Le SIREN déclarant n'est pas enregistré dans l'annuaire PPF",
"ppfErrorCode": "501",
"lastStatusCheckTime": "2026-06-09T10:16:00"
}
Response Body — Report Status Fields
| Field | Type | Nullable | Description |
|---|---|---|---|
| reportId | UUID | No | Unique identifier of this report record in the Docnova system. Matches the reportId passed in the path. |
| status | FranceReportStatus | No | Current Docnova-side lifecycle status of the report. Derived from PPF acknowledgement — transitions to ACCEPTED when ppfAckStatus = Ok, and to REJECTED when ppfAckStatus = Error. |
| reportType | FranceReportType | Yes | Specific report type: B2C or B2B, transaction or payment declaration. |
| source | InvoiceSource | Yes | Origin channel of the underlying invoice document, for example PORTAL, ERP, or PPF. |
| category | FranceCategory | Yes | Business nature of the reported transaction: SERVICE, GOODS, MIXED, or NON_TAXABLE. |
| senderSiren | string | Yes | 9-digit SIREN of the invoice sender, also known as the declarant company. |
| ppfFlowId | string | Yes | The PPF-assigned flow identifier returned when the report was submitted, for example FRR-10.3-.... null before submission. Used internally by the background scheduler to poll PPF status. |
| trackingId | string | Yes | Internal Docnova tracking reference for this submission attempt. |
| invoiceId | UUID | Yes | Docnova UUID of the underlying invoice document this report is based on. |
| invoiceNumber | string | Yes | Human-readable invoice reference number. |
| itemCount | integer | Yes | Number of line items included in this report. |
| totalAmount | BigDecimal | Yes | Total monetary amount reported, in the currency of the underlying invoice. |
| submittedTime | LocalDateTime | Yes | Timestamp when the report was successfully dispatched to the PPF. null if not yet submitted. |
| createdTime | LocalDateTime | No | Timestamp when the report record was created in the Docnova system. |
| submissionDeadline | LocalDateTime | Yes | The PPF-mandated deadline by which this report must be submitted. Calculated from the company's vatRegime and the reporting period. null if not yet calculated. |
| ppfAckStatus | string | Yes | Raw acknowledgement status string returned by the PPF. Possible values: Ok, Error, Pending, Processing. null if no PPF response received yet. |
| ppfErrorMessage | string | Yes | Human-readable rejection reason from the PPF acknowledgement detail. Populated only when ppfAckStatus = Error. Contains the PPF's reasonMessage from the first detail entry. |
| ppfErrorCode | string | Yes | Machine-readable error code from the PPF. Populated when ppfAckStatus = Error. Contains the reasonCode from the PPF detail, or defaults to 501 (IRRECEVABLE) if no detail was returned. |
| lastStatusCheckTime | LocalDateTime | Yes | Timestamp of the most recent background PPF status polling attempt for this report. Used to assess staleness of the ppfAckStatus value. |
PPF Acknowledgement Status Values
The ppfAckStatus field reflects the raw value returned by the PPF acknowledgement.status field. The background scheduler maps these values to the Docnova status field.
| PPF Ack Status | Meaning | Docnova Status Mapping |
|---|---|---|
| Ok | The PPF has fully accepted and processed the report. No errors found. | ACCEPTED |
| Error | The PPF rejected the report. ppfErrorCode and ppfErrorMessage contain the rejection details from PPF acknowledgement detail entries. | REJECTED |
| Pending | The PPF has received the report but has not yet started processing it. Status will be polled again by the background scheduler. | No Docnova status change |
| Processing | The PPF is currently validating the report. Status will be polled again by the background scheduler. | No Docnova status change |
⚠️ PPF error codes: When
ppfAckStatus = Error, theppfErrorCodefield contains a Chorus Pro / PPF status code. The most common values are500(RECEVABLE— accepted) and501(IRRECEVABLE— rejected). If the PPF returns an error without detail entries, the code defaults to501.
Enum Values
FranceReportStatus — Report Lifecycle Status
| Value | Description |
|---|---|
| DRAFT | Report created but not yet sent for validation. Initial state. |
| VALIDATING | Report is undergoing format and business rule validation before submission. |
| SUBMITTED | Report dispatched to the PPF; awaiting acknowledgement (ppfAckStatus is Pending or Processing). |
| ACCEPTED | PPF returned ppfAckStatus = Ok. Report successfully processed. |
| REJECTED | PPF returned ppfAckStatus = Error. See ppfErrorCode and ppfErrorMessage for details. |
| ERROR | A Docnova system-level failure prevented submission. Not a PPF rejection. |
| REPORTED | Report acknowledged and included in a PPF period summary. |
| MERGED | Report was merged with another period report. |
FranceReportType — Specific Report Type
| Value | Group | Flow Prefix | Description |
|---|---|---|---|
| TRANSACTION_B2C | E_REPORTING | FRR-10.3 | B2C transaction e-report, domestic sales to non-business customers. |
| TRANSACTION_B2B | E_REPORTING | FRR-10.1 | B2B international transaction e-report. |
| PAYMENT_B2B | PAYMENT | FRR-10.2 | B2B payment declaration report. |
| PAYMENT_B2C | PAYMENT | FRR-10.4 | B2C payment declaration report. |
FranceCategory — Transaction Business Category
| Value | Description |
|---|---|
| SERVICE | Service-based items only. |
| GOODS | Physical goods only. |
| MIXED | Both goods and services. |
| NON_TAXABLE | Outside the scope of French TVA. |
All error responses share the following structure:
{
"errorMessage": "<human-readable message>",
"errorType": "<error type key>",
"errorTitle": "<HTTP status name>",
"status": 400,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/reporting/FR/status/0034cdf6-3032-4fe1-b276-21a83191aeee"
}
400 - Bad Request
Returned when no report record exists in the Docnova database for the given reportId UUID.
{
"errorMessage": "Report not found",
"errorType": "BAD_REQUEST",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/reporting/FR/status/0034cdf6-3032-4fe1-b276-21a83191aeee"
}
Condition: No report record exists in the Docnova database for the given reportId UUID. The ID may be incorrect, belong to a different company, or have been deleted.
Server behavior: reportRepository.findById() returns empty → service throws IllegalArgumentException("Report not found") → RestExceptionHandler maps to 400.
400 - Bad Request: Invalid UUID Format
Returned when the reportId path variable is not a valid UUID string.
{
"errorMessage": "Invalid request parameters",
"errorType": "VALIDATION_ERROR",
"errorTitle": "BAD_REQUEST",
"status": 400,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/reporting/FR/status/invalid-id"
}
Condition: The reportId path variable is not a valid UUID string, for example missing hyphens, wrong length, or non-hex characters.
Server behavior: Spring's path variable type conversion to UUID fails → BindException is thrown and caught by RestExceptionHandler.
401 - Unauthorized
Returned when the R-Auth header is missing, malformed, or the JWT token is expired.
{
"errorMessage": "Not authorized for this action",
"errorType": "NOT_AUTHORITY",
"errorTitle": "UNAUTHORIZED",
"status": 401,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/reporting/FR/status/0034cdf6-3032-4fe1-b276-21a83191aeee"
}
Condition: The R-Auth header is missing, malformed, or the JWT exp claim has passed.
Server behavior: Spring Security filter chain rejects the request before it reaches the controller.
500 - Internal Server Error
Returned when an unexpected runtime exception occurs while processing the request.
{
"errorMessage": "An unexpected error occurred",
"errorType": "RUNTIME_ERROR",
"errorTitle": "INTERNAL_SERVER_ERROR",
"status": 500,
"timestamp": "2026-06-20T17:26:56.155059",
"path": "/reporting/FR/status/0034cdf6-3032-4fe1-b276-21a83191aeee"
}
Condition: Unexpected runtime exception, such as database connectivity failure, JPA query error, or entity-to-DTO mapping failure.
Server behavior: RuntimeException or Exception handler fires; error is logged server-side with stack trace.
21. Reporting Search Reports GET
Purpose of Use: This endpoint lists e-reporting and payment notification records created under France's mandatory tax reporting system in a paginated and filterable format. Under French tax law, businesses are required to submit two types of mandatory reports to the PPF (Plateforme Publique de Facturation):
- E-Reporting: Periodic submission of tax data for B2C and international B2B transactions
- Payment Reporting: Reporting of invoice payments from prior periods to the PPF
This endpoint allows querying both report groups through a single list interface. Rich filter options allow narrowing results by company, SIREN number, date range, report type, status, source channel, or PPF acknowledgement status. Results follow the standard Spring Data Page structure, making it possible to control page size and sorting for large datasets.
Typical use cases:
- Listing all French tax reports for a specific company on a dashboard
- Identifying failed or rejected reports using
status=REJECTEDorstatus=ERROR - Tracking
PAYMENT_B2Ctype reports submitted within a specific date range - Monitoring pending reports by filtering on
ppfAckStatus - Isolating reports for transactions from a specific sales channel using
source=EBAY
Endpoint Information
| Property | Value |
|---|---|
| URL | /reporting/FR/list |
| Method | GET |
| Content-Type | application/json |
| Base URL | Stage Environment URLhttps://api-fr-stage.docnova.ai/ Production Environment URLhttps://api-fr.docnova.ai/ |
| Authorization | R-Auth header (JWT token) |
Example Request
curl --location 'https://api-fr-stage.docnova.ai/reporting/FR/list?companyId={companyId}&pageNumber=0&pageSize=20&dateFrom=2026-06-09&dateTo=2026-06-17&reportGroup=E_REPORTING' \
--header 'accept: */*' \
--header 'accept-language: en-US,en;q=0.9,tr;q=0.8,tk;q=0.7' \
--header 'content-type: application/json' \
--header 'origin: https://app-fr-stage.docnova.ai' \
--header 'priority: u=1, i' \
--header 'r-auth: '<JWT_TOKEN>' \
--header 'referer: https://app-fr-stage.docnova.ai/invoice-reporting' \
--header 'sec-ch-ua: "Google Chrome";v="149", "Chromium";v="149", "Not)A;Brand";v="24"' \
--header 'sec-ch-ua-mobile: ?0' \
--header 'sec-ch-ua-platform: "Windows"' \
--header 'sec-fetch-dest: empty' \
--header 'sec-fetch-mode: cors' \
--header 'sec-fetch-site: same-site' \
--header 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/149.0.0.0 Safari/537.36'
Request Parameters
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| companyId | string (UUID) | Yes | The unique identifier (UUID) of the company whose reports are being queried. |
| reportType | string (enum) | No | Report type filter. Narrows results to a specific transaction or payment type. |
| reportGroup | string (enum) | No | Report group filter. If reportType is not specified, returns all types within this group. |
| source | string (enum) | No | The source platform or channel through which the invoice/transaction was created. |
| status | string (enum) | No | Processing status filter for the report. |
| ppfAckStatus | string | No | The acknowledgement/notification status returned by PPF. Free-text, case-sensitive match. |
| category | string (enum) | No | Invoice/transaction category filter. |
| dateFrom | string (date) | No | Start date filter (inclusive). ISO 8601 format: YYYY-MM-DD. Matches from start of day. |
| dateTo | string (date) | No | End date filter (inclusive). ISO 8601 format: YYYY-MM-DD. Matches up to start of the following day. |
| siren | string | No | The 9-digit SIREN number of the sending company. Performs a LIKE search on both the senderSiren field and the raw request JSON. |
| pageNumber | integer | No | Page number to retrieve (0-based). Default: 0. |
| pageSize | integer | No | Number of records per page. Default: 20. |
| sort.sorted | boolean | No | Indicates whether sorting is applied. Managed via Spring Pageable. |
| sort.unsorted | boolean | No | Indicates no sorting is applied. |
| offset | integer | No | Pagination offset for the starting position. |
| paged | boolean | No | Whether a paged response is requested. Default: true. |
| unpaged | boolean | No | Whether all records should be returned without pagination. Default: false. |
Parameter Value Tables
reportType Possible Values
| Value | Group | PPF Flow Code | Description |
|---|---|---|---|
| TRANSACTION_B2C | E_REPORTING | FRR-10.3 | E-reporting of B2C individual customer transaction data. |
| TRANSACTION_B2B | E_REPORTING | FRR-10.1 | E-reporting of international B2B transaction data. |
| PAYMENT_B2B | PAYMENT | FRR-10.2 | Payment notification for B2B invoices. |
| PAYMENT_B2C | PAYMENT | FRR-10.4 | Payment notification for B2C invoices. |
reportGroup Possible Values
| Value | Description |
|---|---|
| PAYMENT | Payment notifications group. Includes PAYMENT_B2B and PAYMENT_B2C. |
| E_REPORTING | Electronic reporting group. Includes TRANSACTION_B2C and TRANSACTION_B2B. |
status Possible Values
| Value | Description |
|---|---|
| DRAFT | Draft. Not yet submitted and still editable. |
| VALIDATING | Validating. Being checked by the system before transmission to PPF. |
| SUBMITTED | Submitted. Transmitted to PPF and awaiting acknowledgement. |
| ACCEPTED | Accepted. Successfully processed by PPF. |
| REJECTED | Rejected. Refused by PPF and correction is required. |
| ERROR | Error. Transmission failed due to a technical error. |
| REPORTED | Reported. Processing completed. |
| MERGED | Merged. Combined into another report. |
category Possible Values
| Value | Description |
|---|---|
| SERVICE | Service invoice. |
| GOODS | Goods or product invoice. |
| MIXED | Mixed invoice containing both goods and services. |
| NON_TAXABLE | Transaction not subject to VAT. |
source Selected Values
| Value | Description |
|---|---|
| PORTAL | Created via web portal. |
| ERP | ERP system integration. |
| PEPPOL | Received via the PEPPOL network. |
| EBAY | eBay sales channel. |
| SHOPIFY | Shopify e-commerce platform. |
| AMAZON_SP | Amazon Seller Platform. |
| SFTP | SFTP file transfer. |
| PPF | Directly from the PPF platform. |
| Received via email. | |
| MOBILE | Mobile application. |
| STRIPE | Stripe payment system. |
| TEMU | Temu sales channel. |
For the full list, refer to the InvoiceSource enum. Other values include:
PORTAL_OCR, MOBILE_OCR, EMAIL_OCR, SERVICE, HARVEST, HUBSPOT, ANAF, LAZADA, KSEF, RS_API, ETA, ERACUN, KSEF_OFFLINE, LHDNM, NEMHANDEL.
Responses
200 - Successful Response
{
"content": [
{
"reportId": "3fa85f64-5717-4562-b3fc-...",
"status": "ACCEPTED",
"reportType": "PAYMENT_B2C",
"source": "EBAY",
"category": "NON_TAXABLE",
"senderSiren": "271688503",
"ppfFlowId": "FRR-10.4-20240101-001",
"trackingId": "TRK-2024-00123",
"invoiceId": "8a1e4c2d-1234-4abc-9def-...",
"invoiceNumber": "INV-2024-00456",
"itemCount": 12,
"totalAmount": 1540.50,
"submittedTime": "2024-06-01T10:30:00",
"createdTime": "2024-05-31T08:15:00",
"submissionDeadline": "2024-06-10T23:59:59",
"ppfAckStatus": "Ok",
"ppfErrorMessage": null,
"ppfErrorCode": null,
"lastStatusCheckTime": "2024-06-01T11:00:00"
}
],
"pageable": {
"sort": {
"empty": true,
"sorted": false,
"unsorted": true
},
"offset": 0,
"pageNumber": 0,
"pageSize": 20,
"paged": true,
"unpaged": false
},
"totalPages": 5,
"totalElements": 87,
"last": false,
"sort": {
"empty": true,
"sorted": false,
"unsorted": true
},
"size": 20,
"number": 0,
"first": true,
"numberOfElements": 20,
"empty": false
}
content[] — Report Record Fields
| Field | Type | Description |
|---|---|---|
| reportId | string (UUID) | Unique identifier of the report. Used as a reference in subsequent report operations. |
| status | string (enum) | Current processing status of the report. Uses FranceReportStatus. |
| reportType | string (enum) | Report type. Uses FranceReportType. Indicates which PPF flow this report belongs to. |
| source | string (enum) | Source platform or channel through which the invoice/transaction was created. Uses InvoiceSource. |
| category | string (enum) | Invoice category. Uses FranceCategory. |
| senderSiren | string | 9-digit SIREN number of the sending company. |
| ppfFlowId | string | Flow identifier assigned by PPF. Used for tracking and debugging. |
| trackingId | string | Internal system tracking identifier. |
| invoiceId | string (UUID) | UUID of the invoice associated with this report. |
| invoiceNumber | string | Human-readable invoice number. |
| itemCount | integer | Number of transactions or line items covered by this report. |
| totalAmount | number (decimal) | Total monetary amount of the report. |
| submittedTime | string (datetime) | Date and time the report was transmitted to PPF. ISO 8601 format. |
| createdTime | string (datetime) | Date and time the report was created in the system. ISO 8601 format. |
| submissionDeadline | string (datetime) | Latest date and time by which the report must be submitted. ISO 8601 format. |
| ppfAckStatus | string | Acknowledgement status text returned by PPF, for example Ok, Error, or Pending. |
| ppfErrorMessage | string | null | Error message returned by PPF upon rejection. |
| ppfErrorCode | string | null | Error code returned by PPF. |
| lastStatusCheckTime | string (datetime) | Date and time of the most recent PPF status check. ISO 8601 format. |
400 - Bad Request
Returned when an invalid value is sent for an enum-type parameter, such as status, reportType, or category.
{
"error": "BAD_REQUEST",
"message": "Failed to convert value of type 'String' to required type 'FranceReportStatus'; nested exception is: No enum constant FranceReportStatus.INVALID_VALUE",
"code": "INVALID_PARAMETER"
}
Description: Sending a value outside the defined enum set, such as status=INVALID_VALUE or reportType=UNKNOWN, causes a Spring type conversion failure. Providing dateFrom or dateTo in a format other than YYYY-MM-DD also triggers this error.
400 - Bad Request: Missing Required companyId
Returned when the mandatory companyId query parameter is absent.
{
"error": "BAD_REQUEST",
"message": "Required request parameter 'companyId' for method parameter type UUID is not present",
"code": "MISSING_PARAMETER"
}
Description: companyId is the only mandatory parameter for this endpoint and must be in UUID format. A missing value or an improperly formatted UUID, such as companyId=abc123, triggers this error.
401 - Unauthorized
Returned when the JWT token in the R-Auth header cannot be verified.
{
"error": "UNAUTHORIZED",
"message": "Invalid or expired authentication token",
"code": "AUTH_TOKEN_INVALID"
}
Description: The token has expired, its signature is invalid, or the header is missing entirely. Token TTL is 50 minutes.
403 - Forbidden
Returned when the authenticated user does not have access rights to reports belonging to the specified companyId.
{
"error": "FORBIDDEN",
"message": "Access denied to company reports",
"code": "ACCESS_DENIED"
}
Description: The authorization layer rejects the request when a user attempts to query reports using a companyId that does not belong to them.
500 - Internal Server Error
Returned when an unexpected error occurs during the database query or data transformation.
{
"error": "INTERNAL_SERVER_ERROR",
"message": "An unexpected error occurred while processing your request",
"code": "GENERAL_ERROR"
}
Description: Thrown when an unexpected error occurs in the JPA specification filter or the toResponse() data conversion method.