Transactions
A transaction is one send or receive operation for a document on a single channel. It is created when you trigger a send, or when a document is received.
Use transactions to track that delivery attempt: processing, completed, or failed. One document can have multiple transactions (first send, resend, receive on another channel, and so on).
See also Document model and Status lifecycle.
Transaction types
Types combine direction (send / receive) and channel:
| Type | When created | Channel |
|---|---|---|
send.email |
You send the document by email | |
receive.email |
Document received by email | |
send.peppol |
You send via Peppol | Peppol |
receive.peppol |
Document received via Peppol | Peppol |
send.ksef |
You send via KSeF | KSeF |
receive.ksef |
Document received via KSeF | KSeF |
send.france |
You send via the France channel | France |
receive.france |
Document received via the France channel | France |
France send/receive details: Send and receive invoices.
Transaction lifecycle
Each transaction has a status (for example initial → processing → completed or failed). Document status usually follows that step (for example send.processing, then send.completed or send.failed). See Status lifecycle.
Events and actions
Transactions can expose more than a single status:
| Concept | Meaning | Who creates it |
|---|---|---|
| Event | Something that already happened (sent, received, accepted, …) | xTool / channel |
| Action | Something you ask xTool to do (for example approve or refuse an incoming France invoice) | You (API / web) |
Events are history. Actions are commands. Successful actions typically produce matching events later.
France buyer actions today:
| Action type | Body | Typical resulting event |
|---|---|---|
france.invoice.acknowledge |
{ "type": "france.invoice.acknowledge" } |
france.invoice.acknowledged |
france.invoice.approve |
{ "type": "france.invoice.approve" } |
france.invoice.approved |
france.invoice.partially_approve |
{ "type": "...", "amount": "...", "reason": "..." } |
france.invoice.partially_approved |
france.invoice.dispute |
{ "type": "france.invoice.dispute", "reason": "..." } |
france.invoice.disputed |
france.invoice.refuse |
{ "type": "france.invoice.refuse", "reason": "..." } |
france.invoice.refused |
france.invoice.payment_sent |
{ "type": "france.invoice.payment_sent" } (receive.france) |
france.invoice.payment_sent |
france.invoice.payment_received |
{ "type": "...", "amount"?: "...", "currency"?: "...", "paid_at"?: "..." } (send.france) |
Creates a Payment; event france.invoice.payment_received |
Metadata
For France transactions (send.france / receive.france), the API may expose client-safe metadata such as:
Internal provider identifiers are not returned in the public API response.
API overview
| Method | Path | Notes |
|---|---|---|
GET |
/api/v2/transactions |
List. Filter by document_id, transaction_type, transaction_status |
GET |
/api/v2/transactions/{transaction_id} |
Get one. Optional include=status_log, events, actions |
GET |
/api/v2/transactions/{transaction_id}/events |
List events (includes event files) |
GET |
/api/v2/transaction-events/{transaction_event_id} |
Get one event (includes files) |
GET |
/api/v2/transaction-event-files/{transaction_event_file_id}/download |
Download an event file |
GET |
/api/v2/transactions/{transaction_id}/actions |
List actions |
POST |
/api/v2/transactions/{transaction_id}/actions |
Create an action |
include=events on transaction get also loads nested event files.
There is no get-by-id endpoint for a single action. Use the actions list, or include=actions on the transaction get.
Example — transaction with nested data:
Example — transactions for one document:
Relation to document status
Document status reflects the latest step in the document lifecycle. To inspect one specific send or receive, open that transaction (with status_log / events as needed).
Where to see transactions
- Web — Usage → Transactions (filter by status, type, date). See Usage.
- API — endpoints in the table above.