SupplierDocuments
The SupplierDocument entity represents a document you received from one of your Suppliers: a purchase invoice, a credit note, ... It is the purchase-side counterpart of the Document you issue to your Customers.
Supplier documents enter INFast in two ways: they are received through the e-invoicing network, or they are imported by hand — from the app, or from the API with the two endpoints described in Create a supplier document. Reading them requires the read scope; importing one or changing its status requires the write scope.
Data format
Common fields
The SupplierDocument object includes the id, portalId and lastUpdate common-fields. It does not carry a metadata field.
Specific fields
You can find the detailed format for input and output in the reference.
-
supplierIdandsupplier:supplierIdis the id of the Supplier the document comes from.supplieris the supplier information as captured when the document was received: it may differ from the current information of the supplier, which evolves independently. -
type:invoice,creditNote,debitNote,selfBilledInvoice, orunknownwhen the type could not be determined. -
status: the current status of the document, with the reason that led to it when relevant. -
origin: how the document entered INFast —manualImportwhen a user uploaded it,iopolewhen it was received through the e-invoicing network. -
dueAmountandremainingAmountToPay:dueAmountis what has to be paid to the supplier for this document.remainingAmountToPayis the part of it that the registeredpaymentsdo not cover yet. -
payments: the payments registered on the document. Each one is eithersent(you paid the supplier) orreceived(the supplier acknowledged having received the payment). -
vatSummary: the VAT amounts detailed by VAT rate, in the same shape as thevatSummaryof a Document. You send it in that same shape when you create a document.
Status
| Status | Meaning |
|---|---|
pending | Received, but not reviewed yet. |
processing | The PDF of the document is still being generated. |
approved | Approved by the buyer. |
disputed | Partially approved, disputed or suspended. |
refused | Refused by the buyer. |
payment_sent | A payment has been sent to the supplier. |
payment_received | The supplier acknowledged having received the payment. |
On a disputed or a refused document, status.reason carries the normative reason code that justifies the status, and status.details a free text completing it. A document refused or disputed from INFast always carries OTHER, the explanation being in status.details. One refused or disputed through the e-invoicing network carries the code chosen there, which can be any reason code of the French e-invoicing reform — so expect to read reason codes you cannot write, see below.
Change the status
PATCH /supplier-documents/{id}/status moves a document to a new status, with the very same rules as the INFast app.
status | Meaning | Body |
|---|---|---|
approved | You approve the document. | — |
refused | You refuse the document. | details. |
disputed | You dispute or suspend the document. | details. E-invoicing documents only. |
payment_sent | You declare a payment sent to the supplier. | payment.amount, and optionally payment.currency. |
The transitions allowed on a document depend on its current status and on its origin: any other transition returns a 400, and so does a details or a payment that the target status does not expect.
There is no reason to send. INFast exposes a single normative reason code, OTHER, and it always comes with a free text: a document you refuse or dispute through this endpoint is therefore recorded with status.reason set to OTHER and your details as the explanation. Reason codes coming from the e-invoicing network remain readable on status.reason and in the status history; they just cannot be set here.
A payment that does not cover the remainingAmountToPay is registered as a partial payment: it is added to payments but the status of the document does not change yet.
curl -L -X PATCH 'https://api.infast.fr/api/v2/supplier-documents/63e3c82675de4f6978054579/status' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer [access_token]' \
--data-raw '{ "status": "refused", "details": "The total does not match the purchase order" }'
Status history
GET /supplier-documents/{id}/events returns the status changes recorded on a document, most recent first, paginated with limit and skip.
Each event carries the date of the change, the status the document moved to, and the source that triggered it — infast for a change made from your portal (the app or the API), iopole for one received from the e-invoicing network. A change coming from the network also carries the raw normativeStatusCode it was built from.
{
"data": [
{
"date": "2024-04-30T09:12:00.000Z",
"status": "refused",
"source": "infast",
"reason": "OTHER",
"details": "The total does not match the purchase order",
"userId": "63e3c82675de4f6978054579"
}
]
}
Create a supplier document
Importing a supplier document takes two requests: you upload its PDF, then you create the document itself from the key the upload returned. Both require the write scope.
1. Upload the PDF
POST /supplier-documents/upload-asset takes the file as a multipart/form-data body, in a file field. Only PDFs are accepted — a file of any other type is rejected with a 400.
curl -L -X POST 'https://api.infast.fr/api/v2/supplier-documents/upload-asset' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer [access_token]' \
-F 'file=@invoice.pdf;type=application/pdf'
{
"assetKey": "incoming/63e3c82675de4f6978054579/9f1b7c6e-0f1a-4f0e-9a3d-2b5e6c7d8e90.pdf",
"signedUrl": "https://storage.infast.fr/infast-supplier-documents/incoming/..."
}
The assetKey is temporary: it belongs to your portal, and the creation below consumes it. Reusing a key that has already been consumed fails with a 400.
2. Create the document
POST /supplier-documents takes the assetKey of the upload as its fileKey, along with the fields of the document. The supplierId must be one of your suppliers — create it first if needed.
curl -L -X POST 'https://api.infast.fr/api/v2/supplier-documents' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer [access_token]' \
--data-raw '{
"fileKey": "incoming/63e3c82675de4f6978054579/9f1b7c6e-0f1a-4f0e-9a3d-2b5e6c7d8e90.pdf",
"supplierId": "63e3c82675de4f6978054579",
"reference": "FA-2024-0012",
"type": "invoice",
"issueDate": "2024-04-29T00:00:00.000Z",
"dueDate": "2024-05-29T00:00:00.000Z",
"totalWithoutVat": 100,
"totalVatAmount": 20,
"totalWithVat": 120,
"vatSummary": [
{
"vat": 20,
"vatPart": 20,
"amount": 100
}
]
}'
The response is the created supplier document, in a data object, in the same shape as GET /supplier-documents/{id}. It is a manualImport, in the approved status and in euros, and carries the snapshot of the supplier as it is at that moment.
The amounts you send are not recomputed. There is no dueAmount to send: a document imported this way is due for its totalWithVat, and remainingAmountToPay starts from there — register a payment with PATCH /supplier-documents/{id}/status to bring it down.
Retrieve the PDF
GET /supplier-documents/{id}/pdf returns the PDF encoded in base64, in the same format as GET /documents/{id}/pdf.
curl -L -X GET 'https://api.infast.fr/api/v2/supplier-documents/63e3c82675de4f6978054579/pdf' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer [access_token]'
{
"pdfB64": "JVBERi0xLjcKJeLjz9MK..."
}
A document whose PDF is not available yet — for example an uploaded image that is still being converted, which you recognize by its processing status — returns a 404 on this endpoint.