Skip to main content

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

PropertyValue
Endpoint/auth/login
MethodPOST
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationNone (Initial access)

Request Body (JSON)

The following fields are used to define login criteria:

FieldTypeDescription
apiKeyStringA 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”)
emailStringThe 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:

FieldTypeDescription
jwtThe secure session token that must be used as a 'R-Auth' API Key in all subsequent API calls.
expirationDateDateTimeIndicates 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

PropertyValue
KeyEnter R-Auth in the Key field.
Value{{apiKey}} or {{jwt}} (Copy the jwt string returned from the login endpoint.)
Header SettingNavigate 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

Click to enlarge

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

PropertyValue
URL/auth/login
MethodPOST
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationNot 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

FieldTypeRequiredDescription
emailStringOptionalUser's registered email address
apiKeyStringYesObtained 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

FieldTypeDescription
idStringUser unique identifier
superAdminBooleanWhether user has super admin privileges
companiesArray<AuthorizedCompany>List of companies user is authorized to access
jwtStringJWT access token. Used in R-Auth header for API requests
expirationDateDateTimeJWT token expiration date
refreshTokenStringRefresh token for obtaining new access tokens
refreshTokenExpirationDateTimeRefresh token expiration date
userObjectUser detail information
mfaEnabledBooleanWhether multi factor authentication is enabled
mfaTypeEnumMFA type (GOOGLE, WHATSAPP)
secretImageUriStringGoogle Authenticator QR code URI
lastCompanyIdStringLast selected company ID
requiresRecaptchaV2BooleanWhether reCAPTCHA v2 verification is required
messageStringStatus message (e.g., "MFA required")
activeBooleanWhether user account is active
isAppLoginBooleanWhether this is a mobile app login

Parameter Values Reference Table

currentCountry Values (Sample List)

ValueDescription
DEGermany
ATAustria
RORomania
KZKazakhstan
TRTurkey
FIFinland
FRFrance
ITItaly
NLNetherlands
ESSpain
SESweden
PLPoland
BEBelgium
DKDenmark
NONorway
MYMalaysia
SGSingapore
AUAustralia
NZNew Zealand
JPJapan
EGEgypt
RSSerbia
GLOBALGlobal (default)

Company Information Fields

FieldTypeDescription
idStringCompany unique identifier
nameStringCompany name
taxNumberStringTax number
vatNumberStringVAT number
emailStringCompany email address
websiteStringCompany website
addressStringAddress
cityStringCity
stateStringState or Region
countryEnumCountry code
postalCodeStringPostal code
phoneNumberStringPhone number
faxNumberStringFax number
creditIntegerAvailable credit
userCountIntegerTotal user count
portalTypeEnumPortal type
mailLanguageEnumEmail language
currencyCodeStringCurrency code
sftpBooleanWhether SFTP integration is active
isSubCompanyBooleanWhether it's a sub company
featureAllowedBooleanWhether feature access is granted
participantsArrayPeppol participant information

User Information Fields

FieldTypeDescription
idStringUser unique identifier
emailStringUser email address
firstNameStringUser first name
lastNameStringUser last name
phoneNumberStringUser phone number
photoUrlStringUser photo URL
mailLangEnumUser email language
isSuperAdminBooleanWhether user has super admin privileges
lastLoginTimeDateTimeLast login time
featureAllowedBooleanWhether feature access is granted

Enum Values Reference Table

mfaType Values

ValueDescription
GOOGLEGoogle Authenticator verification
WHATSAPPWhatsApp verification

portalType Values

ValueDescription
DEFAULTDefault portal
RECHNUNGGermany main portal
KZKazakhstan portal
RORomania portal
AUAustralia portal
ATAustria portal
BEBelgium portal
DKDenmark portal
EGEgypt portal
FIFinland portal
FRFrance portal
ITItaly portal
MYMalaysia portal
NLNetherlands portal
NONorway portal
PLPoland portal
RSSerbia portal
SESweden portal
SGSingapore portal

mailLanguage Values

ValueDescription
DEGerman
ENEnglish
TRTurkish
RORomanian
PLPolish
FRFrench
ITItalian
ESSpanish
NLDutch

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

PropertyValue
URL/invoice/document-process/search
MethodPOST
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-Auth header (JWT token)
Required AuthorityADMIN, 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

FieldTypeRequiredDescription
companyIdUUIDYesUnique identifier of the company to search
directionString (Enum)NoDocument direction filter (INCOMING or OUTGOING)
sourceString (Enum)NoSource system filter
filenameStringNoExact match filter by filename
statusString (Enum)NoDocument processing status filter
createdAtObject (DateRange)NoCreation date range filter
createdAt.fromString (LocalDate)NoStart date (inclusive). Format: yyyy-MM-dd. Must be past or present
createdAt.toString (LocalDate)NoEnd date (inclusive). Format: yyyy-MM-dd. Must be past or present

Query Parameters (Pagination)

FieldTypeDefaultDescription
pageInteger0Page number (0 indexed)
sizeInteger20Number of records per page (max 100)
sortStringcreatedAt,descSort field and direction. Format: field,asc|desc

Enum Value Reference

direction Values (Document Direction)

ValueDescription
INCOMINGIncoming document
OUTGOINGOutgoing document

status Values (Processing Status)

ValueDescription
PENDINGQueued and waiting for processing
PROCESSINGCurrently being processed
COMPLETEDSuccessfully completed
FAILEDProcessing failed (retriable)
SENDING_FAILEDFailed at the sending stage
PERMANENT_FAILEDPermanently failed (will not be retried)

source Values (Source and Target System)

ValueDescription
ERPERP integration
PORTALWeb portal
PORTAL_OCRPortal upload via OCR
EMAIL_OCROCR via email
EMAILEmail
PEPPOLPeppol network
SFTPSFTP connection
KSEFPoland KSeF system
ANAFRomania ANAF system
LHDNMMalaysia LHDNM system
NEMHANDELDenmark NemHandel
RS_APISerbia API
ETAEgypt ETA system
ERACUNeRacun system
HARVESTHarvest integration
SHOPIFYShopify integration
AMAZON_SPAmazon SP API
EBAYeBay integration
HUBSPOTHubSpot integration
LAZADALazada integration
STRIPEStripe integration
SERVICEInternal service

documentType Values (Document Format)

ValueDescription
PEPPOL_BISPeppol BIS 3.0
XRECHNUNG_CIIXRechnung (CII)
ZUGFERDZUGFeRD
FACTUR_XFactur X
CIICross Industry Invoice
CIDCID format
RO_EFACTURARomania e Factura
MY_INVOISMalaysia MyInvois
MY_PINTMalaysia PINT
DK_OIOUBLDenmark OIOUBL
EG_INVOICEEgypt invoice
HR_INVOICECroatia invoice
UAE_PINTUAE PINT
KZ_ESF_V2Kazakhstan ESF v2
KSEFPoland KSeF
KSEF_OFFLINEPoland KSeF (offline)

waybillType Values (Waybill Type)

ValueDescription
RS_WAYBILL_DESPATCHSerbia despatch waybill
RS_WAYBILL_RECEIPTSerbia receipt waybill
RS_APPLICATION_RESPONSESerbia application response
RO_ETRANSPORTRomania 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

FieldTypeDescription
contentArray<Object>Page content (document processing records)
content[].trackingIdUUIDProcessing tracking identifier
content[].companyIdUUIDCompany identifier
content[].directionString (Enum)Document direction (INCOMING / OUTGOING)
content[].documentTypeString (Enum)Document format (see documentType enum table)
content[].waybillTypeString (Enum) | nullWaybill type (only for waybill documents)
content[].sourceString (Enum)Source system of the document
content[].targetString (Enum) | nullTarget system for the document
content[].statusString (Enum)Current processing status
content[].filenameStringOriginal filename
content[].invoiceNumberString | nullInvoice number
content[].documentIdUUID | nullAssociated document identifier
content[].sendingResultString | nullSending result message
content[].errorTypeString (Enum) | nullError type code (on failed processes)
content[].errorsObject | nullError details (validation errors, message list, or text)
content[].additionalDataObject | nullCountry or document type specific metadata
content[].createdAtString (DateTime)Creation timestamp. Format: yyyy-MM-ddTHH:mm:ss
content[].statusUpdatedAtString (DateTime)Last status update timestamp
content[].completedAtString (DateTime) | nullCompletion timestamp (only when COMPLETED)
totalElementsLongTotal number of matching records
totalPagesIntegerTotal number of pages
numberIntegerCurrent page number (0-indexed)
sizeIntegerNumber 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)

FieldTypeDescriptionInclusion Condition
errorMessageStringHuman readable error descriptionAlways
errorTypeStringMachine readable error code (ErrorType enum name)Always
errorTitleString (HttpStatus)HTTP status description (BAD_REQUEST, UNAUTHORIZED, etc.)Always
errorIdStringCorrelation ID (for log tracing)If present in ThreadContext
statusIntegerHTTP status code (numeric)Always
timestampString (DateTime)Timestamp when the error occurredBy RestExceptionHandler
pathStringURI of the requestBy RestExceptionHandler
dataStringAdditional data informationIf present (@JsonInclude NON_NULL)
detailsMap<String, Object>Additional detail informationIf present (@JsonInclude NON_NULL)
validationErrorsArray<ValidationError>Field level validation errorsIf 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

PropertyValue
URL/invoice/send-document-async
MethodPOST
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationJWT 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

FieldTypeRequiredDescription
compIdString (UUID)Conditional*Company unique identifier. Required if apiKey is not provided.
apiKeyStringConditional*API key. Required if compId is not provided.
base64DocumentStringConditional**Base64-encoded XML document. Required if base64Pdf is not provided.
base64PdfStringConditional**Base64-encoded PDF document. Required if base64Document is not provided.
invoiceTypeEnumConditional***Invoice format type. Required if waybillType is not provided.
waybillTypeEnumConditional***Waybill format type. Required if invoiceType is not provided.
businessTypeEnumNoBusiness model type (B2B, B2C, B2G).
invoiceSourceEnumNoDocument source.
receiverEmailsArray<String>NoList of recipient email addresses.
mailTemplateIdStringNoEmail 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

