Skip to content

France API integration

This page is for integrators who connect an ERP or middleware to xTool over the public API (/api/v2/..., x-api-key header).

France configuration (Annuaire / QAS registration, company identifiers, tax-report mode) is managed in the web UI only. There is no public /api/v2/france/... endpoint. After the configuration is Active, all invoice exchange, payments, and tax-report reads go through the standard document / transaction / payment APIs.

Related pages:


Integration model

France API work is built on standard xTool entities. Use the exact names below — they match the API resources.

Entity API resource You create? Role
Document /api/v2/documents Yes (upload) or xTool (inbound) Invoice / credit note content
Transaction /api/v2/transactions Indirectly via send, or xTool on receive One channel attempt: send.france or receive.france
Transaction Event /api/v2/transaction-events No Immutable history entry on a transaction (prepare, send, receive, approved, …)
Transaction Event File /api/v2/transaction-event-files/.../download No Binary attachment belonging to a transaction event (XML payload, acknowledgement, …)
Transaction Action /api/v2/transactions/{id}/actions Yes (buyer) Command you submit on a receive.france transaction (acknowledge / approve / partially approve / dispute / refuse)
Payment /api/v2/payments Yes Money movement + allocations to documents
Tax report /api/v2/tax-reports No Read-only regulatory report built by xTool

Object model:

flowchart TD
    Document --> Transaction
    Transaction --> Events["Transaction Event[]"]
    Events --> Files["Transaction Event File[]"]
    Transaction --> Actions["Transaction Action[]"]
  • Transaction type: send.france or receive.france
  • Actions: buyer lifecycle + payment_sent on receive.france; payment_received on send.france

Transaction Action ≠ Transaction Event.
You POST a Transaction Action. For buyer lifecycle actions, xTool records a matching Transaction Event (for example action france.invoice.approve → event france.invoice.approved). Action france.invoice.payment_sent (receive.france) marks payment as transmitted. Action france.invoice.payment_received (send.france) creates a Payment allocated to the document (same as POST /api/v2/payments). On B2B domestic, these map to CDV lifecycle codes (see below); B2C and B2B cross-border may not use CDV.

See also Transactions.


Transaction, events, actions, and files

This section is the core object model for France lifecycle tracking.

Transaction

A Transaction is one send or receive attempt for one document on one channel.

Field (API) Notes
id Transaction UUID — store it for polling
document_id Parent document
type send.france or receive.france
status Lifecycle of the attempt (initialprocessingcompleted / failed)
metadata Client-safe France fields such as invoice_state (no internal provider ids)
status_log Optional via include=status_log
events Optional via include=events (nested events include files)
actions Optional via include=actions
1
2
3
GET /api/v2/transactions/{transaction_id}?include=events&include=actions&include=status_log
GET /api/v2/transactions?document_id={document_id}
GET /api/v2/transactions?transaction_type=receive.france

One document can have multiple transactions (resend, receive, other channels). Always follow the specific France transaction you care about.

Transaction Event

A Transaction Event is a historical record of something that already happened on that transaction. Clients never create events.

Field (API) Notes
id Event UUID
transaction_id Parent transaction (on get-by-id / list)
type Event type string (see table below)
metadata Optional event-specific data
files Nested Transaction Event File items when loaded
created_at / updated_at Timestamps
GET /api/v2/transactions/{transaction_id}/events
GET /api/v2/transaction-events/{transaction_event_id}

include=events on the transaction get also loads nested event files.

France transaction event types

type Typical meaning
france.invoice.prepare Invoice prepared / validated for the provider
france.invoice.send Submitted to the France channel (outbound)
france.invoice.receive Inbound invoice received from the channel
france.invoice.acknowledged Buyer acknowledged the invoice (CDV 204)
france.invoice.approved Buyer fully approved the invoice (CDV 205)
france.invoice.partially_approved Buyer partially approved the invoice (CDV 206)
france.invoice.disputed Buyer disputed the invoice (CDV 207)
france.invoice.suspended Buyer suspended processing (CDV 208; channel/CDAR)
france.invoice.completed Seller completed after suspension (CDV 209; channel/CDAR)
france.invoice.refused Buyer refused the invoice (CDV 210)
france.invoice.payment_sent Buyer marked payment as sent (CDV 211; receive.france)
france.invoice.payment_received Seller recorded payment received (CDV 212; send.france)
france.tax_report.send Tax report submitted
france.tax_report.acknowledged Tax report acknowledged
france.tax_report.registered Tax report registered

