The Dolibarr REST API, from the key to a paid invoice
Enable the Dolibarr REST API, create an API key for a dedicated user, then create a customer, an invoice, its PDF and its payment with curl. Including the trap of invoice lines that change order.
Dolibarr ships a REST API: everything you do on screen (third parties, invoices, orders, products…) can be done from another program, a website or a script. This page starts from scratch and goes all the way to a validated invoice, with its PDF and its payment. Every command was run on 13 October 2026 against a fresh Dolibarr 24.0.1 instance.
Along the way, three behaviours worth knowing that the documentation does not mention:
- lines sent together with the invoice change order on the invoice and on the PDF;
- an invoice validated through the API has no PDF until you ask for one;
- when the module is disabled, the API still answers “200 OK”.
1. Enable the module
Setup › Modules/Applications, module API / Web services (REST server). Its setup page gives the explorer address and lets you restrict access to some IP addresses.
While the module is disabled, every API address answers with code 200 and this text:
Module <b>Api</b> must be enabled.<br><br>To activate modules, go on setup Area (Home->Setup->Modules).
A script that only checks the HTTP code will think all is well: also check that the response is JSON.
Enable the modules whose data you want as well. For this page: Third Parties, Invoices and, for payments, Banks & Cash. The APIs of a disabled module do not show up.
2. Create a dedicated user and its key
The API key carries exactly the permissions of the user it belongs to. Do not create it on your administrator account: create a user reserved for the API.
- Users & Groups › New user: a name, a login (for example
api-invoicing). - On the Token for API line, click Generate: a 32-character key appears. Copy it, then Create user.
- Permissions tab: grant only what is needed. For everything below, this was enough:
| Module | Permissions |
|---|---|
| Third Parties | Read third parties linked to user; Create/modify third parties linked to user |
| Invoices | Read customer invoices (and payments); Create/modify customer invoices; Create payments for customer invoices |
The user record then shows the key as “Hidden”: it is stored encrypted in the database. To see it again, open the record with Modify.
3. The first call
Every address starts with https://your-dolibarr/api/index.php/. The key goes in the DOLAPIKEY
header:
DOLI=https://your-dolibarr/api/index.php
KEY=paste_your_key_here
curl -s -H "DOLAPIKEY: $KEY" "$DOLI/status"
{
"success": {
"code": 200,
"dolibarr_version": "24.0.1",
"access_locked": "0"
}
}
The Authorization: Bearer <key> header works too. Dolibarr also accepts the key in the address
(?DOLAPIKEY=…), but it then ends up in server and proxy logs: prefer the header.
The errors you will meet
| Response | Cause |
|---|---|
| 401 “Neither parameter ‘HTTP_DOLAPIKEY’ nor ‘Authentication: Bearer’ found” | No key sent |
| 401 “Error user not valid (not found with api key or bad status…)” | Wrong key, or user disabled or outside its validity dates |
| 403 “Forbidden” | Right key, but the user lacks the required permission |
| 200 with “Module Api must be enabled” | API module disabled |
400 “Invalid value specified for accountid” |
Payment without a bank account (see step 8) |
4. Create a customer
curl -s -X POST -H "DOLAPIKEY: $KEY" -H "Content-Type: application/json" \
-d '{"name": "Martin Bakery", "client": 1}' \
"$DOLI/thirdparties"
The response is simply the id of the new third party, for example 1. "client": 1 makes it a
customer. To find a third party by name:
curl -s -G -H "DOLAPIKEY: $KEY" \
--data-urlencode "sqlfilters=(t.nom:like:'Martin%')" \
"$DOLI/thirdparties"
5. Create the invoice, then its lines one by one
The API accepts an invoice with its lines in a single call (a lines array). Don’t. In our
tests the lines changed order: sent as 1, 2, 3, they showed on the invoice and on the PDF as 2, 1,
3, and as 3, 1, 2 when each line’s rank was given. During creation, Dolibarr believes it is
inserting each line between the others and shifts ranks wrongly. The same code is in 24.0.2 and in
the development branch.
Create the invoice on its own first:
curl -s -X POST -H "DOLAPIKEY: $KEY" -H "Content-Type: application/json" \
-d '{"socid": 1, "type": 0, "date": "2026-10-13"}' \
"$DOLI/invoices"
The response is the invoice id (here 4). socid is the customer id and "type": 0 means a
standard invoice. A YYYY-MM-DD date is accepted. Then add each line, in the order you want:
curl -s -X POST -H "DOLAPIKEY: $KEY" -H "Content-Type: application/json" \
-d '{"desc": "Dolibarr installation", "qty": 1, "subprice": 690, "tva_tx": 20, "product_type": 1}' \
"$DOLI/invoices/4/lines"
subprice is the unit price excluding tax, tva_tx the VAT rate, and product_type is 1 for a
service, 0 for a product. The invoice stays a draft, with a temporary reference such as (PROV4).
6. Validate the invoice
curl -s -X POST -H "DOLAPIKEY: $KEY" "$DOLI/invoices/4/validate"
The response holds the full invoice, with its final reference ("ref": "FA2610-0001").
7. Generate and fetch the PDF
On screen, validation produces the PDF. Through the API it does not: after validation, the invoice folder holds no PDF. Ask for it explicitly, with the reference you got:
curl -s -X PUT -H "DOLAPIKEY: $KEY" -H "Content-Type: application/json" \
-d '{"modulepart": "invoice", "original_file": "FA2610-0001/FA2610-0001.pdf", "langcode": "en_US"}' \
"$DOLI/documents/builddoc" > /dev/null
The file is then stored in Dolibarr, as if you had generated it on screen. To download it, the API
returns its content base64-encoded (decoded here with jq):
curl -s -H "DOLAPIKEY: $KEY" \
"$DOLI/documents/download?modulepart=invoice&original_file=FA2610-0001/FA2610-0001.pdf" \
| jq -r .content | base64 -d > FA2610-0001.pdf
8. Record the payment
A payment must belong to an account of the Banks module: without accountid, the API answers
“Invalid value specified for accountid”. The account id can be read in the address of its record
(…/compta/bank/card.php?id=1). The payment method id can be found through the API:
curl -s -H "DOLAPIKEY: $KEY" "$DOLI/setup/dictionary/payment_types"
On a fresh install: 2 transfer, 4 cash, 6 card, 7 cheque. Then:
curl -s -X POST -H "DOLAPIKEY: $KEY" -H "Content-Type: application/json" \
-d '{"datepaye": "2026-10-13", "paymentid": 2, "closepaidinvoices": "yes", "accountid": 1, "num_payment": "TRF-001"}' \
"$DOLI/invoices/4/payments"
With "closepaidinvoices": "yes", a fully paid invoice moves to the paid status.
The explorer, for everything else
At https://your-dolibarr/api/index.php/explorer/, Dolibarr lists all its APIs. Paste the key in
the field at the top right and click Explore: without a key, only the login API shows. Every
call is documented there and can be tried; the list depends on the enabled modules. The same
description, in Swagger format, is at /api/index.php/explorer/swagger.json.
Good practice
- One user per use (website, invoicing tool, script…), each with its own permissions only: you can cut one off without touching the others.
- Always over HTTPS: the key travels with every request.
- If the API only serves a known server, restrict access to its IP address in the module setup.
To connect Dolibarr to another program without writing the code yourself, the Custom module package starts from a precise quote.