ValueDescription
B2BBusiness to Business
B2CBusiness to Consumer
B2GBusiness to Government

invoiceSource Values

ValueDescription
PORTALSubmission via web portal
PORTAL_OCRPortal with OCR processing
EMAILVia email
EMAIL_OCREmail with OCR processing
ERPERP system integration
PEPPOLVia Peppol network
LHDNMMalaysia LHDNM system
NEMHANDELDenmark NemHandel
SERVICEService integration
HARVESTHarvest integration
SHOPIFYShopify integration
AMAZON_SPAmazon SP-API integration
EBAYeBay integration
HUBSPOTHubSpot integration
ANAFRomania ANAF system
LAZADALazada integration
SFTPVia SFTP
KSEFPoland KSeF system
RS_APISerbia API
ETAEgypt ETA system
ERACUNIndonesia e-Racun
STRIPEStripe integration

invoiceType Values

ValueGroupDescription
PEPPOL_BISXRECHNUNGPeppol BIS 3.0 format
XRECHNUNGXRECHNUNGGerman XRechnung format
RO_EFACTURAXRECHNUNGRomania e-Factura format
ZUGFERDZUGFERDZUGFeRD format (PDF/A-3 with XML)
FACTUR_XZUGFERDFactur-X format (France)
XRECHNUNG_CIIZUGFERDXRechnung CII profile
CIIZUGFERDCross Industry Invoice format
CIDZUGFERDCID format
PDFZUGFERDPDF format
MY_INVOISCountry-SpecificMalaysia MyInvois format
MY_PINTCountry-SpecificMalaysia PINT format
DK_OIOUBLCountry-SpecificDenmark OIOUBL format
EG_INVOICECountry-SpecificEgypt e-Invoice format
HR_INVOICECountry-SpecificCroatia e-Invoice format
UAE_PINTCountry-SpecificUAE PINT format
KZ_ESF_V2KazakhstanKazakhstan ESF v2
KSEFPolandPoland KSeF format
KSEF_OFFLINEPolandPoland KSeF offline

waybillType Values

ValueDescription
RS_WAYBILL_DESPATCHSerbia despatch waybill
RS_WAYBILL_RECEIPTSerbia receipt waybill
RS_APPLICATION_RESPONSESerbia application response
RO_ETRANSPORTRomania e-Transport

Responses

200 - Successful Response

{
"trackingId": "a1b2c3d4-e5f6-7890-abcd-...",
"status": "PENDING",
"message": "Document queued for processing"
}

Response Fields

FieldTypeDescription
trackingIdUUIDUnique process tracking identifier. This ID can be used to query the processing status.
statusEnumCurrent status of the process.
messageStringDescriptive message about the status.

status Values

ValueDescription
PENDINGProcess queued, not yet started
PROCESSINGProcess in progress
COMPLETEDProcess completed successfully
FAILEDProcess failed
SENDING_FAILEDSending failed
PERMANENT_FAILEDPermanent 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

PropertyValue
URL/invoice/send-document-async-json
MethodPOST
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-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 NameTypeRequiredDescription
apiKeystringConditionalAPI key used to identify the company. Required if ublDto.CompanyId is not provided.
ublDtoobject (UBLDto)YesUBL 2.1 compliant invoice data structure containing all invoice details.
ublDto — Document Object
Field NameTypeRequiredDescription
ublDto.Typestring (enum)OptionalDocument format type. E.g.: PEPPOL_BIS, XRECHNUNG, ZUGFERD. See Parameter Values Reference table for full list.
ublDto.IsPeppolParticipantbooleanOptionalIndicates whether the recipient is registered on the Peppol network. If true, the document is routed via Peppol.
ublDto.CompanyIdstring (UUID)ConditionalUUID of the sending company. Required if apiKey is not provided.
ublDto.ProfileTypestring (enum)OptionalZUGFeRD / Factur-X profile type. Default: EN16931.
ublDto.CustomizationID.ValuestringOptionalInvoice customization identifier (urn value). Specifies PEPPOL / EN16931 compliance.
ublDto.ID.ValuestringOptionalInvoice number / unique document identifier.
ublDto.IssueDate.Valuestring (ISO 8601)OptionalInvoice issue date. Format: YYYY-MM-DD.
ublDto.DueDate.Valuestring (ISO 8601)OptionalInvoice due date. Format: YYYY-MM-DD.
ublDto.InvoiceTypeCode.ValuestringOptionalUN/CEFACT invoice type code. E.g.: 380 = Commercial Invoice, 381 = Credit Note, 384 = Corrected Invoice.
ublDto.Note[].ValuestringOptionalFree-text note attached to the invoice.
ublDto.DocumentCurrencyCode.ValuestringOptionalInvoice currency code (ISO 4217). E.g.: EUR, USD, GBP.
ublDto.BuyerReference.ValuestringOptionalBuyer reference number (Buyer Reference / Leitweg-ID).
ublDto.OrderReference.ID.ValuestringOptionalPurchase order number.
ublDto.OrderReference.SalesOrderID.ValuestringOptionalSales order number.
ublDto.AccountingSupplierPartyobjectOptionalSupplier / seller information. The Party object contains EndpointID (Peppol ID), PartyName, PostalAddress, PartyTaxScheme, PartyLegalEntity, and Contact sub-objects.
ublDto.AccountingSupplierParty.Party.EndpointID.ValuestringOptionalSupplier's Peppol Endpoint ID value.
ublDto.AccountingSupplierParty.Party.EndpointID.schemeIDstringOptionalEndpoint ID scheme code. E.g.: 9930 = German Tax No, 0088 = GLN.
ublDto.AccountingCustomerPartyobjectOptionalCustomer / buyer information. The Party object contains EndpointID, PartyName, PostalAddress, PartyTaxScheme, PartyLegalEntity, and Contact sub-objects.
ublDto.Delivery[].ActualDeliveryDate.Valuestring (ISO 8601)OptionalActual delivery date. Format: YYYY-MM-DD.
ublDto.Delivery[].DeliveryLocation.AddressobjectOptionalDelivery address. Contains StreetName, CityName, PostalZone, and Country sub-fields.
ublDto.PaymentMeans[].PaymentMeansCode.ValuestringOptionalPayment method code. E.g.: 58 = SEPA Credit Transfer, 30 = Credit Transfer, 49 = Direct Debit.
ublDto.PaymentMeans[].PayeeFinancialAccount.ID.ValuestringOptionalPayee bank account IBAN number.
ublDto.PaymentMeans[].PayeeFinancialAccount.Name.ValuestringOptionalBank account holder name.
ublDto.PaymentTerms[].Note[].ValuestringOptionalFree-text description of payment terms.
ublDto.TaxTotal[].TaxAmount.ValuenumberOptionalTotal tax amount.
ublDto.TaxTotal[].TaxAmount.currencyIDstringOptionalCurrency code for the tax amount (ISO 4217).
ublDto.TaxTotal[].TaxSubtotal[].TaxableAmount.ValuenumberOptionalTaxable base amount.
ublDto.TaxTotal[].TaxSubtotal[].TaxCategory.ID.ValuestringOptionalTax category code. E.g.: S = Standard, Z = Zero Rated, E = Exempt, AE = Reverse Charge.
ublDto.TaxTotal[].TaxSubtotal[].TaxCategory.Percent.ValuenumberOptionalTax rate percentage. E.g.: 19, 7, 10.
ublDto.LegalMonetaryTotal.LineExtensionAmount.ValuenumberOptionalSum of invoice line net amounts (excluding tax).
ublDto.LegalMonetaryTotal.TaxExclusiveAmount.ValuenumberOptionalTotal amount excluding VAT.
ublDto.LegalMonetaryTotal.TaxInclusiveAmount.ValuenumberOptionalTotal amount including VAT.
ublDto.LegalMonetaryTotal.PayableAmount.ValuenumberOptionalNet payable amount.
ublDto.InvoiceLine[].ID.ValuestringOptionalInvoice line sequence number.
ublDto.InvoiceLine[].InvoicedQuantity.ValuenumberOptionalInvoiced quantity.
ublDto.InvoiceLine[].InvoicedQuantity.unitCodestringOptionalUnit of measure code (UN/ECE Rec. 20). E.g.: MTQ = Cubic Metre, C62 = Each, KGM = Kilogram.
ublDto.InvoiceLine[].LineExtensionAmount.ValuenumberOptionalInvoice line net amount (excluding tax).
ublDto.InvoiceLine[].Item.Name.ValuestringOptionalProduct / service name.
ublDto.InvoiceLine[].Item.SellersItemIdentification.ID.ValuestringOptionalSeller's item/product code.
ublDto.InvoiceLine[].Price.PriceAmount.ValuenumberOptionalUnit price.
ublDto.InvoiceLine[].Price.BaseQuantity.ValuenumberOptionalBase quantity the price applies to. Typically 1.
receiverEmailsarray (string)OptionalRecipient email addresses for sending the invoice via email after processing.
mailTemplateIdstringOptionalCustom mail template ID to be used for email delivery.
businessTypestring (enum)OptionalBusiness 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

FieldTypeDescription
trackingIdstring (UUID)Document processing tracking ID. Used in the /invoice/document-status/{trackingId} endpoint.
statusstring (enum)Immediate processing status of the document. Returns PENDING initially.
messagestringInformational message about the process initiation.

Parameter Value Reference

Document Format Type (ublDto.Type)