CDV codes (204–212) come from the domestic B2B lifecycle (CDAR / AFNOR XP Z12-012). They apply to B2B domestic flows. B2C and B2B cross-border use different reporting paths and may not produce these CDV lifecycle codes; xTool still records the same transaction event types when the channel reports the corresponding status.

Timing depends on domestic vs cross-border scenarios and provider processing. Poll and process new event ids only.

When the channel delivers a lifecycle notification (CDAR / ApplicationResponse) for B2B domestic, xTool prefers the CDV code in the XML (ProcessConditionCode / ResponseCode) over the provider invoice state. That is what distinguishes e.g. full approval (205) from partial approval (206).

Transaction Event File

A Transaction Event File is a stored file attached to a Transaction Event (for example the invoice XML that was sent or received, or a related acknowledgement payload).

Field (API) Notes
id File UUID — required for download
filename Original / stored name
content_type MIME type
created_at Timestamp

Files appear nested under events when you list/get events. Download content separately:

GET /api/v2/transaction-event-files/{transaction_event_file_id}/download

Typical usage:

  1. Poll transaction with include=events
  2. Find the event of interest (for example france.invoice.receive or france.invoice.send)
  3. Read files[].id / filename / content_type
  4. Download each needed file by id

There is no create/update/delete of event files via the public client API.

Transaction Action

A Transaction Action is a command you ask xTool to perform on an existing transaction. Today France buyer actions exist only on receive.france.

Field (API) Notes
id Action UUID
transaction_id Parent transaction
type Buyer lifecycle action, france.invoice.payment_sent, or france.invoice.payment_received
parameters Action payload (for refuse: reason / optional reason_code)
status initialprocessingcompleted / failed
created_at Timestamp
GET /api/v2/transactions/{transaction_id}/actions
POST /api/v2/transactions/{transaction_id}/actions

There is no get-by-id endpoint for a single action. Use the list, or include=actions on the transaction get.

CDV codes → actions (B2B domestic)

CDV codes apply to B2B domestic only (CDAR / AFNOR XP Z12-012). B2C and B2B cross-border may not use them. Codes without an action are reported by the channel only.

CDV Label Action type Event type Transaction
204 Prise en charge france.invoice.acknowledge france.invoice.acknowledged receive.france
205 Approuvée france.invoice.approve france.invoice.approved receive.france
206 Approuvée partiellement france.invoice.partially_approve france.invoice.partially_approved receive.france
207 En litige france.invoice.dispute france.invoice.disputed receive.france
208 Suspendue — (channel only) france.invoice.suspended either
209 Complétée — (channel only) france.invoice.completed either
210 Refusée france.invoice.refuse france.invoice.refused receive.france
211 Paiement transmis france.invoice.payment_sent france.invoice.payment_sent receive.france
212 Encaissée france.invoice.payment_received france.invoice.payment_received send.france

Earlier channel statuses such as 200 (Déposée), 202 (Reçue), and 203 (Mise à disposition) are also B2B domestic CDV codes; xTool does not expose client actions for them.

France action types → resulting events

Action type Body Result
france.invoice.acknowledge { "type": "france.invoice.acknowledge" } Event france.invoice.acknowledged
france.invoice.approve { "type": "france.invoice.approve" } Event france.invoice.approved
france.invoice.partially_approve { "type": "france.invoice.partially_approve", "amount": "...", "reason": "..." } (amount_code optional, default MAPTTC) Event france.invoice.partially_approved
france.invoice.dispute { "type": "france.invoice.dispute", "reason": "..." } Event france.invoice.disputed
france.invoice.refuse { "type": "france.invoice.refuse", "reason": "..." } (reason required; reason_code optional) Event france.invoice.refused
france.invoice.payment_sent { "type": "france.invoice.payment_sent" } (receive.france only) Event france.invoice.payment_sent
france.invoice.payment_received { "type": "france.invoice.payment_received" } (optional amount / currency / paid_at; send.france only) Creates a Payment allocated to the document; event france.invoice.payment_received (after channel notification)

Rules:

  • Submitting the same lifecycle action twice for one transaction returns conflict (409)
  • Wait for action status to become completed / failed, and for the matching event to appear
  • Payment sent (receive.france) only updates channel status; it does not create a Payment
  • Payment received (send.france) creates the Payment immediately and syncs to the provider

Authentication and organisation scope

x-api-key: <your-api-key>

The API key is scoped to an organisation. Every document, transaction, payment, and tax report you see belongs to that organisation.

