“Can you automate our supplier invoices?” Say yes.
It is the request that reaches you every month, and until now it was hard to say yes to. DocFlow reads and validates your clients' supplier invoices and delivers them through the door the ERP exposes: your endpoint with a signature, a SQL script for the import table, or the archive their process already looks at. You keep the client.
Why you can say yes now
You installed the ERP and the client keeps asking you for what the ERP does not solve. Three reasons to say no, and what changes in each.
Without writing to the database
We deliver through the door the ERP exposes: your endpoint, a SQL script for the import table, or a file. Numbering, calculating and posting stay with the ERP.
See how it fitsWith the scope written on one page
Five questions for the client before you take the job, the exact request shown before any code exists, and a test key the same day.
See the five questionsWhat does not add up does not go in
Tax number check digit, line totals against the invoice total, duplicates, the invoice's QR code. Whatever fails stops for review instead of going in wrong.
See the guaranteesHow we work with partners
Four things that do not change, whatever the ERP.
- The client is yours. You are the ones who talk to them, write the routine and bill the implementation. We keep the reading, the rules and the technical support for the integration.
- Flows are configured with us. Tell us which fields you want, where, and with which rules. Change requests are usually applied the same day. It is not self-service, and that is deliberate.
- It starts in a test environment. Your own key and a dedicated mailbox, the same day. The contract is the same as production; when you move, only the URLs and the key change.
- You pay per document. Setup tailored to the process, then per document processed, with no per-user licences. The tiers are on the pricing page.
The technical part
What whoever will connect the client's system needs to know, in order. The request and response examples open on click.
How it fits
We come in ahead of the ERP and deliver through the door it exposes, instead of writing into the database underneath. A direct INSERT skips numbering, stock, accounting and tax, and it is the first objection any consultant raises.
You submit
A POST with the file, from your application or from a process you already run. PDF or image, up to 25 MB. If the end user would rather forward an email, there is a dedicated mailbox that takes the same path.
We read and check
Header and line items. Then the rules: the tax number passes its check digit, the line items add up to the total, the duplicate is caught. What does not add up stops for human review instead of going in wrong.
We deliver
To your endpoint, signed. And in parallel wherever else it is needed: spreadsheet, SharePoint archive, SQL script. There is no need to pick just one.
From the button to the number
The case for those who already have an application of their own: the user clicks a button you already have, and the document shows up in the client system with a number assigned. There is no screen of ours in between.
See the request and the response
1. The button submits
POST /ingest/<INBOX_ID>
{ "data": { "document_id": "a3f1…", "status": "queued",
"tracking_url": "https://app.docflow.pt/documents/a3f1…",
"routing": { "flow_id": "…", "strategy": "default_flow" } },
"error": null }
2. And asks how it went
GET /ingest/<INBOX_ID>/documents/a3f1…
{ "data": { "status": "delivered",
"client_metadata": { "encomenda": "ENC-2026-8842" },
"deliveries": [
{ "name": "Pedido API para o PHC", "status": "delivered",
"document_ref": "FT 2026/1187",
"document_url": "https://erp.cliente.pt/documentos/1187" } ] },
"error": null }
The document_ref and the document_url are what your system returned when it received the document. They come back here so the button can show the number it ended up with, instead of just «sent». We accept the usual keys (id, numero, obrano, stamp), at the root of the response or inside data.
If you would rather not ask, we call an address of yours on every status change, including when the document stops for review. It is switched on in your delivery connection, on our side and on the same day: the notices go to the same address that receives the documents, or to another one you give us, with the same signature.
Document states: received, extracting, extracted, pending_approval, approved, delivering, delivered. And also failed, rejected and needs_routing. The happy ending is delivered with every delivery delivered.
See the reference go and come back
This is the detail that separates an integration from a file drop. On submission you send whatever identifies the process on your side:
curl -X POST "https://api.docflow.pt/ingest/<INBOX_ID>" \
-H "Authorization: Bearer dfl_live_…" \
-H "Idempotency-Key: $(uuidgen)" \
-F "file=@fatura.pdf;type=application/pdf" \
-F 'metadata={"encomenda":"ENC-2026-8842","operador":"amaral"}'
That field becomes reachable in the destination mapping as _meta.encomenda, and comes out in what we deliver:
{ "adoc": "FT 2026/1187", "ncont": "501234567",
"etotaldeb": 475.89, "encomenda": "ENC-2026-8842" }
And it comes back in the status call, exactly as sent, so you do not have to keep a lookup table on your side. There is no list of recognised names: _meta. followed by whatever key you send.
Without it, the invoice reaches your system with no link to the process that produced it, and somebody has to match it by hand at the other end. Which is exactly the work this exists to remove.
Guarantees
What the integration honours, with the numbers written down.
No duplicates on retries
An idempotency header of your own per submission. Repeating the request returns the original response instead of creating a new document. As a second line, the same file submitted twice stops for review.
Your process asks whether it is done
A GET returns the status and each delivery. Ask for the payload and it also returns the mapped data that went to each destination. Nobody has to open a screen to learn the result.
Or it does not ask, and we tell you
Instead of polling, we call an endpoint of yours on every status change, with an HMAC-SHA256 signature and automatic retries.
Delivery arrives signed
The request carries the document id and the delivery id, so you can de-duplicate on your side, and an optional signature so you can verify it came from us.
Errors say whose fault it is
Every response carries the same envelope, error responses included, with a code of its own. If you get HTML instead, it came from the network layer in front of the API and not from us.
The limits are written down
60 requests per minute and 1000 per day on submission; 240 and 20,000 on status, counted separately. The 429 carries the wait time and the window.
The five questions for the client
Ask them before you take the job; they decide whether the project takes two weeks or two months. They hold for any tool.
- Does the ERP expose a web service for entering documents, or what is the supported path? Never the final table.
- Which fields are mandatory for the posting to go through, and which are not on the paper?
- Is there a mapping table between the supplier's references and the client's?
- Where does the scanned document live?
- Who reviews whatever is doubtful, and how fast?
With the five answered, the rest is on us: the mapping, the rules, the test environment. The article with the questions in full (in Portuguese).
Questions from people who integrate
Which ERP does this go into?
Any of them: the connector is built to measure for the client's ERP, with you. Delivery is an HTTP request to your endpoint, a SQL script, or a file, and when the ERP has an API of its own we write and maintain the link to that API. That is why this page talks about an endpoint and not about a list of ERPs: you are the ones who know the client's system, and we deliver in the format it accepts.
What can be mapped without writing code?
Any field of the document to any name your system expects, lookups against the client's reference tables (items, suppliers, accounts) with typo recovery confirmed by a second field, and line numbering following the ERP's convention. Calculations and conditions, no: those stay on your side or on ours, in the configuration.
Can we prove the fit before there is an endpoint?
Yes, and it is the path we recommend. One destination builds the request and shows it without sending it, and another generates the SQL script. You see the exact body that would go out, with the fields already mapped, before any code exists on your side.
What do we not do?
- It is not self-service The key is issued by us and handed over once. There is no portal where you manage it, or where you create environments on your own.
-
There is an integration guide, handed over with the key. It is
multipart/form-datain and JSON out, so any language gets there with what it already has. - Your account is operational The documents of your organisation, approval and reprocessing, counts and times, and the view of the configured flows.
Next time a client asks, say yes.
Tell us which system you installed. A twenty minute conversation is enough to know whether it fits, and you leave it with a test environment and a key.
Talk to us