ValueDescription
PEPPOL_BISPEPPOL BIS Billing 3.0 format (UBL-based)
XRECHNUNGGermany XRechnung format (UBL-based)
ZUGFERDZUGFeRD format (PDF/A-3 + embedded XML)
FACTUR_XFrance Factur-X format (PDF/A-3 + embedded XML)
XRECHNUNG_CIIGermany XRechnung CII format
CIIUN/CEFACT Cross Industry Invoice format
CIDCross Industry Document format
MY_INVOISMalaysia MyInvois format
MY_PINTMalaysia PINT format
DK_OIOUBLDenmark OIOUBL format
RO_EFACTURARomania e-Invoice format
UAE_PINTUAE PINT format
HR_INVOICECroatia invoice format
EG_INVOICEEgypt invoice format
KSEFPoland KSeF format

Profile Type (ublDto.ProfileType)

ValueDescription
EN16931EN 16931 compliant profile (default)
EXTENDEDExtended profile
BASICBasic profile

Business Model Type (businessType)

ValueDescription
B2BBusiness to Business
B2CBusiness to Consumer
B2GBusiness 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

PropertyValue
URL/invoice/document-status/{trackingId}
MethodGET
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-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

FieldTypeRequiredDescription
trackingIdUUIDYesThe 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

FieldTypeDescription
trackingIdUUIDUnique tracking identifier for the document processing
companyIdUUIDUnique identifier of the company the document belongs to
directionString (Enum)Document direction: INCOMING or OUTGOING
documentTypeString (Enum)Document format (e.g., XRECHNUNG, UBL, ZUGFERD)
waybillTypeString (Enum)Waybill type. Only populated for waybill operations
sourceString (Enum)Source platform the document was submitted from (e.g., ERP, PORTAL)
targetString (Enum) | nullTarget platform for the document
statusString (Enum)Current processing status: PENDING, PROCESSING, COMPLETED, FAILED, SENDING_FAILED, PERMANENT_FAILED
filenameStringName of the processed file
invoiceNumberString | nullInvoice number assigned to the document. Populated when processing completes
documentIdUUID | nullUnique system identifier of the created document. Populated when processing completes
sendingResultString | nullSending result (e.g., SUCCESS, SENT_TO_PEPPOL). Populated when processing completes
errorTypeString (Enum) | nullError category when an error occurs. Null for successful operations
errorsObject | nullError details. Variable type: can be List<ValidationError>, List<String>, or String
additionalDataObjectCountry specific additional metadata. Structure varies by country/document type (e.g., Poland KSeF: ksefNumber, Romania: submissionId)
createdAtDateTimeTimestamp when the processing record was created (ISO 8601)
statusUpdatedAtDateTimeTimestamp when the status was last updated (ISO 8601)
completedAtDateTime | nullTimestamp when processing completed. Null while processing is ongoing

Parameter Value Reference

DocumentProcessStatus — Possible Status Values

ValueDescription
PENDINGDocument is queued, processing has not started yet
PROCESSINGDocument is actively being processed (conversion, validation, sending, etc.)
COMPLETEDDocument processing completed successfully
FAILEDAn error occurred during document processing (may be retried)
SENDING_FAILEDDocument was created but failed during the sending phase
PERMANENT_FAILEDDocument processing permanently failed (will not be retried)

DocumentType — Document Direction

ValueDescription
INCOMINGIncoming document
OUTGOINGOutgoing document

DataType — Document Format

ValueDescription
PEPPOL_BISPeppol BIS 3.0 UBL format
XRECHNUNGXRechnung (Germany) UBL format
RO_EFACTURARomania eFactura format
MY_INVOISMalaysia MyInvois format
MY_PINTMalaysia PINT format
DK_OIOUBLDenmark OIOUBL format
EG_INVOICEEgypt e-Invoice format
HR_INVOICECroatia e-Invoice format
UAE_PINTUAE PINT format
ZUGFERDZUGFeRD format
FACTUR_XFactur-X (France) format
XRECHNUNG_CIIXRechnung CII format
CIIUN/CEFACT CII format
PDFUnstructured PDF (paper invoices, images, etc.)
KSEFPoland KSeF format
KSEF_OFFLINEPoland KSeF Offline format
KZ_ESF_V2Kazakhstan ESF v2 format

InvoiceSource — Document Source

ValueDescription
ERPSubmitted via ERP integration
PORTALSubmitted via web portal
PEPPOLReceived via Peppol network
EMAILReceived via email
SFTPTransferred via SFTP
KSEFVia KSeF system
ANAFVia ANAF system (Romania)
ERACUNVia eRacun system (Croatia)
OthersPORTAL_OCR, EMAIL_OCR, LHDNM, NEMHANDEL, SERVICE, HARVEST, SHOPIFY, AMAZON_SP, EBAY, HUBSPOT, LAZADA, RS_API, ETA, STRIPE

WaybillDataType — Waybill Type

ValueDescription
RS_WAYBILL_DESPATCHSerbia despatch waybill
RS_WAYBILL_RECEIPTSerbia receipt waybill
RS_APPLICATION_RESPONSESerbia application response
RO_ETRANSPORTRomania eTransport waybill

ErrorType — Error Types Specific to This Endpoint

ValueMessage
INVOICE_PROCESS_NOT_FOUNDTracking ID not found
VALIDATION_FAILEDValidation failed!
INVOICE_NULL_COULD_NOT_SAVEInvoice is NULL and/or could not be saved!
ZUGFERD_VALIDATION_ERRORZUGFeRD validation error
INVOICE_CREATION_FAILEDInvoice creation failed!
INVOICE_SENDING_FAILEDInvoice 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"
}
DetailDescription
HTTP Status401 Unauthorized
TriggerJWT token is missing, malformed, expired, or signature verification failed
ResolutionSend 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)

DetailDescription
HTTP Status404 Not Found
Response Bodynull (body is empty)
TriggerNo DocumentProcessEntity record matches the given trackingId in the database
Internal Error TypeINVOICE_PROCESS_NOT_FOUND — "Tracking ID not found"
ResolutionVerify 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)

DetailDescription
HTTP Status500 Internal Server Error
Response Bodynull (body is empty)
TriggerDatabase connection failure, entity conversion error, or other unexpected runtime exceptions
ResolutionCheck 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

PropertyValue
URL/invoice/get-document//{documentTypes}
MethodGET
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-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 NameTypeRequiredDescription
documentIdString (UUID)YesUnique identifier of the document. Must be in UUID v4 format. Example: 550e8400-e29b-41d4-a716-...
documentTypesString (Enum)YesRequested document format type. Multiple types can be separated by hyphen -. Example: PDF, XML

Header Parameters

Field NameTypeRequiredDescription
R-AuthString (JWT)YesAuthentication token. JWT signed with HS512 algorithm.
AcceptStringNoAccepted response media type. Default: /

documentTypes Parameter Values

ValueFormat TypeDescription
PDFFormatType.PDFReturns Base64-encoded PDF representation of the invoice
XMLFormatType.XMLReturns Base64-encoded UBL XML content of the invoice
JSONFormatType.JSONReturns Base64-encoded UBL DTO JSON content of the invoice
PDF-XMLMultiple formatsMultiple formats can be requested simultaneously using hyphen separator
XML-PDF-JSONMultiple formatsAll 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 NameTypeDescription
documentsList<Document>List of documents in requested formats. Contains one Document object per format.
documents[].file_typeString (Enum)Document format type. Possible values: PDF, XML, JSON
documents[].dataString (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"
}

FieldDescription
errorMessageSpecifies the unsupported document type and which type was invalid.
errorTypeINVALID_ARGUMENT An invalid parameter was provided.
status400

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"
}

FieldDescription
errorMessageIndicates the invoice has not been processed by MelaAI yet and should be retried later.
errorTypeINVALID_ARGUMENT The invoice is not in a processable state currently.
status400

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"
}

FieldDescription
errorMessageIndicates that the authentication process must be completed.
errorTypeAUTHENTICATION_REQUIRED Token is missing, expired, or invalid.
status401

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"
}

FieldDescription
errorMessageReturns a not found message along with the document UUID.
errorTypeNOT_FOUND_INVOICE No matching invoice record exists in the database.
status404

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"
}
FieldDescription
errorMessageGeneric server error message.
errorTypeSERVER_ERROR An unexpected error occurred.
status500

Common Error Response Field Descriptions

Field NameTypeDescription
errorMessageStringHuman readable description of the error
errorTypeStringProgrammatic classification code of the error
errorTitleString (HttpStatus)Text representation of the HTTP status code
errorIdStringRequest correlation ID (for log tracking)
statusIntegerHTTP status code (numeric)
timestampString (ISO 8601)Timestamp when the error occurred
pathStringEndpoint path where the error occurred
detailsMap<String, Object>Additional error details (if available)
validationErrorsList<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

PropertyValue
URL/invoice/search-documents
MethodPOST
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-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

FieldTypeRequiredDescription
companyIdUUIDYesUnique identifier of the company to search documents for
documentTypeString (Enum)NoDocument direction filter. Used to filter incoming or outgoing documents
statusString (Enum)NoInvoice status filter. Returns invoices in a specific status
typeString (Enum)NoDocument format type filter. Filters by invoice format
startDateString (ISO Date)NoSearch start date. Format: YYYY-MM-DD
endDateString (ISO Date)NoSearch end date. Format: YYYY-MM-DD
tinStringNoTax Identification Number filter
uitStringNoUIT identifier filter
referenceDocumentStringNoSearch by reference document number
pageIntegerNoPage number (0-based). Default: 0
sizeIntegerNoNumber of records per page. Default: 50

Parameter Values

documentType Values

ValueDescription
INCOMINGIncoming documents (invoices sent by suppliers)
OUTGOINGOutgoing documents (invoices sent to customers)

type Values

ValueGroupDescription
MY_INVOISMY_INVOISMalaysian MyInvois format
MY_PINTMY_PINTMalaysian PINT format
DK_OIOUBLDK_OIOUBLDanish OIOUBL format
EG_INVOICEEG_INVOICEEgyptian e-Invoice format
HR_INVOICEHR_INVOICECroatian eRacun format
UAE_PINTUAE_PINTUAE PINT format
ZUGFERDZUGFERDZUGFeRD format (PDF + embedded XML)
FACTUR_XZUGFERDFrench Factur-X format
XRECHNUNG_CIIZUGFERDXRechnung CII format
CIIZUGFERDUN/CEFACT CII format
CIDZUGFERDCID format
PDFZUGFERDUnstructured invoices (paper, images, etc.)
KSEFKSEFPolish KSeF format
KSEF_OFFLINEKSEF_OFFLINEPolish KSeF offline format
KZ_ESF_V2KZ_ESF_V2Kazakhstan 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