Checklist:

  1. Create an API key in the web UI with permission to send via France (and to read documents / transactions / payments as needed).
  2. Call /api/v2/... with that key.
  3. Ensure the organisation has at least one Active France configuration (web UI → Channels → France).

France configuration and which account sends

France configuration is not selected in the send request body. On send.france, xTool:

  1. Takes the document’s organisation
  2. Loads Active France configurations for that organisation (with a provider account id)
  3. Matches the document sender (metadata.sender_id, typically the supplier endpoint / SIREN) to configuration siren / siret / cin_value
  4. If no match, falls back to the first Active configuration with an account

Practical rules:

  • Put the seller identifiers in the invoice so they match the configuration you intend to send from
  • One organisation may have several France configurations (for example two QAS companies for send/receive tests)
  • Reception-only mode (annuaire_only) cannot send invoices

Configuration lifecycle (NEW → … → DIRECTORY_PENDING / SCHEDULEDACTIVE) is web + background jobs. API exchange requires Active.


Formats

Preferred for France channel tests and production-like flows:

Format code Syntax Notes
france_cius.invoice.1_0.xml_ubl.en16931 UBL France CIUS invoice
france_cius.invoice.1_0.xml_cii.en16931 CII France CIUS invoice
france_cius.credit_note.1_0.xml_ubl UBL France CIUS credit note
peppol_bis_billing_france.invoice.3_0.xml_ubl UBL Peppol BIS Billing France invoice (explicit)
peppol_bis_billing_france.credit_note.3_0.xml_ubl UBL Peppol BIS Billing France credit note (explicit)
xtool.invoice.1_0 JSON Internal model; can be converted / mapped
xtool.credit_note.1_0 JSON Internal credit note

France CIUS models require France-specific fields such as document.profile_id (billing mode, for example S1).

Domestic B2B send typically expects EUR, a short enough invoice number, and a French buyer routing id (PIN / endpoint) where required. Validation failures return before or during prepare.

Upload options:

1
2
3
POST /api/v2/documents/upload/xml?direction=outbound&require_valid=true
Content-Type: application/xml
x-api-key: <your-api-key>
1
2
3
POST /api/v2/documents/upload/model?direction=outbound&require_valid=true
Content-Type: application/json
x-api-key: <your-api-key>

Keep the returned document id.

Example France CIUS UBL (test)

Use this body for POST /api/v2/documents/upload/xml?direction=outbound&require_valid=true in the xTool test environment, then POST .../send with { "transaction_type": "send.france" }.

Before upload:

  1. Replace seller SIREN 256685928 with the Active France configuration SIREN you send from (QAS number from your Chorus Pro dataset — see Test Environment).
  2. Replace buyer SIREN 346628948 with another QAS company that is also registered / Active as receiver (second France configuration, or a counterparty in QAS).
  3. Align EndpointID, PartyLegalEntity/CompanyID, and VAT CompanyID (FR… + SIREN) with those numbers.
  4. Use a unique cbc:ID for each send.
<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
    xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
    xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
    <cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:peppol:france:billing:cius:1.0</cbc:CustomizationID>
    <cbc:ProfileID>S1</cbc:ProfileID>
    <cbc:ID>FA-2026-0001</cbc:ID>
    <cbc:IssueDate>2026-07-28</cbc:IssueDate>
    <cbc:DueDate>2026-08-28</cbc:DueDate>
    <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
    <cbc:Note>FA-2026-0001 - Test Company A, SIREN 256685928</cbc:Note>
    <cbc:Note>#PMT#Credit transfer</cbc:Note>
    <cbc:Note>#PMD#FA-2026-0001</cbc:Note>
    <cbc:Note>#AAB#Paiement a 30 jours par virement bancaire.</cbc:Note>
    <cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
    <cbc:BuyerReference>TEST-BUYER-B</cbc:BuyerReference>
    <cac:AccountingSupplierParty>
        <cac:Party>
            <cbc:EndpointID schemeID="0225">256685928</cbc:EndpointID>
            <cac:PartyName>
                <cbc:Name>Test Company A</cbc:Name>
            </cac:PartyName>
            <cac:PostalAddress>
                <cbc:StreetName>1 Rue de Test</cbc:StreetName>
                <cbc:CityName>Paris</cbc:CityName>
                <cbc:PostalZone>75001</cbc:PostalZone>
                <cbc:CountrySubentity>Ile-de-France</cbc:CountrySubentity>
                <cac:Country>
                    <cbc:IdentificationCode>FR</cbc:IdentificationCode>
                </cac:Country>
            </cac:PostalAddress>
            <cac:PartyTaxScheme>
                <cbc:CompanyID>FR16256685928</cbc:CompanyID>
                <cac:TaxScheme>
                    <cbc:ID>VAT</cbc:ID>
                </cac:TaxScheme>
            </cac:PartyTaxScheme>
            <cac:PartyLegalEntity>
                <cbc:RegistrationName>Test Company A</cbc:RegistrationName>
                <cbc:CompanyID schemeID="0002">256685928</cbc:CompanyID>
            </cac:PartyLegalEntity>
            <cac:Contact>
                <cbc:ElectronicMail>company-a@example.test</cbc:ElectronicMail>
            </cac:Contact>
        </cac:Party>
    </cac:AccountingSupplierParty>
    <cac:AccountingCustomerParty>
        <cac:Party>
            <cbc:EndpointID schemeID="0225">346628948</cbc:EndpointID>
            <cac:PartyName>
                <cbc:Name>Test Company B</cbc:Name>
            </cac:PartyName>
            <cac:PostalAddress>
                <cbc:StreetName>2 Rue de Test</cbc:StreetName>
                <cbc:CityName>Lyon</cbc:CityName>
                <cbc:PostalZone>69001</cbc:PostalZone>
                <cbc:CountrySubentity>Auvergne-Rhone-Alpes</cbc:CountrySubentity>
                <cac:Country>
                    <cbc:IdentificationCode>FR</cbc:IdentificationCode>
                </cac:Country>
            </cac:PostalAddress>
            <cac:PartyTaxScheme>
                <cbc:CompanyID>FR05346628948</cbc:CompanyID>
                <cac:TaxScheme>
                    <cbc:ID>VAT</cbc:ID>
                </cac:TaxScheme>
            </cac:PartyTaxScheme>
            <cac:PartyLegalEntity>
                <cbc:RegistrationName>Test Company B</cbc:RegistrationName>
                <cbc:CompanyID schemeID="0002">346628948</cbc:CompanyID>
            </cac:PartyLegalEntity>
            <cac:Contact>
                <cbc:ElectronicMail>account-b@example.test</cbc:ElectronicMail>
            </cac:Contact>
        </cac:Party>
    </cac:AccountingCustomerParty>
    <cac:Delivery>
        <cbc:ActualDeliveryDate>2026-07-29</cbc:ActualDeliveryDate>
    </cac:Delivery>
    <cac:PaymentMeans>
        <cbc:PaymentMeansCode name="Credit transfer">30</cbc:PaymentMeansCode>
        <cbc:PaymentID>FA-2026-0001</cbc:PaymentID>
        <cac:PayeeFinancialAccount>
            <cbc:ID>FR7630006000011234567890189</cbc:ID>
            <cbc:Name>Test Company A</cbc:Name>
            <cac:FinancialInstitutionBranch>
                <cbc:ID>AGRIFRPP</cbc:ID>
            </cac:FinancialInstitutionBranch>
        </cac:PayeeFinancialAccount>
    </cac:PaymentMeans>
    <cac:PaymentTerms>
        <cbc:Note>Paiement a 30 jours par virement bancaire.</cbc:Note>
    </cac:PaymentTerms>
    <cac:TaxTotal>
        <cbc:TaxAmount currencyID="EUR">260.00</cbc:TaxAmount>
        <cac:TaxSubtotal>
            <cbc:TaxableAmount currencyID="EUR">1300.00</cbc:TaxableAmount>
            <cbc:TaxAmount currencyID="EUR">260.00</cbc:TaxAmount>
            <cac:TaxCategory>
                <cbc:ID>S</cbc:ID>
                <cbc:Percent>20.00</cbc:Percent>
                <cac:TaxScheme>
                    <cbc:ID>VAT</cbc:ID>
                </cac:TaxScheme>
            </cac:TaxCategory>
        </cac:TaxSubtotal>
    </cac:TaxTotal>
    <cac:LegalMonetaryTotal>
        <cbc:LineExtensionAmount currencyID="EUR">1300.00</cbc:LineExtensionAmount>
        <cbc:TaxExclusiveAmount currencyID="EUR">1300.00</cbc:TaxExclusiveAmount>
        <cbc:TaxInclusiveAmount currencyID="EUR">1560.00</cbc:TaxInclusiveAmount>
        <cbc:PayableAmount currencyID="EUR">1560.00</cbc:PayableAmount>
    </cac:LegalMonetaryTotal>
    <cac:InvoiceLine>
        <cbc:ID>1</cbc:ID>
        <cbc:InvoicedQuantity unitCode="DAY">7.0</cbc:InvoicedQuantity>
        <cbc:LineExtensionAmount currencyID="EUR">700.00</cbc:LineExtensionAmount>
        <cac:Item>
            <cbc:Description>Architecture review services</cbc:Description>
            <cbc:Name>Architecture review</cbc:Name>
            <cac:ClassifiedTaxCategory>
                <cbc:ID>S</cbc:ID>
                <cbc:Percent>20.00</cbc:Percent>
                <cac:TaxScheme>
                    <cbc:ID>VAT</cbc:ID>
                </cac:TaxScheme>
            </cac:ClassifiedTaxCategory>
        </cac:Item>
        <cac:Price>
            <cbc:PriceAmount currencyID="EUR">100.0</cbc:PriceAmount>
        </cac:Price>
    </cac:InvoiceLine>
    <cac:InvoiceLine>
        <cbc:ID>2</cbc:ID>
        <cbc:InvoicedQuantity unitCode="DAY">3.0</cbc:InvoicedQuantity>
        <cbc:LineExtensionAmount currencyID="EUR">600.00</cbc:LineExtensionAmount>
        <cac:Item>
            <cbc:Description>API integration services</cbc:Description>
            <cbc:Name>API integration</cbc:Name>
            <cac:ClassifiedTaxCategory>
                <cbc:ID>S</cbc:ID>
                <cbc:Percent>20.00</cbc:Percent>
                <cac:TaxScheme>
                    <cbc:ID>VAT</cbc:ID>
                </cac:TaxScheme>
            </cac:ClassifiedTaxCategory>
        </cac:Item>
        <cac:Price>
            <cbc:PriceAmount currencyID="EUR">200.0</cbc:PriceAmount>
        </cac:Price>
    </cac:InvoiceLine>