CategoryValueDescription
GeneralCREATEDInvoice created
PENDINGAwaiting processing
CANCELEDCancelled
DELETEDDeleted
SENT_VIA_EMAILSent via email
SavedSAVED_AS_UBLSaved as UBL
SAVED_AS_ZUGFERDSaved as ZUGFeRD
SAVED_AS_FACTUR_XSaved as Factur-X
SAVED_AS_CIISaved as CII
SAVED_AS_CIDSaved as CID
SAVED_AS_KSEFSaved as KSeF
SAVED_AS_PDFSaved as PDF
OCROCR_WAITINGOCR processing pending
OCR_PARSEDOCR completed successfully
OCR_FAILEDOCR processing failed
OCR_PARSED_PENDING_PAYMENTOCR completed, payment pending
OCR_WAITING_TOKENOCR waiting for token
COMPLETED_BY_MELA_AICompleted by Mela AI
PeppolSENT_TO_PEPPOLSent to Peppol network
SENT_TO_ACCESS_POINTSent to Access Point
SUCCESSSuccessfully delivered
TRANSPORT_ERRORTransport error
INVALID_PARAMETERSInvalid parameters
NO_SIGNAL_MESSAGE_RECEIVEDNo signal message received
AS4_ERROR_MESSAGE_RECEIVEDAS4 error message received
INVALID_SIGNAL_MESSAGE_RECEIVEDInvalid signal message received
INCOMING_RESPONSE_ACKNOWLEDGEDIncoming response acknowledged (MLR/MLS)
INCOMING_RESPONSE_REJECTEDIncoming response rejected
INCOMING_RESPONSE_ACCEPTEDIncoming response accepted
OUTGOING_RESPONSE_ACKNOWLEDGEDOutgoing response acknowledged (MLR/MLS)
OUTGOING_RESPONSE_REJECTEDOutgoing response rejected
OUTGOING_RESPONSE_ACCEPTEDOutgoing response accepted
Romania (ANAF)SENT_TO_ANAFSent to ANAF
PORTAL_OKAYPortal approved
PORTAL_ERRORPortal error
PORTAL_ERRORSPortal multiple errors
PORTAL_SYSTEM_ERRORPortal system error
PORTAL_IN_PROCESSPortal processing
Poland (KSeF)KSEF_PENDINGKSeF processing
KSEF_ACCEPTEDKSeF accepted
KSEF_REJECTEDKSeF rejected
KSEF_DUPLICATEKSeF duplicate record
Malaysia (LHDNM)LHDNM_SUBMITTEDSubmitted to LHDNM
LHDNM_VALIDLHDNM valid
LHDNM_INVALIDLHDNM invalid
LHDNM_CANCELLEDLHDNM cancelled
LHDNM_REJECT_REQUESTEDLHDNM rejection requested
LHDNM_REJECTEDLHDNM rejected
LHDNM_ERRORLHDNM error
Egypt (ETA)ETA_SUBMITTEDSubmitted to ETA
Croatia (eRacun)ERACUN_ERROReRacun error
ERACUN_PENDINGeRacun pending
ERACUN_WAITING_TO_SENDeRacun waiting to send
ERACUN_SENTeRacun sent
ERACUN_RECEIVEDeRacun received
ERACUN_APPROVEDeRacun approved
ERACUN_REJECTEDeRacun rejected
ERACUN_FULLY_PAIDeRacun fully paid
ERACUN_PARTIALLY_PAIDeRacun partially paid
ERACUN_DELIVERY_FAILEDeRacun delivery failed
DenmarkSENT_TO_NEMHANDELSent to Nemhandel
OtherCREDIT_BLOCKEDCredit 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

FieldTypeDescription
totalCountLongTotal number of documents matching the filters
netTotalDoubleTax-exclusive total amount (excludes CREDIT_BLOCKED)
totalDoubleTax-inclusive total amount (excludes CREDIT_BLOCKED)
invoiceListArray<Invoice>List of invoice objects

Invoice Object Fields

FieldTypeDescription
idString (UUID)Unique identifier of the invoice
companyIdString (UUID)Company ID the invoice belongs to
userIdString (UUID)User ID who created the invoice
customerNameStringCustomer (buyer) name
supplierNameStringSupplier (seller) name
supplierIdStringSupplier ID
supplierVatStringSupplier VAT number
statusString (Enum)Current invoice status
invoiceNumberStringInvoice number
taxExclusiveAmountDoubleTax-exclusive amount
taxInclusiveAmountDoubleTax-inclusive amount
lineExtensionAmountDoubleLine items total amount
payableAmountDoubleAmount payable
allowanceTotalAmountDoubleTotal allowance/discount amount
currencyStringCurrency code (ISO 4217: EUR, USD, TRY, etc.)
createdTimeString (DateTime)Creation timestamp (UTC)
localCreatedTimeString (DateTime)Creation timestamp (local time)
issueDateString (Date)Invoice issue date
deliveryDateString (Date)Delivery date
dueDateString (Date)Due date
supplierCountryCodeStringSupplier country code (ISO 3166-1 alpha-2)
supplierEndpointStringSupplier Peppol endpoint
customerIdStringCustomer ID
customerVatStringCustomer VAT number
customerEndpointStringCustomer Peppol endpoint
customerCountryCodeStringCustomer country code
typeCodeStringInvoice type code (e.g., 380=Invoice, 381=Credit Note)
documentTypeString (Enum)Document direction: INCOMING or OUTGOING
errorMessageStringError message (if any)
lastUpdatedTimeString (DateTime)Last update timestamp (UTC)
localLastUpdatedTimeString (DateTime)Last update timestamp (local time)
typeString (Enum)Document format type (DataType)
sourceString (Enum)Invoice source (PORTAL, ERP, PEPPOL, EMAIL, etc.)
sendViaPeppolBooleanWhether sent via Peppol
statusTimeString (DateTime)Status change timestamp (UTC)
localStatusTimeString (DateTime)Status change timestamp (local time)
fileNameStringFile name
ocrParserString (Enum)OCR parser type
paymentDetailsObjectPayment details (null for certain statuses)
profileTypeString (Enum)ZUGFeRD profile type: BASIC, EN16931, EXTENDED
isActiveBooleanWhether the invoice is active
countrySpecificDataObjectCountry-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

FieldTypeDescription
errorMessageStringHuman-readable error description
errorTypeStringError type code
errorTitleStringHTTP status name
errorIdStringCorrelation ID (for log tracing)
statusIntegerHTTP status code
timestampString (DateTime)Error occurrence time
pathStringRequest 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

FieldTypeDescription
errorMessageStringAuthorization error description
errorTypeStringFixed value: NOT_AUTHORITY
errorTitleStringHTTP status name: UNAUTHORIZED
errorIdStringCorrelation ID
statusInteger401
timestampString (DateTime)Error occurrence time
pathStringRequest 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

FieldTypeDescription
errorMessageStringGeneral error message
errorTypeStringRUNTIME_ERROR, IO_ERROR, or SERVER_ERROR
errorTitleStringHTTP status name: INTERNAL_SERVER_ERROR
errorIdStringCorrelation ID (for log tracing)
statusInteger500
timestampString (DateTime)Error occurrence time
pathStringRequest 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

PropertyValue
URLPOST /invoice/merge-zugferd-pdf-xml
MethodPOST
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthenticationR-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 NameTypeRequiredDescription
base64PdfStringYesBase64-encoded PDF document to be merged. Must contain a valid PDF file.
base64XmlStringYesBase64-encoded ZUGFeRD/Factur-X XML invoice data to be merged. Must conform to the ZUGFeRD schema (EN 16931).

Parameter Value Constraints

ParameterAccepted ValueConstraintSource
base64PdfValid Base64 StringMust be a Base64 encoding of a valid PDF document. Invalid Base64 or corrupted PDF returns an error.ErpController.java
base64XmlValid Base64 StringMust be XML conforming to ZUGFeRD EN 16931:2017 schema. Validated by Mustang ZUGFeRDValidator.ValidationService.java
file_type (response)PDF, XML, SIGN, JSON, GPDF, HTMLThis endpoint always returns PDF.FormatType.java

Responses

200 - Successful Response

{
"file_type": "PDF",
"data": "<BASE64_ENCODED_MERGED_PDF>"
}

Successful Response Field Descriptions

Field NameTypeDescription
file_typeStringFormat of the returned file. Always PDF for this endpoint.
dataStringBase64-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 NameTypeDescription
errorMessageStringDetailed description of the error
errorTypeStringError classification. API_ERROR in this case
errorTitleStringHTTP status code name: BAD_REQUEST
statusIntegerHTTP status code: 400
errorIdStringRequest tracking identifier (Correlation ID)
timestampString (ISO 8601)Time when the error occurred
pathStringRequest 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 NameTypeDescription
fieldStringXML XPath location where the error was found
codeStringZUGFeRD/EN 16931 business rule code (e.g., BR-02, BR-CO-15)
messageStringDetailed 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

PropertyValue
URL/invoice/generate/pdf
MethodPOST
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthenticationR-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 NameTypeRequiredDescription
base64XMLStringYesBase64-encoded invoice XML data. Must be a valid XML in UBL 2.1, CrossIndustryInvoice (CII), or the relevant country-specific format.
typeEnum (DataType)YesInvoice format type. Specifies the standard of the provided XML. Valid values are listed in the table below.
countryEnum (Country)NoCountry 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.
vatNumberStringNoVAT 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