</Invoice>

Detected / expected format: france_cius.invoice.1_0.xml_ubl.en16931.

Step A — Upload

Upload CIUS XML or a JSON model (see formats above).

Step B — Send

1
2
3
POST /api/v2/documents/{document_id}/send
Content-Type: application/json
x-api-key: <your-api-key>
{ "transaction_type": "send.france" }

Store transaction.id.

Step C — Poll the transaction

Recommended poll:

GET /api/v2/transactions/{transaction_id}?include=events&include=status_log

Also useful:

Call Purpose
GET /api/v2/transactions/{id}/events Transaction Event list (+ nested Transaction Event Files)
GET /api/v2/transaction-events/{event_id} Single Transaction Event (+ files)
GET /api/v2/transaction-event-files/{file_id}/download Download a Transaction Event File
GET /api/v2/transactions?document_id={document_id} All transactions for one document

Suggested polling:

  • Interval: 5–30 seconds while transaction status is processing
  • Stop when the transaction reaches completed or failed
  • Persist last seen Transaction Event ids so you only process new events
  • When you need payloads, download Transaction Event Files by files[].id

Typical outbound Transaction Events

Transaction Event type Meaning
france.invoice.prepare Built / validated for the provider
france.invoice.send Submitted to the France channel
france.invoice.approved Buyer approved
france.invoice.refused Buyer refused
france.invoice.payment_received Payment received confirmed (CDV 212, B2B domestic)
france.tax_report.send / acknowledged / registered Related tax-report processing

Exact timing depends on scenario (domestic vs cross-border) and provider processing. Some tax-report events may appear later.

Step D — Optional payment

POST /api/v2/payments

Allocate to the document id (not the transaction id). For outbound invoices, POST /api/v2/transactions/{transaction_id}/actions with { "type": "france.invoice.payment_received" } creates the same kind of payment for that transaction's document; the matching france.invoice.payment_received event usually appears after channel notification (on B2B domestic, CDV 212). For inbound invoices, use france.invoice.payment_sent to mark payment as transmitted without creating a Payment (on B2B domestic, CDV 211).


Inbound integration pattern

Inbound documents are created by xTool when the channel delivers them. Your job is to discover, store, and respond.

Discovery

1
2
3
GET /api/v2/documents?direction=inbound
GET /api/v2/transactions?transaction_type=receive.france
GET /api/v2/transactions?document_id={document_id}

Pattern:

  1. Poll inbound documents and/or receive.france transactions on a schedule
  2. Deduplicate by document id
  3. Fetch content once, then drive ERP posting

Read content

1
2
3
GET /api/v2/documents/{document_id}?include=model&include=status_log
GET /api/v2/documents/{document_id}/xml
GET /api/v2/documents/{document_id}/model

Optional:

POST /api/v2/documents/{document_id}/ack
{ "ack": true }

Inspect receive transaction

GET /api/v2/transactions/{transaction_id}?include=events&include=actions&include=status_log

Transaction Event france.invoice.receive typically carries the inbound invoice as Transaction Event Files. Download them via /api/v2/transaction-event-files/{id}/download.

Buyer response (Transaction Actions)

Only on receive.france:

POST /api/v2/transactions/{transaction_id}/actions
{ "type": "france.invoice.approve" }
1
2
3
4
5
{
  "type": "france.invoice.refuse",
  "reason": "Incorrect amount",
  "reason_code": null
}

Other buyer lifecycle actions: france.invoice.acknowledge, france.invoice.partially_approve, france.invoice.dispute.

Then poll Transaction Events until the matching lifecycle event appears (for example france.invoice.approved or france.invoice.refused) on both receiver and sender sides as the network propagates. Also check the Transaction Action status (processingcompleted / failed).


Payments API (France-relevant rules)

Method Path
POST /api/v2/payments
GET /api/v2/payments
GET /api/v2/payments/{payment_id}
PATCH /api/v2/payments/{payment_id}
DELETE /api/v2/payments/{payment_id}/delete

Rules of thumb:

  • currency is required on create (use EUR for typical France domestic flows)
  • Allocations target document_id + amount
  • PATCH amount does not rewrite allocations unless you also send allocations
  • Partial payments are normal: multiple payments over time for one invoice

Tax reports API

Read-only:

GET /api/v2/tax-reports
GET /api/v2/tax-reports/{tax_report_id}

Reports list sources (document, payment, …). You do not create tax reports via API; they appear from France processing (sometimes delayed for aggregated / cross-border scenarios).


Endpoint map

Documents

Method Path Notes
POST /api/v2/documents/upload/xml Outbound/inbound via query direction
POST /api/v2/documents/upload/model JSON model upload
GET /api/v2/documents Filter direction=inbound / outbound
GET /api/v2/documents/{id} Optional include=model, status_log
GET /api/v2/documents/{id}/xml XML representation
GET /api/v2/documents/{id}/model Model representation
POST /api/v2/documents/{id}/send Body: transaction_type
POST /api/v2/documents/{id}/ack Optional inbound ack

Transactions / Transaction Events / Transaction Actions / Transaction Event Files

Method Path Notes
GET /api/v2/transactions Filters: document_id, transaction_type, transaction_status
GET /api/v2/transactions/{id} include=events, actions, status_log
GET /api/v2/transactions/{id}/events Transaction Events (includes nested Transaction Event Files)
GET /api/v2/transaction-events/{id} Single Transaction Event + files
GET /api/v2/transaction-event-files/{id}/download Download Transaction Event File content
GET /api/v2/transactions/{id}/actions List Transaction Actions
POST /api/v2/transactions/{id}/actions Create Transaction Action (buyer lifecycle / paid)

There is no get-by-id for a single Transaction Action.

Payments / tax reports

See tables above.


Error handling

Situation What to do
400 on upload / send Fix validation / format / France rules (currency, profile, buyer id, …)
400 “No active France configuration” Complete Channels → France onboarding in the web UI
400 annuaire_only cannot issue Switch tax-report mode to full for sending
Transaction failed Read Transaction Events + status_log; fix data and send again (new Transaction)
Missing inbound Confirm receiver configuration is Active; poll direction=inbound and receive.france
Payment created but no paid event yet Wait for channel confirmation; keep polling Transaction Events

Always log transaction_id, document_id, Transaction Event types, and Transaction Action ids for support.


  1. Web setup — Active France configuration(s); note SIREN/SIRET used as seller/buyer
  2. Auth — API key with France send (+ read) rights
  3. Outbound worker — upload → send.france → poll Transaction / Transaction Events / Event Files → optional Payment
  4. Inbound worker — poll inbound / receive.france → fetch document XML/model and/or Transaction Event Files → ERP → Transaction Actions (approve / refuse / …) → optional Payment
  5. Reporting — periodically GET /api/v2/tax-reports and reconcile sources to documents/payments
  6. Idempotency — store external invoice number ↔ xTool document id; ignore duplicate inbound ids
  7. Observability — persist Transaction Event timeline (and action outcomes) per document for audits

For copy-paste HTTP examples of each step, use Send and receive invoices.