ValueDescriptionXSLT Group
XRECHNUNGGerman XRechnung standard (EN 16931 compliant)XRECHNUNG
PEPPOL_BISPEPPOL BIS 3.0 standardXRECHNUNG
RO_EFACTURARomania e-Factura formatXRECHNUNG
MY_INVOISMalaysia MyInvois formatMY_INVOIS
MY_PINTMalaysia PINT formatMY_PINT
DK_OIOUBLDenmark OIOUBL formatDK_OIOUBL
EG_INVOICEEgypt invoice formatEG_INVOICE
HR_INVOICECroatia invoice formatHR_INVOICE
UAE_PINTUAE PINT formatUAE_PINT

CII / ZUGFeRD-Based Formats

ValueDescriptionXSLT Group
ZUGFERDZUGFeRD 2.x format (XML-embedded PDF)ZUGFERD
FACTUR_XFrench Factur-X formatZUGFERD
XRECHNUNG_CIIXRechnung CII formatZUGFERD
CIIUN/CEFACT CrossIndustryInvoiceZUGFERD
CIDCrossIndustryDocument formatZUGFERD
PDFUnstructured invoice (paper invoices, images, etc.)ZUGFERD

Other Formats

ValueDescriptionXSLT Group
KZ_ESF_V2Kazakhstan ESF v2 formatKZ_ESF_V2
KSEFPoland KSeF formatKSEF
KSEF_OFFLINEPoland KSeF offline formatKSEF_OFFLINE

country Parameter

Country CodeCountryPDF Language
DEGermanyGerman (DE)
ATAustriaGerman (DE)
FRFranceFrench (FR)
ITItalyItalian (IT)
NLNetherlandsDutch (NL)
RORomaniaRomanian (RO)
ESSpainSpanish (ES)
TRTurkeyTurkish (TR)
KZKazakhstanKazakh (KK)
MYMalaysiaMalay (MS)
BNBruneiMalay (MS)
All othersEnglish (EN)

Responses

200 - Successful Response

PropertyValue
HTTP Status200
Content-Typeapplication/octet-stream
BodyBinary 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 NameTypeDescription
errorMessageStringDetailed description of the error
errorTypeStringError type identifier
errorTitleStringHTTP status name (BAD_REQUEST, INTERNAL_SERVER_ERROR, etc.)
errorIdStringCorrelation ID (for log tracing)
statusIntegerHTTP status code (400, 500, etc.)
timestampString (ISO 8601)Time when the error occurred
pathStringRequested 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

PropertyValue
URL/email/send
MethodPOST
Content-Typemultipart/form-data
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthenticationR-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

FieldTypeRequiredDescription
invoiceIdListList<UUID>YesList of invoice IDs to be sent. Multiple invoices can be included.
companyIdUUIDYesThe company ID that the invoices belong to.
formatTypesList<FormatType>YesFormat(s) in which invoice attachments will be generated. Multiple formats can be specified.
toListList<String>NoList of recipient email addresses.
ccListList<String>NoList of CC (Carbon Copy) recipient email addresses.
bccListList<String>NoList of BCC (Blind Carbon Copy) recipient email addresses.
subjectStringNoEmail subject line. If omitted, a template or default subject is used.
bodyStringNoEmail body text. If omitted, a template or default content is used.
attachmentsList<MultipartFile>NoAdditional file attachments (beyond the auto-generated invoice files).

FormatType Values

ValueDescription
PDFInvoice attached in PDF format
XMLInvoice attached in XML (UBL/CII) format
SIGNSigned invoice file attached
JSONInvoice attached in JSON format
GPDFInvoice attached in graphic PDF format
HTMLInvoice attached in HTML format

Attachment Constraints

ConstraintValue
Maximum file count3
Maximum file size (per file)5 MB
Allowed content typesapplication/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

FieldTypeValueDescription
HTTP StatusInteger200Operation successful
BodyBooleantrueEmail 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

PropertyValue
URL/peppol/search-mlr
MethodGET
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-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

FieldTypeRequiredFormatDescription
companyIdString (UUID)Yesxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxUnique identifier of the company to query
documentIdString (UUID)Noxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxPeppol document identifier (instance identifier)
counterpartParticipantIdStringNo{scheme}:{identifier} (e.g., 9930:de111222777)Counterpart’s Peppol participant identifier
invoiceIdStringNoFree textInvoice number or identifier
fromDateString (ISO Date)Noyyyy-MM-dd (e.g., 2025-09-09)Search start date (inclusive)
toDateString (ISO Date)Noyyyy-MM-dd (e.g., 2026-09-09)Search end date (inclusive)

Request Headers

HeaderTypeRequiredDescription
R-AuthString (JWT)YesUser authentication token. JWT signed with HS512 algorithm
AcceptStringNoDefault /. Response is returned as application/json

Parameter Values

counterpartParticipantId Format

SchemeDescriptionExample
9930Germany VAT number9930:de111222777
0204Leitweg-ID0204:1234567890123
0088EAN location code0088:1234567890123

responseType Response Type Enum Values

ValueDescription
ACCEPTANCEDocument was accepted by the counterpart
ACKNOWLEDGINGDocument was acknowledged (received) by the counterpart
REJECTIONDocument was rejected by the counterpart

statusReasonCode Status Reason Code Enum Values

ValueDescription
BUSINESS_RULE_VIOLATION_FATALBusiness rule violation. Critical error. Document was not processed
BUSINESS_RULE_VIOLATION_WARNINGBusiness rule violation. Warning. Document can still be processed
SYNTAX_VIOLATIONSyntax 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

FieldTypeDescription
idUUIDUnique identifier of the MLR record
companyIdStringIdentifier of the related company
documentIdStringPeppol document identifier
responseTypeEnum (MessageLevelResponseType)Overall response type: ACCEPTANCE, ACKNOWLEDGING, REJECTION
receivedTimeDateTime (ISO 8601)Date and time the MLR response was received
counterpartParticipantIdStringCounterpart’s Peppol participant identifier
invoiceIdStringRelated invoice number
responseLinesList<SearchMLRLineResponse>MLR detail lines

Response Detail Lines

FieldTypeDescription
idUUIDUnique identifier of the detail line
errorFieldString (nullable)The field / XPath expression where the error occurred
responseCodeEnum (MessageLevelResponseType)Line level response code: ACCEPTANCE, ACKNOWLEDGING, REJECTION
descriptionString (nullable)Error or status description
statusReasonCodeEnum (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

FieldTypeDescription
errorMessageStringHuman readable description of the error
errorTypeStringError classification code (e.g., NOT_AUTHORITY, RUNTIME_ERROR)
errorTitleString (HttpStatus)HTTP status code name (e.g., BAD_REQUEST, UNAUTHORIZED, INTERNAL_SERVER_ERROR)
statusIntegerHTTP status code numeric value (e.g., 400, 401, 500)
errorIdString (nullable)Correlation ID used for log tracing
dataString (nullable)Additional data (if available)
detailsMap<String, Object> (nullable)Detailed error information (if available)
validationErrorsList<ValidationError> (nullable)Field level validation errors (if available)
timestampDateTime (ISO 8601)Time when the error occurred
pathStringEndpoint 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

PropertyValue
URL/peppol/send-mlr
MethodPOST
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthenticationR-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 NameTypeRequiredDescription
invoiceIdString (UUID)YesUnique identifier of the invoice to send the MLR for (UUID format)
responseCodeEnum (MessageLevelResponseType)YesOverall response code for the invoice
errorLinesArray<MLRErrorLine>NoList of error details in the invoice. Can be left empty
errorLines Array Element
Field NameTypeRequiredDescription
descriptionStringNoHuman readable description of the error
errorFieldStringNoUBL/XML field path where the error was detected (XPath-like)
responseCodeEnum (MessageLevelResponseType)NoResponse code specific to this error line
statusReasonCodeEnum (MLRStatusReasonCode)NoClassification code of the error

Allowed Parameter Values


MessageLevelResponseType (responseCode)
ValueDescription
ACCEPTANCEInvoice accepted. It has been processed and approved
ACKNOWLEDGINGInvoice received. Receipt is confirmed but not yet fully processed
REJECTIONInvoice rejected. Not processed due to errors
MLRStatusReasonCode (statusReasonCode)
ValueDescription
BUSINESS_RULE_VIOLATION_FATALFatal business rule violation. A critical error that prevents the invoice from being processed
BUSINESS_RULE_VIOLATION_WARNINGWarning level business rule violation. The invoice can be processed but correction is recommended
SYNTAX_VIOLATIONSyntax error. Format or schema incompatibility in the XML/UBL structure

Responses

200 - Successful Response

FieldTypeValueDescription
HTTP StatusInteger200Operation successful
BodyString"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 NameTypeDescription
errorMessageStringDetailed description of the error
errorTypeStringError classification code (e.g., NOT_FOUND_INVOICE, API_ERROR)
errorTitleString (HttpStatus)HTTP status name (e.g., NOT_FOUND, BAD_REQUEST)
errorIdStringCorrelation identifier (for log tracing)
statusIntegerHTTP status code (e.g., 400, 404, 500)
dataStringAdditional data (if available)
detailsMap<String, Object>Additional detail information (if available)
validationErrorsArray<ValidationError>Validation error list (if available)
timestampString (ISO 8601)Timestamp of when the error occurred
pathStringEndpoint 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

PropertyValue
URL/annuaire/FR/siren/{siren}
MethodGET
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-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

FieldTypeRequiredDescription
sirenStringYesThe 9-digit French SIREN number for the target legal entity

Path Parameter Values

FieldRuleValid ExampleInvalid Example
sirenExactly 9 digits; leading zeros are preserved271688503271-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 idInstance value to use in onboarding or routing flows

Endpoint Information

PropertyValue
URL/annuaire/FR/siret/{siret}
MethodGET
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-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

FieldTypeRequiredDescription
siretStringYesThe 14-digit French SIRET number for the target establishment

Path Parameter Values

FieldRuleValid ExampleInvalid Example
siretExactly 14 digits; leading zeros are preserved. The first 9 digits must match the parent company's SIREN.27168850399286, 000000000000012716885039928 (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

FieldTypeDescription
siretStringThe queried 14-digit SIRET number.
sirenStringThe parent company's 9-digit SIREN number.
denominationStringOfficial establishment name (may differ from parent company name).
typeEtablissementStringEstablishment type (e.g., 'S' = secondary, 'P' = principal).
diffusibleStringPublishability flag: "O" = Yes, "N" = No.
etatAdministratifStringAdministrative status enum (e.g., "A", "F").
adresseObjectEstablishment address details.
historisationObjectAudit 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, or CODE_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, and codeRoutage detail 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

StepProcessDescription
1AuthenticationThe R-Auth JWT is validated by the Spring Security filter chain. The authenticated user principal is extracted.
2Input validationidInstance is checked to be non-blank. A blank value throws a validation error and returns 400.
3PPF availability checkIf 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.
4External PPF callDocnova 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.
5PPF 404 handlingIf the PPF returns 404, meaning the instance was not found, Docnova returns null, and the response maps to 404.
6ResponseReturns HTTP 200 OK with the full AnnuaireLigneAnnuaireResponse JSON object mapped from the PPF response.

Endpoint Information

PropertyValue
URL/annuaire/FR/directory-line/instance/{idInstance}
MethodGET
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-Auth header (JWT token)
Integration TypeLive 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 idInstance path variable and the authentication token.

Request Parameters

Header Parameters

FieldTypeRequiredDescription
R-Authstring (JWT)YesUser 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.
AcceptstringNo*/* or application/json. Defaults to JSON if omitted.

Path Parameters

ParameterTypeRequiredFormat / ExampleDescription
idInstancestring (numeric)Yes1013330The 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
FieldTypeNullableDescription
identifiantAdressagestringYesThe 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.
matriculePlateformestringYesPPF 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.
identifiantRoutagestringYesFull 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.
sirenstring (9)YesThe 9-digit SIREN of the company this directory line belongs to.
siretstring (14)YesThe 14-digit SIRET of the specific establishment, if this entry is registered at SIRET granularity. null for SIREN-level entries.
suffixeAdressagestringYesSuffix appended to the SIRET for sub-unit identification. Populated only when the annuaire maille is SUFFIXE.
dateFinEffetLocalDateYesThe planned end date of this directory line's validity. null if the entry is open-ended and still active.
dateFinEffectiveLocalDateYesThe actual effective end date as confirmed by the PPF. May differ from dateFinEffet if the closure was processed at a different time.
historisationobjectYesVersion and audit metadata assigned by the PPF to this specific instance. See historisation below.
plateformeobjectYesFull detail of the Plateforme Agréée associated with this directory line. See plateforme below.
uniteLegaleobjectYesLegal entity (SIREN-level) details of the company. See uniteLegale below.
etablissementobjectYesEstablishment (SIRET-level) details including address and B2G configuration. See etablissement below.
codeRoutageobjectYesRouting 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
FieldTypeNullableDescription
idInstanceintegerNoThe PPF-assigned unique instance number of this directory line version. Matches the idInstance supplied in the request path.
dateDebutEffetLocalDateYesThe date from which this directory line version became effective in the PPF.
dateDefinitionOffsetDateTimeYesThe exact date-time when this instance was defined, created, or updated in the PPF Annuaire. ISO 8601 with timezone offset.
creeParstringYesIdentifier of the actor, PA matricule or PPF internal identifier, that created this instance.
masquebooleanYesIf 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
FieldTypeNullableDescription
typePlateformestringYesPlatform type code. Typically PA (Plateforme Agréée) or PPF (Portail Public de Facturation itself).
matriculePlateformestringYesThe PPF-assigned registration number of the platform. Used as the routing endpoint identifier in e-invoice transmission.
raisonSocialePlateformestringYesLegal company name of the platform operator.
nomCommercialPlateformestringYesCommercial or brand name of the platform, for example Docnova.
contactOuUrlPlateformestringYesContact email address or URL of the platform for support or integration queries.
statutPlateformestringYesAdministrative status of the platform in the PPF registry. Common values: ACTIF (active), SUSPENDU (suspended), FERME (closed).
FieldTypeNullableDescription
sirenstring (9)Yes9-digit SIREN of the legal entity.
raisonSocialestringYesLegal company name registered with INSEE.
typeEntitestringYesEntity type: PM (Personne Morale / legal person) or PP (Personne Physique / natural person).
etatAdministratifstringYesAdministrative status from INSEE: A (Actif / active) or C (Cessé / ceased).
diffusiblestringYesINSEE diffusion flag: O (diffusible / public) or N (non-diffusible / private). Non-diffusible entities have restricted access in public directories.
etablissement — Establishment (SIRET Level)
FieldTypeNullableDescription
siretstring (14)Yes14-digit SIRET of the establishment.
sirenstring (9)YesParent SIREN of the establishment.
denominationstringYesEstablishment name or designation. May include branch suffix, for example - SIEGE.
typeEtablissementstringYesType of establishment: SIEGE (registered head office) or SECONDAIRE (secondary establishment).
diffusiblestringYesINSEE diffusion flag: O or N.
etatAdministratifstringYesAdministrative status: A (active) or F (fermé / closed).
adresseobjectYesPostal address of the establishment. See etablissement.adresse fields below.
donneesB2gComplementairesobjectYesB2G (Business-to-Government) supplementary data. null for purely B2B companies. See donneesB2gComplementaires below.
etablissement.adresse — Postal Address
FieldTypeNullableDescription
ligneAdresse1stringYesFirst address line, including street number and name.
ligneAdresse2stringYesSecond address line, for example building, floor, or additional location information.
ligneAdresse3stringYesThird address line for additional details.
codePostalstringYesFrench postal code, 5 digits.
localitestringYesCity or locality name.
codePaysstring (2)YesISO 3166-1 alpha-2 country code, for example FR.
libellePaysstringYesFull country name in French.
subDivisionPaysstringYesCountry subdivision code (ISO 3166-2). Rare; mostly null for French addresses.
etablissement.donneesB2gComplementaires — B2G Supplementary Data
FieldTypeNullableDescription
gestionEngagementJuridiquebooleanYesWhether legal commitment management is enabled for this entity in the B2G context.
gestionStatutMiseEnPaiementbooleanYesWhether payment status management is active.
gestionCodeServicebooleanYesWhether service code management is enabled.
moaUniquementbooleanYesIf true, this entity operates as buyer (MOA — Maître d'Ouvrage) only in B2G flows.
gestionEngagementJuridiqueOuServicebooleanYesCombined flag indicating whether legal commitment or service code management is enabled.
moabooleanYesWhether this entity is designated as MOA (project owner / buyer) in the B2G procurement flow.
codeRoutage — Routing Code Detail (CODE_ROUTAGE Maille Only)
FieldTypeNullableDescription
identifiantRoutagestringYesThe routing code identifier assigned to this sub-unit.
typeIdentifiantRoutagestringYesType of the routing identifier, also known as the scheme.
libelleCodeRoutagestringYesHuman-readable label for the routing code.
gestionEngagementJuridiquebooleanYesB2G legal commitment flag at routing code level.
etatAdministratifstringYesAdministrative status of this routing code: A (active) or F (closed).
adresseobjectYesPostal 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.

ValueidentifiantAdressage ContainsPopulated Nested ObjectDescription
SIREN9-digit SIRENuniteLegaleCompany is registered at SIREN level. All invoices addressed to this company, regardless of establishment, are routed to the same PA.
SIRET14-digit SIRETetablissementCompany is registered at establishment level. Different SIRET numbers may route to different PAs.
SUFFIXESIRET + suffixetablissement + suffixeAdressageSub-unit of an establishment identified by an additional suffix. Used for large organizations with complex internal routing.
CODE_ROUTAGErouting code valuecodeRoutageCustom 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 ppfStatus and ppfActivationDate fields.
  • Dynamic EDI flow control: Read the per-company dynamic EDI transformation mode state via the dynamicEdiEnabled field.

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 RegimeTransaction Report FrequencyPayment Report Frequency
Régime réel normal mensuelDécadaireMonthly
Régime réel normal trimestrielMonthlyMonthly
Régime simplifié d'impositionMonthlyMonthly
Franchise en base de TVABi-monthlyBi-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

PropertyValue
URL/reporting/FR/config/{companyId}
MethodGET
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-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

FieldTypeRequiredFormatDescription
companyIdUUIDYesxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxThe Docnova system UUID of the company to query. The France configuration is bound to this company identifier.

Responses

200 - Successful Response

A 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

FieldTypeDescription
idUUIDUnique system identifier of this configuration record.
companyIdUUIDThe company UUID sent in the request; identifies the owner of this configuration.
siretstring (14)The company's 14-digit SIRET number in the French tax system. Digits only. Cannot be changed after PPF activation.
vatRegimeFranceVatRegimeThe company's VAT regime. Directly determines the reporting period and PPF submission deadline.
enabledbooleantrue means the France e-reporting module is active for this company. false blocks all report submissions.
declarantRoleCodestring (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.
dynamicEdiEnabledbooleantrue means dynamic EDI transformation mode is enabled for this company; EDI messages are processed through runtime-configured mappings.
ppfIdInstancestring | nullThe instance identifier assigned to the company on PPF. Returns null if PPF onboarding has not been completed.
ppfActivationDateLocalDate | nullThe date the company became active on PPF. Format: YYYY-MM-DD. null if activation has not occurred.
ppfStatusFrancePpfStatusPPF registration status.
ppfMailleFrancePpfMaille | nullPPF addressability granularity level; indicates at which level the company is registered in the annuaire.
createdTimeLocalDateTimeTimestamp when the configuration record was first created. ISO 8601, second precision.
updatedTimeLocalDateTime | nullTimestamp 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.

ValueFull NameReporting Period
RRN_MRégime Réel Normal — MensuelTransaction reports: decadal; payment reports: monthly
RRN_TRégime Réel Normal — TrimestrielTransaction and payment reports: monthly
RSIRégime Simplifié d'ImpositionMonthly e-reporting
FBFranchise en Base de TVABimonthly e-reporting

FrancePpfStatus — PPF Registration Status

ValueDescription
PENDINGPPF onboarding has been initiated but not yet completed. Waiting for annuaire registration.
ACTIVECompany is active on PPF; report submissions are permitted.
CLOSEDPPF registration has been closed; new report submissions are blocked.

FrancePpfMaille — Addressability Granularity

ValueDescription
SIRENCompany is registered in the PPF annuaire at the SIREN level (9 digits).
SIRETCompany is registered at the establishment level via SIRET number (14 digits).
SUFFIXECompany is identified with a suffix appended to its SIRET; used for specific sub-units.
CODE_ROUTAGECompany 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/&#123;companyId&#125;"
}

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/&#123;companyId&#125;"
}

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/&#123;companyId&#125; 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 enabled to true or false to enable or suspend France e-reporting for the company.
  • VAT regime update: Adjust vatRegime when the company's TVA filing regime changes, which directly affects reporting cadence and PPF submission deadlines.
  • Declarant role correction: Update declarantRoleCode to 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 (ppfIdInstance is set), the SIRET field becomes immutable and any attempt to change it returns 400.
  • 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 RegimeTransaction Report FrequencyPayment Report Frequency
Régime réel normal mensuelDécadaireMonthly
Régime réel normal trimestrielMonthlyMonthly
Régime simplifié d'impositionMonthlyMonthly
Franchise en base de TVABi-monthlyBi-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

PropertyValue
URL/reporting/FR/config/{companyId}
MethodPUT
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-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

FieldTypeRequiredFormatDescription
companyIdUUIDYesxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxThe 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

FieldTypeRequiredConstraintsDescription
companyIdstring (UUID)YesValid UUID formatThe Docnova system UUID of the company. Must match the companyId path parameter.
siretstringNoExactly 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.
vatRegimeFranceVatRegimeYesEnum — see Enum ValuesThe company's TVA regime. Determines reporting cadence and PPF submission deadlines.
declarantRoleCodestringNo2-3 charactersRole code for the declarant in Flux 10 per Annexe 6 V1.9 rule G7.52. Accepted values: SE (Seller) or BY (Buyer).
enabledbooleanYestrue / falseActivates or deactivates the France e-reporting module for this company. Transitioning from false to true while ppfStatus is PENDING triggers PPF annuaire onboarding.
dynamicEdiEnabledbooleanNotrue / falseEnables or disables per-company dynamic EDI transformation mode. Defaults to false if omitted.

⚠️ SIRET immutability: The siret field is locked after PPF onboarding (ppfIdInstance is set). Any update request that changes the SIRET value at this stage will be rejected with 400 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
FieldTypeDescription
idUUIDUnique system identifier of this configuration record.
companyIdUUIDThe company UUID that owns this configuration.
siretstring (14)The 14-digit SIRET number stored for this company. Immutable after PPF onboarding.
vatRegimeFranceVatRegimeThe updated VAT regime. Governs reporting cadence and PPF deadlines.
enabledbooleantrue if the France e-reporting module is active for this company.
declarantRoleCodestring (2-3)Declarant role in Flux 10. SE = Seller, BY = Buyer.
dynamicEdiEnabledbooleantrue if dynamic EDI transformation mode is active for this company.
ppfIdInstancestring | nullPPF-assigned instance identifier. null until onboarding is complete.
ppfActivationDateLocalDate | nullDate the company became active on PPF. Format: YYYY-MM-DD. null if not yet activated.
ppfStatusFrancePpfStatusPPF registration status.
ppfMailleFrancePpfMaille | nullPPF addressability level; the granularity at which the company is registered in the annuaire.
createdTimeLocalDateTimeTimestamp when the configuration was originally created. Does not change on update.
updatedTimeLocalDateTimeTimestamp 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.

ValueFull NameTransaction FrequencyPayment Frequency
RRN_MRégime Réel Normal — MensuelDécadaire (10-day, 3x/month)Monthly
RRN_TRégime Réel Normal — TrimestrielMonthlyMonthly
RSIRégime Simplifié d'ImpositionMonthlyMonthly
FBFranchise en Base de TVABi-monthlyBi-monthly

declarantRoleCode — Declarant Role (Annexe 6 V1.9, rule G7.52)

ValueFrench TermDescription
SEVendeurSeller — the company issues invoices and submits Flux 10 transaction reports as the invoice sender.
BYAcheteurBuyer — the company receives invoices and reports as the invoice recipient.

FrancePpfStatus — PPF Registration Status (read-only in response)

ValueDescription
PENDINGOnboarding initiated but not yet completed. Annuaire registration awaited.
ACTIVECompany is active on PPF; report submissions are permitted.
CLOSEDPPF registration closed; new submissions are blocked.

FrancePpfMaille — Addressability Granularity (read-only in response)

ValueDescription
SIRENRegistered in PPF annuaire at SIREN level (9 digits).
SIRETRegistered at establishment level via SIRET (14 digits).
SUFFIXEIdentified by a suffix appended to SIRET; used for specific sub-units.
CODE_ROUTAGEIdentified 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/&#123;companyId&#125;.

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 ppfStatus to PENDING on creation. This field transitions to ACTIVE once PPF onboarding completes.
  • Conditional PPF onboarding trigger: If enabled is sent as true, the server immediately triggers the PPF annuaire onboarding call (annuaireService.onboard()) after saving the record. If enabled is false, onboarding is deferred until the record is updated with enabled: true.
  • VAT regime assignment: The vatRegime value 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) or BY (Acheteur / Buyer).

Server-side Execution Flow

StepProcessDescription
1Company lookupRetrieves the company record by companyId. Returns 404 if not found.
2Company validationChecks 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.
3Duplicate checkVerifies no France configuration already exists for this company. Returns 400 if one is found.
4Record creationPersists the new FranceCompanyConfigEntity with ppfStatus = PENDING and all request fields mapped.
5Conditional onboardingIf enabled = true, calls annuaireService.onboard(companyId) to register the company in the PPF annuaire.
6ResponseReturns 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:

VatRegimeFull NameTransaction ReportPayment Report
RRN_MRégime Réel Normal — MensuelDécadaire (3 × 10-day / month)Monthly
RRN_TRégime Réel Normal — TrimestrielMonthlyMonthly
RSIRégime Simplifié d'ImpositionMonthlyMonthly
FBFranchise en Base de TVABi-monthlyBi-monthly

Endpoint Information

PropertyValue
URL/reporting/FR/config
MethodPOST
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-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

FieldTypeRequiredConstraintsDescription
companyIdstring (UUID)YesValid UUIDThe Docnova system UUID of the company for which the France configuration is being created. The company must already exist in the system.
vatRegimeFranceVatRegimeYesEnum — see Enum ValuesThe company's TVA regime. Determines reporting cadence and PPF submission deadlines.
enabledbooleanYestrue / falseActivates 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.
siretstringNoExactly 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.
declarantRoleCodestringNo2-3 charactersRole 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.
dynamicEdiEnabledbooleanNotrue / falseEnables 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 companyId returns 400 BAD_REQUEST with 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
FieldTypeInitial ValueDescription
idUUIDAuto-generatedUnique system identifier for this configuration record.
companyIdUUIDFrom requestThe company UUID that owns this configuration.
siretstring (14) | nullFrom requestThe 14-digit SIRET number. null if not provided in the request.
vatRegimeFranceVatRegimeFrom requestThe assigned VAT regime. Governs all subsequent PPF reporting cadences.
enabledbooleanFrom requesttrue if the France e-reporting module is active and PPF onboarding was triggered.
declarantRoleCodestring | nullFrom requestDeclarant role in Flux 10. null if not provided.
dynamicEdiEnabledbooleanfalseDynamic EDI mode flag. Always false unless explicitly set.
ppfIdInstancestring | nullnullPPF-assigned instance identifier. Always null on initial creation; populated after onboarding completes.
ppfActivationDateLocalDate | nullnullDate the company became active on PPF. null on creation.
ppfStatusFrancePpfStatusPENDINGAlways PENDING on creation, regardless of enabled. Transitions to ACTIVE once PPF onboarding is confirmed.
ppfMailleFrancePpfMaille | nullnullPPF addressability granularity. null on creation; set by the PPF onboarding response.
createdTimeLocalDateTimeNowTimestamp of this creation operation. ISO 8601, second precision.
updatedTimeLocalDateTimeNowEquals createdTime on initial creation.

Enum Values

FranceVatRegime — VAT Regime

Per France PPF Dossier Général v3.1, Table 12.

ValueFull NameTransaction Report FrequencyPayment Report Frequency
RRN_MRégime Réel Normal — MensuelDécadaire (10-day, 3×/month)Monthly
RRN_TRégime Réel Normal — TrimestrielMonthlyMonthly
RSIRégime Simplifié d'ImpositionMonthlyMonthly
FBFranchise en Base de TVABi-monthlyBi-monthly

declarantRoleCode — Declarant Role (Annexe 6 V1.9, rule G7.52)

ValueFrench TermDescription
SEVendeurSeller — the company issues invoices and submits Flux 10 transaction reports as the invoice sender.
BYAcheteurBuyer — the company receives invoices and reports as the invoice recipient.

FrancePpfStatus — PPF Registration Status (read-only in response)

ValueDescription
PENDINGDefault on creation. Onboarding initiated but not yet confirmed by PPF.
ACTIVEPPF onboarding complete; report submissions are permitted.
CLOSEDPPF registration closed; new submissions are blocked.

FrancePpfMaille — Addressability Granularity (read-only in response)

ValueDescription
SIRENRegistered at SIREN level (9 digits) in PPF annuaire.
SIRETRegistered at establishment level via SIRET (14 digits).
SUFFIXEIdentified by a suffix appended to SIRET; for specific sub-units.
CODE_ROUTAGEIdentified 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 includes ppfErrorCode and ppfErrorMessage populated from the PPF acknowledgement detail, allowing developers and support teams to understand the exact rejection reason.
  • Deadline monitoring: The submissionDeadline field 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

StepProcessDescription
1AuthenticationThe R-Auth JWT is validated by the Spring Security filter chain. The authenticated user's uid is extracted via @AuthenticationPrincipal JwtUser.
2Report lookupThe service calls reportRepository.findById(reportId). If no record exists for this UUID, IllegalArgumentException("Report not found") is thrown and mapped to 400.
3DTO mappingThe found FranceReportEntity is mapped to FranceReportResponse via toResponse(). All persisted fields, including PPF acknowledgement data, are included.
4ResponseReturns 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

PropertyValue
URL/reporting/FR/status/{reportId}
MethodGET
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-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 reportId path variable and the authentication token.

Request Parameters

Path Parameters

ParameterTypeRequiredFormat / ExampleDescription
reportIdUUIDYes0034cdf6-3032-4fe1-b276-21a83191aeeeThe 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
FieldTypeNullableDescription
reportIdUUIDNoUnique identifier of this report record in the Docnova system. Matches the reportId passed in the path.
statusFranceReportStatusNoCurrent Docnova-side lifecycle status of the report. Derived from PPF acknowledgement — transitions to ACCEPTED when ppfAckStatus = Ok, and to REJECTED when ppfAckStatus = Error.
reportTypeFranceReportTypeYesSpecific report type: B2C or B2B, transaction or payment declaration.
sourceInvoiceSourceYesOrigin channel of the underlying invoice document, for example PORTAL, ERP, or PPF.
categoryFranceCategoryYesBusiness nature of the reported transaction: SERVICE, GOODS, MIXED, or NON_TAXABLE.
senderSirenstringYes9-digit SIREN of the invoice sender, also known as the declarant company.
ppfFlowIdstringYesThe 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.
trackingIdstringYesInternal Docnova tracking reference for this submission attempt.
invoiceIdUUIDYesDocnova UUID of the underlying invoice document this report is based on.
invoiceNumberstringYesHuman-readable invoice reference number.
itemCountintegerYesNumber of line items included in this report.
totalAmountBigDecimalYesTotal monetary amount reported, in the currency of the underlying invoice.
submittedTimeLocalDateTimeYesTimestamp when the report was successfully dispatched to the PPF. null if not yet submitted.
createdTimeLocalDateTimeNoTimestamp when the report record was created in the Docnova system.
submissionDeadlineLocalDateTimeYesThe 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.
ppfAckStatusstringYesRaw acknowledgement status string returned by the PPF. Possible values: Ok, Error, Pending, Processing. null if no PPF response received yet.
ppfErrorMessagestringYesHuman-readable rejection reason from the PPF acknowledgement detail. Populated only when ppfAckStatus = Error. Contains the PPF's reasonMessage from the first detail entry.
ppfErrorCodestringYesMachine-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.
lastStatusCheckTimeLocalDateTimeYesTimestamp 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 StatusMeaningDocnova Status Mapping
OkThe PPF has fully accepted and processed the report. No errors found.ACCEPTED
ErrorThe PPF rejected the report. ppfErrorCode and ppfErrorMessage contain the rejection details from PPF acknowledgement detail entries.REJECTED
PendingThe 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
ProcessingThe 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, the ppfErrorCode field contains a Chorus Pro / PPF status code. The most common values are 500 (RECEVABLE — accepted) and 501 (IRRECEVABLE — rejected). If the PPF returns an error without detail entries, the code defaults to 501.

Enum Values

FranceReportStatus — Report Lifecycle Status

ValueDescription
DRAFTReport created but not yet sent for validation. Initial state.
VALIDATINGReport is undergoing format and business rule validation before submission.
SUBMITTEDReport dispatched to the PPF; awaiting acknowledgement (ppfAckStatus is Pending or Processing).
ACCEPTEDPPF returned ppfAckStatus = Ok. Report successfully processed.
REJECTEDPPF returned ppfAckStatus = Error. See ppfErrorCode and ppfErrorMessage for details.
ERRORA Docnova system-level failure prevented submission. Not a PPF rejection.
REPORTEDReport acknowledged and included in a PPF period summary.
MERGEDReport was merged with another period report.

FranceReportType — Specific Report Type

ValueGroupFlow PrefixDescription
TRANSACTION_B2CE_REPORTINGFRR-10.3B2C transaction e-report, domestic sales to non-business customers.
TRANSACTION_B2BE_REPORTINGFRR-10.1B2B international transaction e-report.
PAYMENT_B2BPAYMENTFRR-10.2B2B payment declaration report.
PAYMENT_B2CPAYMENTFRR-10.4B2C payment declaration report.

FranceCategory — Transaction Business Category

ValueDescription
SERVICEService-based items only.
GOODSPhysical goods only.
MIXEDBoth goods and services.
NON_TAXABLEOutside 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=REJECTED or status=ERROR
  • Tracking PAYMENT_B2C type 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

PropertyValue
URL/reporting/FR/list
MethodGET
Content-Typeapplication/json
Base URL
Production Environment URLhttps://api-fr.docnova.ai/
AuthorizationR-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

FieldTypeRequiredDescription
companyIdstring (UUID)YesThe unique identifier (UUID) of the company whose reports are being queried.
reportTypestring (enum)NoReport type filter. Narrows results to a specific transaction or payment type.
reportGroupstring (enum)NoReport group filter. If reportType is not specified, returns all types within this group.
sourcestring (enum)NoThe source platform or channel through which the invoice/transaction was created.
statusstring (enum)NoProcessing status filter for the report.
ppfAckStatusstringNoThe acknowledgement/notification status returned by PPF. Free-text, case-sensitive match.
categorystring (enum)NoInvoice/transaction category filter.
dateFromstring (date)NoStart date filter (inclusive). ISO 8601 format: YYYY-MM-DD. Matches from start of day.
dateTostring (date)NoEnd date filter (inclusive). ISO 8601 format: YYYY-MM-DD. Matches up to start of the following day.
sirenstringNoThe 9-digit SIREN number of the sending company. Performs a LIKE search on both the senderSiren field and the raw request JSON.
pageNumberintegerNoPage number to retrieve (0-based). Default: 0.
pageSizeintegerNoNumber of records per page. Default: 20.
sort.sortedbooleanNoIndicates whether sorting is applied. Managed via Spring Pageable.
sort.unsortedbooleanNoIndicates no sorting is applied.
offsetintegerNoPagination offset for the starting position.
pagedbooleanNoWhether a paged response is requested. Default: true.
unpagedbooleanNoWhether all records should be returned without pagination. Default: false.

Parameter Value Tables

reportType Possible Values

ValueGroupPPF Flow CodeDescription
TRANSACTION_B2CE_REPORTINGFRR-10.3E-reporting of B2C individual customer transaction data.
TRANSACTION_B2BE_REPORTINGFRR-10.1E-reporting of international B2B transaction data.
PAYMENT_B2BPAYMENTFRR-10.2Payment notification for B2B invoices.
PAYMENT_B2CPAYMENTFRR-10.4Payment notification for B2C invoices.

reportGroup Possible Values

ValueDescription
PAYMENTPayment notifications group. Includes PAYMENT_B2B and PAYMENT_B2C.
E_REPORTINGElectronic reporting group. Includes TRANSACTION_B2C and TRANSACTION_B2B.

status Possible Values

ValueDescription
DRAFTDraft. Not yet submitted and still editable.
VALIDATINGValidating. Being checked by the system before transmission to PPF.
SUBMITTEDSubmitted. Transmitted to PPF and awaiting acknowledgement.
ACCEPTEDAccepted. Successfully processed by PPF.
REJECTEDRejected. Refused by PPF and correction is required.
ERRORError. Transmission failed due to a technical error.
REPORTEDReported. Processing completed.
MERGEDMerged. Combined into another report.

category Possible Values

ValueDescription
SERVICEService invoice.
GOODSGoods or product invoice.
MIXEDMixed invoice containing both goods and services.
NON_TAXABLETransaction not subject to VAT.

source Selected Values

ValueDescription
PORTALCreated via web portal.
ERPERP system integration.
PEPPOLReceived via the PEPPOL network.
EBAYeBay sales channel.
SHOPIFYShopify e-commerce platform.
AMAZON_SPAmazon Seller Platform.
SFTPSFTP file transfer.
PPFDirectly from the PPF platform.
EMAILReceived via email.
MOBILEMobile application.
STRIPEStripe payment system.
TEMUTemu 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
FieldTypeDescription
reportIdstring (UUID)Unique identifier of the report. Used as a reference in subsequent report operations.
statusstring (enum)Current processing status of the report. Uses FranceReportStatus.
reportTypestring (enum)Report type. Uses FranceReportType. Indicates which PPF flow this report belongs to.
sourcestring (enum)Source platform or channel through which the invoice/transaction was created. Uses InvoiceSource.
categorystring (enum)Invoice category. Uses FranceCategory.
senderSirenstring9-digit SIREN number of the sending company.
ppfFlowIdstringFlow identifier assigned by PPF. Used for tracking and debugging.
trackingIdstringInternal system tracking identifier.
invoiceIdstring (UUID)UUID of the invoice associated with this report.
invoiceNumberstringHuman-readable invoice number.
itemCountintegerNumber of transactions or line items covered by this report.
totalAmountnumber (decimal)Total monetary amount of the report.
submittedTimestring (datetime)Date and time the report was transmitted to PPF. ISO 8601 format.
createdTimestring (datetime)Date and time the report was created in the system. ISO 8601 format.
submissionDeadlinestring (datetime)Latest date and time by which the report must be submitted. ISO 8601 format.
ppfAckStatusstringAcknowledgement status text returned by PPF, for example Ok, Error, or Pending.
ppfErrorMessagestring | nullError message returned by PPF upon rejection.
ppfErrorCodestring | nullError code returned by PPF.
lastStatusCheckTimestring (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.