Difference between revisions of "Module Web Services API REST (developer)"

From Dolibarr ERP CRM Wiki
Jump to navigation Jump to search
Tag: 2017 source edit
 
(44 intermediate revisions by 7 users not shown)
Line 1: Line 1:
 +
<!-- BEGIN origin interlang links -->
 +
<!-- You can edit this section but do NOT remove these comments
 +
    Links below will be automatically replicated on translated pages by PolyglotBot -->
 +
[[fr:Module_Web_Services_API_REST_(développeur)]]
 +
[[ja:Module_Web_Services_API_REST_(developer)_JA]]
 +
[[zh:提供REST_API的Web服务模块(开发者)]]
 +
<!-- END interlang links -->
 +
 
{{TemplateDocDevEn}}
 
{{TemplateDocDevEn}}
 
{{TemplateModEN}}
 
{{TemplateModEN}}
Line 8: Line 16:
 
userdoc=Not applicable|}}
 
userdoc=Not applicable|}}
  
 +
=Function=
 +
When enabling this module, you enable usage of web services provided by Dolibarr server. You can then make REST call of different web services provided by Dolibarr.
 +
 +
=Installation=
 +
 +
To install, open the modules page and activate de "API REST" module.
 +
 +
Once module webservices REST is activated, Dolibarr become also a server of REST web services. So you can send your own REST request to relative URL
 +
'''/api/index.php/xxx''' where xxx is name of the API to call.
 +
 +
A list of APIs on your installation can be found via the explorer. Click on link to explorer to open the API explorer.
 +
 +
==Apache setup==
 +
There is nothing to do. If your Dolibarr is working with Apache, the REST API should also work. APIs will be served by the same virtual web server than your application.
 +
 +
==Nginx setup==
 +
Like Apache, if your Dolibarr is working inside a NGinx virtual host, you should have nothing to do to have your API working. APIs will be served by the same virtual web server than your application.
 +
 +
However, NGinx default setup on a lot of distribution is often a gaz engine and you may experience troubles. If you experience such troubles, you can try to edit your NGinx config file to match the following example. This is a simple localhost setup with a working REST API handling (tested with 9.0.1 on parabola gnu/linux).
 +
 +
<syntaxhighlight lang="nginx">
 +
worker_processes  1;
 +
error_log  /var/log/nginx/error.log;
 +
 +
events {
 +
    worker_connections  1024;
 +
}
 +
 +
 +
http {
 +
    include      mime.types;
 +
    default_type  application/octet-stream;
 +
 +
    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
 +
    #                  '$status $body_bytes_sent "$http_referer" '
 +
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
 +
 +
    #access_log  logs/access.log  main;
  
 +
    sendfile        on;
 +
    #tcp_nopush    on;
  
 +
    #keepalive_timeout  0;
 +
    keepalive_timeout  65;
  
 +
    #gzip  on;
  
 +
    server {
 +
    listen 80;
 +
        server_name    dolibarr.localhost; # adjust to your domain
  
 +
        root    /usr/share/webapps/dolibarr/htdocs; # adjust to your path
 +
        index  index.php;
  
 +
        # from https://github.com/Dolibarr/dolibarr/issues/6163#issuecomment-391265538
 +
        location ~ [^/]\.php(/|$) {
 +
            fastcgi_split_path_info ^(.+?\.php)(/.*)$;
 +
            if (!-f $document_root$fastcgi_script_name) {
 +
                return 404;
 +
            }
  
= Function =
+
            # Mitigate https://httpoxy.org/ vulnerabilities
When enabling this module, you enable usage of web services provided by Dolibarr server. You can then make REST call of different web services provided by Dolibarr.
+
            fastcgi_param HTTP_PROXY "";
  
= Dolibarr REST web services server =
+
            root          /usr/share/webapps/dolibarr/htdocs;
Once module webservices REST is activated, Dolibarr become also a server of REST web services. So you can send your own REST request to relative URL
+
            fastcgi_pass  unix:/run/php-fpm/php-fpm.sock;
'''/api/index.php'''
+
            fastcgi_index  index.php;
 +
            include        fastcgi_params;
 +
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
 +
            # Dolibarr Rest API path support
 +
            fastcgi_param  PATH_INFO      $fastcgi_path_info;
 +
            fastcgi_param  PATH_TRANSLATED $document_root$fastcgi_script_name;
 +
        }
 +
    }
 +
}
 +
</syntaxhighlight>
  
= List of provided services =
+
=List of provided services=
Only few services are available. Starting to Dolibarr 5.0 version, you can see full list of Dolibarr Webservices provided, by calling the explorer here at address:
+
Only few services are available. You can see full list of Dolibarr Web services provided, by calling the explorer here at address:
  
 
'''http://yourdolibarrurl/api/index.php/explorer'''.
 
'''http://yourdolibarrurl/api/index.php/explorer'''.
 
You must first make the first call to the '''login''' api to get the api key.
 
Then enter api key to get list of all other available services.
 
  
 
For example, you can try the explorer on the demo instance at:
 
For example, you can try the explorer on the demo instance at:
Line 34: Line 102:
 
'''https://demo.dolibarr.org/api/index.php/explorer'''
 
'''https://demo.dolibarr.org/api/index.php/explorer'''
  
You must first make the first call to the '''login''' api to get the api key.
 
Then enter api key to get list of all other available services.
 
  
= Adding a new service =
+
On the top right corner, paste the <token> of the user you want to use to call the API and click the "explore" button. Note: The token of each user can be defined on the user record page.
Adding a new REST service is as easy than adding a file called '''api_mymoduleobject.class.php''' into the directory '''htdocs/module/class'''.
+
If you prefer, you can first make a first call to the '''login''' API to get the API token key. Then enter API key to get list of all other available API services.
You take the example into '''htdocs/commande/class/api_orders.class.php'''
+
 
 +
 
 +
After clicking on "Explore", you should see all the actions available with this token. If you don't have a lot of actions, it's probably because the according modules are not activated. If you want to see the invoices, you have to activate the invoice module in the configuration of Dolibarr. Same for products, third parties and so on.
  
The framework detects automatically the API and it should be visible into the explorer.
+
On this exploration page of the API, you can do quite a lot of tests. Reading datas from Dolibarr and writing, modifying and deleting as well. Warning: Data are really modified in your database.
  
Method and parameters are detected according to introspection done into PHP class of the object ('''htdocs/module/class/object.class.php''') using the '''annotations''' found into the class.
+
You can then test directly from the explorer tool any API. This is the recommended solution to test any Dolibarr API since any API and parameters is documented here. As a result of any test, you will get the answer but also example on how to call the API from command line using '''curl'''.
For a documentation about annotation: https://github.com/Luracast/Restler/blob/master/ANNOTATIONS.md
 
  
= Installation =
+
=Use=
  
To install, open the modules page and activate de API REST module. On the configuration page of the module, There's two links. No need to click on the first, it doesnt work as is.
+
To use the REST API,  you have to call an url such as this one : <nowiki>http://<my_server>/api/index.php/<action></nowiki><br />
 +
with one of the 4 following methods : GET, POST, PUT, DELETE, replacing <action> by the action you want to use. Ex : <nowiki>http://<my_server>/api/index.php/invoices</nowiki>
  
The link has this pattern = <nowiki>http://<my server>/api/index.php/login?login=<user login>&password=yourpassword</nowiki><br/>
+
Before using any API, you must first get a custom API-key. You have to create a new user and generate or set its "Key for API".
copy the link and replace yourpassword by your user password. <my server> and <user login> should have been already replaced. Past the link in your browser to generate your <token>. This token is linked to the user account.<br/>
 
  
Write down this <token> as you will need it later !!!
+
[[File:Dolibarr user for api.png|400px]]
  
Now, You can use the second link on the configuration page of the module. On the top right corner, paste your <token> and click the "explore" button. You should see all the actions available with this token. If you don't have a lot of actions, it's probably because the according modules are not activated. If you want to see the invoices, you have to activate the invoice module in the configuration of Dolibarr. Same for products, thirdparties and so on.<br/>
 
On this exploration page of the API, you can do quite a lot of tests. Reading datas from Dolibarr and writing, modifying and deleting as well.
 
  
= Use =
+
You will have to use this API key in any of your client program that need to call a Dolibarr API.
  
To use the REST API,  you have to call an url such as this one : <nowiki>http://<my_server>/api/index.php/<action></nowiki><br/>
 
with one of the 4 following methods : GET, POST, PUT, DELETE, replacing <action> by the action you want to use. Ex : <nowiki>http://<my_server>/api/index.php/invoices</nowiki>
 
  
 +
==Client code example==
 +
 +
===PHP===
 
There's different ways to do so. Here's a piece of code but you can also use libraries such as phphttpclient.com
 
There's different ways to do so. Here's a piece of code but you can also use libraries such as phphttpclient.com
  
 
+
<syntaxhighlight lang="php">
<source lang="php">
 
 
// Example of function to call a REST API
 
// Example of function to call a REST API
 
function callAPI($method, $apikey, $url, $data = false)
 
function callAPI($method, $apikey, $url, $data = false)
Line 110: Line 175:
  
 
     return $result;
 
     return $result;
}</source>
+
}</syntaxhighlight>
 +
 
 +
This is just a working example. There's no error control and security was not in mind but you can use this code, modify it to suit your needs<br />
 +
The fonction has 4 parameters :
 +
 
 +
*$method : string, "GET", "POST", "PUT", "DELETE"
 +
*$apikey : string, "your <token> generated earlier"
 +
*$url : string, url to call. Ex : "<nowiki>http://<my_server>/api/index.php/invoices</nowiki>"
 +
*$data : string, datas in json format. This parameter is not mandatory.
 +
 
 +
===Javascript Ajax===
 +
 
 +
<syntaxhighlight lang="javascript">
 +
<script>
 +
$.ajax({
 +
  type: 'GET',
 +
  async: true,
 +
  contentType: "application/json; charset=utf-8",
 +
  data: { 'lang': 'en_US' },
 +
  dataType: "json",
 +
  cache: false,
 +
  jsonp: false,
 +
  headers: {
 +
    'DOLAPIKEY': 'abcdef123456'
 +
  },
 +
  url: 'https://myserver/api/index.php/theapi',
 +
  success: function(rep) {
 +
    console.log("API call success");
 +
    console.log(rep);
 +
  },
 +
  error: function(rep) {
 +
    console.log("API call error");
 +
    console.log(rep);
 +
  }
 +
});
 +
</script>
 +
</syntaxhighlight>
 +
 
 +
==Accepted parameters==
 +
This is documented somewhat in the REST Explorer. Check that first. Second try and see what response you get. Third look at the source code for the given API.
 +
 
 +
===sqlfilters===
 +
They are passed on to the database after a check.
 +
These work on the product endpoint:
  
 +
*(t.fk_product_type: = :'0') and (t.tosell: = :'1') and (t.label: ilike :'%string')
  
This is just a working example. There's no error control and security was not in mind but you can use this code, modify it to suit your needs<br/>
+
===Date===
The fonction has 4 parameters :
+
The ISO date format is accepted: %Y-%m-%d e.g. 2020-07-14. yymmdd is not accepted.
* $method : string, "GET", "POST", "PUT", "DELETE"
 
* $apikey : string, "your <token> generated earlier"
 
* $url : string, url to call. Ex : "<nowiki>http://<my_server>/api/index.php/invoices</nowiki>"
 
* $data : string, datas in json format. This parameter is not mandatory.
 
  
= Examples =
+
=Examples with PHP=
  
 
This is more examples, for different uses cases:
 
This is more examples, for different uses cases:
  
 
In every examples, we have:
 
In every examples, we have:
* $apiKey = "my <token>";
 
* $apiUrl = "<nowiki>http://<my_server>/api/index.php/</nowiki>";
 
  
<source lang="php">
+
*$apiKey = "<my token>";
 +
*$apiUrl = "<nowiki>http://<my_server>/api/index.php/</nowiki>";
 +
 
 +
<syntaxhighlight lang="php">
 
// Retrieve products list
 
// Retrieve products list
 
$listProduits = [];
 
$listProduits = [];
Line 141: Line 247:
 
}
 
}
 
}
 
}
</source>
+
</syntaxhighlight>
 
Comments :
 
Comments :
* I retrieve the 10'000 first products sorted on their ID in the base
+
 
* html_entity_decode is necessary as single quotes are encoded
+
*I retrieve the 10'000 first products sorted on their ID in the base
* It's easy to use the same method (replacing products with dictionnarycountries) to retrieve the list of countries and their ID
+
*html_entity_decode is necessary as single quotes are encoded
 +
*It's easy to use the same method (replacing products with dictionnarycountries) to retrieve the list of countries and their ID
  
  
<source lang="php">
+
<syntaxhighlight lang="php">
 
// Create a product
 
// Create a product
 
$ref = "my_product_ref_X203ZZ";
 
$ref = "my_product_ref_X203ZZ";
Line 157: Line 264:
 
$newProductResult = CallAPI("POST", $apiKey, $apiUrl."products", json_encode($newProduct));
 
$newProductResult = CallAPI("POST", $apiKey, $apiUrl."products", json_encode($newProduct));
 
$newProductResult = json_decode($newProductResult, true);
 
$newProductResult = json_decode($newProductResult, true);
</source>
+
</syntaxhighlight>
 
Comments :
 
Comments :
* before creating a product, it could be wise to check if it exists. Using my first example, you'll have  :
+
 
 +
*before creating a product, it could be wise to check if it exists. Using my first example, you'll have  :
  
  
<source lang="php">
+
<syntaxhighlight lang="php">
 
// my ref
 
// my ref
 
$ref = "my_product_ref_X203ZZ";
 
$ref = "my_product_ref_X203ZZ";
Line 189: Line 297:
 
}
 
}
 
}
 
}
</source>
+
</syntaxhighlight>
 
Comments :
 
Comments :
* I check if the ref of my product exist in the array created in the first example.
 
* If it exists, I use it's key in the array as ID
 
* If it doesn't exist, I create the product, then I add it to my array for next time then I use the ID created
 
* I choose this method to do less API calls when I have to import 500 orders. I just need to retrieve the products list once at the beginning instead of searching Dolibarr each time.
 
  
 +
*I check if the ref of my product exist in the array created in the first example.
 +
*If it exists, I use it's key in the array as ID
 +
*If it doesn't exist, I create the product, then I add it to my array for next time then I use the ID created
 +
*I choose this method to do less API calls when I have to import 500 orders. I just need to retrieve the products list once at the beginning instead of searching Dolibarr each time.
  
<source lang="php">
+
Warning: The example below is not working properly. Creating an order and lines in one go is not supported. Instead you have to create an order first and with the returned order id add the lines using the /orders/{id}/lines endpoint.
 +
 
 +
<syntaxhighlight lang="php">
 
// create an order with 2 products
 
// create an order with 2 products
  
Line 241: Line 351:
 
$newCommandeResult = json_decode($newCommandeResult, true);
 
$newCommandeResult = json_decode($newCommandeResult, true);
 
}
 
}
</source>
+
</syntaxhighlight>
 
Comments :
 
Comments :
* $clientDoliId is the ID of the customer in the Dolibarr database. Either you know it or you can search for it before
 
* type => 0, This is a customer order (while 1 = supplier order)
 
  
 +
*$clientDoliId is the ID of the customer in the Dolibarr database. Either you know it or you can search for it before
 +
*type => 0, This is a customer order (while 1 = supplier order)
  
<source lang="php">
+
 
 +
<syntaxhighlight lang="php">
 
// Validate an order  
 
// Validate an order  
 
$newCommandeValider = [
 
$newCommandeValider = [
Line 256: Line 367:
 
$newCommandeValiderResult = json_decode($newCommandeValiderResult, true);
 
$newCommandeValiderResult = json_decode($newCommandeValiderResult, true);
  
</source>
+
</syntaxhighlight>
 
Comments :
 
Comments :
* in this example, on the penultimate line, we can see : $apiUrl."orders/".$newCommandeResult."/validate".<br/>
+
 
 +
*in this example, on the penultimate line, we can see : $apiUrl."orders/".$newCommandeResult."/validate".<br />
 +
 
 
$newCommandeResult is the ID of the order created in the previous example
 
$newCommandeResult is the ID of the order created in the previous example
  
  
<source lang="php">
+
<syntaxhighlight lang="php">
 
// search in the database if a customer exist
 
// search in the database if a customer exist
 
$customer_name = "Acme Inc";
 
$customer_name = "Acme Inc";
Line 274: Line 387:
 
)
 
)
 
), true);
 
), true);
</source>
+
</syntaxhighlight>
 
Comments :
 
Comments :
* limit => 1 only 1 customer
 
* mode => 1 we are looking for a customer, not a supplier (they are thirdparties too but with a different status)
 
* sqlfilters a bit special but there are more examples on the explorer page
 
  
 +
*limit => 1 only 1 customer
 +
*mode => 1 we are looking for a customer, not a supplier (they are thirdparties too but with a different status)
 +
*sqlfilters a bit special but there are more examples on the explorer page
  
<source lang="php">
+
 
 +
<syntaxhighlight lang="php">
 
// customer doesn't exist. Let's create it and get it's ID
 
// customer doesn't exist. Let's create it and get it's ID
 
$newClient = [
 
$newClient = [
Line 287: Line 401:
 
"email" => "customer company email",
 
"email" => "customer company email",
 
"client" => "1",
 
"client" => "1",
"code_client" => "-1"
+
"code_client" => "auto"
 
];
 
];
 
$newClientResult = CallAPI("POST", $apiKey, $apiUrl."thirdparties", json_encode($newClient));
 
$newClientResult = CallAPI("POST", $apiKey, $apiUrl."thirdparties", json_encode($newClient));
 
$newClientResult = json_decode($newClientResult, true);
 
$newClientResult = json_decode($newClientResult, true);
 
$clientDoliId = $newClientResult;
 
$clientDoliId = $newClientResult;
</source>
+
</syntaxhighlight>
Comments :
+
 
* client => 1 He is a customer (not a supplier)
+
Comments:
* code_client => -1 so the customer code will be generated automatically.
+
*client => 1, he is a customer.
* we get the customer ID in $clientDoliId
+
*code_client => 'auto' so the customer code will be generated automatically.
 +
*we get the customer ID in $clientDoliId
 +
 
 +
=Examples with Python=
 +
See https://pypi.org/project/dolipy/ (2021) or https://pypi.org/project/dolibarr/ (2019) or https://pypi.org/project/dolibarrpy/ (2024)
 +
 
 +
First you can install the python-module with "pip install dolibarr" or pypi install dolibarrpy
 +
 
 +
<syntaxhighlight lang="python">
 +
from dolibarr import Dolibarr
 +
 
 +
api_url = '<nowiki>http://your-url/dolibarr/htdocs/api/index.php/'</nowiki>
 +
api_key = 'custom_API-Key'
 +
 
 +
# Connection to dolibarr
 +
dolibarr_inst = Dolibarr(api_url, api_key)
 +
 
 +
# create Product
 +
params = {'ref': 'Product_Reference', 'status': '1', 'barcode_type': '6', 'note_public': None,         
 +
 
 +
          'note_private': <nowiki>''</nowiki>, 'specimen': 0, 'label': 'Product_Label',
 +
 
 +
          'description': <nowiki>''</nowiki>, 'type': '0', 'price': <nowiki>''</nowiki>, 'price_ttc': '15.6000000', 'price_base_type': 'TTC',  # excl. tax = HT, incl. tax = TTC
 +
 
 +
          'tva_tx': '19.0000', 'seuil_stock_alerte': '0', 'desiredstock': '0', 'status_buy': '1', 'barcode': 'barcode'}
 +
 
 +
ret_val = dolibarr_inst.call_create_api('products', params)
 +
print(ret_val)
 +
 
 +
# get product list
 +
product_dict = dolibarr_inst.call_list_api('products')
 +
print(product_dict)
 +
</syntaxhighlight>
 +
 
 +
=Develop your own service / API=
 +
Adding a new REST service is as easy than adding a file called '''api_mymoduleobject.class.php''' into the directory '''htdocs/mymodule/class'''.
 +
You can take an example into '''htdocs/commande/class/api_orders.class.php'''
 +
 
 +
Note that if you use the '''modulebuilder''' tool, this file may be generated for you.
 +
 
 +
The framework detects automatically the API files and it should be visible into the explorer.
 +
 
 +
Method and parameters are detected according to introspection done into PHP class of the object ('''htdocs/mymodule/class/object.class.php''') using the '''annotations''' found into the class.
 +
For a documentation about annotation: https://github.com/Luracast/Restler/blob/master/ANNOTATIONS.md
  
= Conclusion =
+
These are just the basics.
  
These are just the basics.<br/>
+
To find all existing API files in Dolibarr, you can search all files htdocs/<directory>/class/api_xxx_class.php
Some more informations in the dolibarr code. You can look here : htdocs/<directory>/class/api_xxx_class.php<br/>
 
Ex : htdocs/societe/class/api_thirdparties.class.php for thirdparties.<br/>
 
Invoices are in htdocs/compta/facture/class
 

Latest revision as of 12:27, 7 August 2024


Web services
Numero/ID of module 2610
User doc. of module Not applicable
Developer doc. of module This page

Function

When enabling this module, you enable usage of web services provided by Dolibarr server. You can then make REST call of different web services provided by Dolibarr.

Installation

To install, open the modules page and activate de "API REST" module.

Once module webservices REST is activated, Dolibarr become also a server of REST web services. So you can send your own REST request to relative URL /api/index.php/xxx where xxx is name of the API to call.

A list of APIs on your installation can be found via the explorer. Click on link to explorer to open the API explorer.

Apache setup

There is nothing to do. If your Dolibarr is working with Apache, the REST API should also work. APIs will be served by the same virtual web server than your application.

Nginx setup

Like Apache, if your Dolibarr is working inside a NGinx virtual host, you should have nothing to do to have your API working. APIs will be served by the same virtual web server than your application.

However, NGinx default setup on a lot of distribution is often a gaz engine and you may experience troubles. If you experience such troubles, you can try to edit your NGinx config file to match the following example. This is a simple localhost setup with a working REST API handling (tested with 9.0.1 on parabola gnu/linux).

worker_processes  1;
error_log  /var/log/nginx/error.log;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
    	listen		80;
        server_name     dolibarr.localhost; # adjust to your domain

        root    /usr/share/webapps/dolibarr/htdocs; # adjust to your path 
        index   index.php;

        # from https://github.com/Dolibarr/dolibarr/issues/6163#issuecomment-391265538
        location ~ [^/]\.php(/|$) {
            fastcgi_split_path_info ^(.+?\.php)(/.*)$;
            if (!-f $document_root$fastcgi_script_name) {
                return 404;
            }

            # Mitigate https://httpoxy.org/ vulnerabilities
            fastcgi_param HTTP_PROXY "";

            root           /usr/share/webapps/dolibarr/htdocs;
            fastcgi_pass   unix:/run/php-fpm/php-fpm.sock;
            fastcgi_index  index.php;
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            # Dolibarr Rest API path support
            fastcgi_param  PATH_INFO       $fastcgi_path_info;
            fastcgi_param  PATH_TRANSLATED $document_root$fastcgi_script_name;
        }
     }		
}

List of provided services

Only few services are available. You can see full list of Dolibarr Web services provided, by calling the explorer here at address:

http://yourdolibarrurl/api/index.php/explorer.

For example, you can try the explorer on the demo instance at:

https://demo.dolibarr.org/api/index.php/explorer


On the top right corner, paste the <token> of the user you want to use to call the API and click the "explore" button. Note: The token of each user can be defined on the user record page. If you prefer, you can first make a first call to the login API to get the API token key. Then enter API key to get list of all other available API services.


After clicking on "Explore", you should see all the actions available with this token. If you don't have a lot of actions, it's probably because the according modules are not activated. If you want to see the invoices, you have to activate the invoice module in the configuration of Dolibarr. Same for products, third parties and so on.

On this exploration page of the API, you can do quite a lot of tests. Reading datas from Dolibarr and writing, modifying and deleting as well. Warning: Data are really modified in your database.

You can then test directly from the explorer tool any API. This is the recommended solution to test any Dolibarr API since any API and parameters is documented here. As a result of any test, you will get the answer but also example on how to call the API from command line using curl.

Use

To use the REST API, you have to call an url such as this one : http://<my_server>/api/index.php/<action>
with one of the 4 following methods : GET, POST, PUT, DELETE, replacing <action> by the action you want to use. Ex : http://<my_server>/api/index.php/invoices

Before using any API, you must first get a custom API-key. You have to create a new user and generate or set its "Key for API".

Dolibarr user for api.png


You will have to use this API key in any of your client program that need to call a Dolibarr API.


Client code example

PHP

There's different ways to do so. Here's a piece of code but you can also use libraries such as phphttpclient.com

// Example of function to call a REST API
function callAPI($method, $apikey, $url, $data = false)
{
    $curl = curl_init();
    $httpheader = ['DOLAPIKEY: '.$apikey];

    switch ($method)
    {
        case "POST":
            curl_setopt($curl, CURLOPT_POST, 1);
            $httpheader[] = "Content-Type:application/json";

            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

            break;
        case "PUT":

	    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
            $httpheader[] = "Content-Type:application/json";

            if ($data)
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

            break;
        default:
            if ($data)
                $url = sprintf("%s?%s", $url, http_build_query($data));
    }

    // Optional Authentication:
    //    curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    //    curl_setopt($curl, CURLOPT_USERPWD, "username:password");

    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $httpheader);

    $result = curl_exec($curl);

    curl_close($curl);

    return $result;
}

This is just a working example. There's no error control and security was not in mind but you can use this code, modify it to suit your needs
The fonction has 4 parameters :

  • $method : string, "GET", "POST", "PUT", "DELETE"
  • $apikey : string, "your <token> generated earlier"
  • $url : string, url to call. Ex : "http://<my_server>/api/index.php/invoices"
  • $data : string, datas in json format. This parameter is not mandatory.

Javascript Ajax

<script>
$.ajax({
  type: 'GET',
  async: true,
  contentType: "application/json; charset=utf-8",
  data: { 'lang': 'en_US' },
  dataType: "json",
  cache: false,
  jsonp: false,
  headers: {
    'DOLAPIKEY': 'abcdef123456'
  }, 
  url: 'https://myserver/api/index.php/theapi',
  success: function(rep) {
    console.log("API call success");
    console.log(rep);
  },
  error: function(rep) {
    console.log("API call error");
    console.log(rep);
  }
});
</script>

Accepted parameters

This is documented somewhat in the REST Explorer. Check that first. Second try and see what response you get. Third look at the source code for the given API.

sqlfilters

They are passed on to the database after a check. These work on the product endpoint:

  • (t.fk_product_type: = :'0') and (t.tosell: = :'1') and (t.label: ilike :'%string')

Date

The ISO date format is accepted: %Y-%m-%d e.g. 2020-07-14. yymmdd is not accepted.

Examples with PHP

This is more examples, for different uses cases:

In every examples, we have:

  • $apiKey = "<my token>";
  • $apiUrl = "http://<my_server>/api/index.php/";
// Retrieve products list
	$listProduits = [];
	$produitParam = ["limit" => 10000, "sortfield" => "rowid"];
	$listProduitsResult = CallAPI("GET", $apiKey, $apiUrl."products", $produitParam);
	$listProduitsResult = json_decode($listProduitsResult, true);

	if (isset($listProduitsResult["error"]) && $listProduitsResult["error"]["code"] >= "300") {
	} else {
		foreach ($listProduitsResult as $produit) {
			$listProduits[intval($produit["id"])] = html_entity_decode($produit["ref"], ENT_QUOTES);
		}
	}

Comments :

  • I retrieve the 10'000 first products sorted on their ID in the base
  • html_entity_decode is necessary as single quotes are encoded
  • It's easy to use the same method (replacing products with dictionnarycountries) to retrieve the list of countries and their ID


// Create a product
	$ref = "my_product_ref_X203ZZ";
	$newProduct = [
		"ref"	=> $ref,
		"label"	=> $ref
	];
	$newProductResult = CallAPI("POST", $apiKey, $apiUrl."products", json_encode($newProduct));
	$newProductResult = json_decode($newProductResult, true);

Comments :

  • before creating a product, it could be wise to check if it exists. Using my first example, you'll have :


// my ref
	$ref = "my_product_ref_X203ZZ";
// does it exist in my array
	$produitKey = array_search($ref, $listProduits);
	if ($produitKey) {
// yes
		$fk_product = $produitKey;
	} else {
// no
// Create the product
		$newProduct = [
			"ref"	=> $ref,
			"label"	=> $ref
		];
		$newProductResult = CallAPI("POST", $apiKey, $apiUrl."products", json_encode($newProduct));
		$newProductResult = json_decode($newProductResult, true);
		if (isset($newProductResult["error"]) && $newProductResult["error"]["code"] >= "300") {
// there's been an error
			echo "<pre>ERROR", var_dump($newProductResult), "</pre>";
			exit;
		} else {
// everything good
			$fk_product = $newProductResult;
			$listProduits[$fk_product] = $ref;
		}
	}

Comments :

  • I check if the ref of my product exist in the array created in the first example.
  • If it exists, I use it's key in the array as ID
  • If it doesn't exist, I create the product, then I add it to my array for next time then I use the ID created
  • I choose this method to do less API calls when I have to import 500 orders. I just need to retrieve the products list once at the beginning instead of searching Dolibarr each time.

Warning: The example below is not working properly. Creating an order and lines in one go is not supported. Instead you have to create an order first and with the returned order id add the lines using the /orders/{id}/lines endpoint.

// create an order with 2 products

// The array where there will be all the products lines of my order.
	$newCommandeLine = [];

// product 1
	$ref1 = "my_product_ref_X203ZZ";
	$prix1 = 10;
	$qtt1  = 100;
	$tva1 = 20;
	$fk_product1
// product 2
	$ref2 = "my_product_ref_B707FD";
	$prix2 = 13;
	$qtt2  = 37;
	$tva2 = 20;

	$newCommandeLine[] = [
		"desc"		=> $ref1,
		"subprice"	=> $prix1,
		"qty"		=> $qtt1,
		"tva_tx"	=> floatval($tva1),
		"fk_product"=> $fk_product1
	];

	$newCommandeLine[] = [
		"desc"		=> $ref2,
		"subprice"	=> $prix2,
		"qty"		=> $qtt2,
		"tva_tx"	=> floatval($tva2),
		"fk_product"=> $fk_product2
	];

	if (count($newCommandeLine) > 0) {
		$newCommande = [
			"socid"			=> $clientDoliId,
			"type" 			=> "0",
			"lines"			=> $newCommandeLine,
			"note_private"	=> "order created automatically with API",
		];
		$newCommandeResult = CallAPI("POST", $apiKey, $apiUrl."orders", json_encode($newCommande));
		$newCommandeResult = json_decode($newCommandeResult, true);
	}

Comments :

  • $clientDoliId is the ID of the customer in the Dolibarr database. Either you know it or you can search for it before
  • type => 0, This is a customer order (while 1 = supplier order)


// Validate an order 
	$newCommandeValider = [
		"idwarehouse"	=> "0",
		"notrigger"		=> "0"
	];
	$newCommandeValiderResult = CallAPI("POST", $apiKey, $apiUrl."orders/".$newCommandeResult."/validate", json_encode($newCommandeValider));
	$newCommandeValiderResult = json_decode($newCommandeValiderResult, true);

Comments :

  • in this example, on the penultimate line, we can see : $apiUrl."orders/".$newCommandeResult."/validate".

$newCommandeResult is the ID of the order created in the previous example


// search in the database if a customer exist
	$customer_name = "Acme Inc";

	$clientSearch = json_decode(CallAPI("GET", $apiKey, $apiUrl."thirdparties", array(
		"sortfield" => "t.rowid", 
		"sortorder" => "ASC", 
		"limit" => "1", 
		"mode" => "1",
		"sqlfilters" => "(t.nom:=:'".$customer_name."')"
		)
	), true);

Comments :

  • limit => 1 only 1 customer
  • mode => 1 we are looking for a customer, not a supplier (they are thirdparties too but with a different status)
  • sqlfilters a bit special but there are more examples on the explorer page


// customer doesn't exist. Let's create it and get it's ID
	$newClient = [
		"name" 			=> "customer company name",
		"email"			=> "customer company email",
		"client" 		=> "1",
		"code_client"	=> "auto"
	];
	$newClientResult = CallAPI("POST", $apiKey, $apiUrl."thirdparties", json_encode($newClient));
	$newClientResult = json_decode($newClientResult, true);
	$clientDoliId = $newClientResult;

Comments:

  • client => 1, he is a customer.
  • code_client => 'auto' so the customer code will be generated automatically.
  • we get the customer ID in $clientDoliId

Examples with Python

See https://pypi.org/project/dolipy/ (2021) or https://pypi.org/project/dolibarr/ (2019) or https://pypi.org/project/dolibarrpy/ (2024)

First you can install the python-module with "pip install dolibarr" or pypi install dolibarrpy

 from dolibarr import Dolibarr

 api_url = '<nowiki>http://your-url/dolibarr/htdocs/api/index.php/'</nowiki>
 api_key = 'custom_API-Key'

 # Connection to dolibarr
 dolibarr_inst = Dolibarr(api_url, api_key)

 # create Product
 params = {'ref': 'Product_Reference', 'status': '1', 'barcode_type': '6', 'note_public': None,          

           'note_private': <nowiki>''</nowiki>, 'specimen': 0, 'label': 'Product_Label',

           'description': <nowiki>''</nowiki>, 'type': '0', 'price': <nowiki>''</nowiki>, 'price_ttc': '15.6000000', 'price_base_type': 'TTC',  # excl. tax = HT, incl. tax = TTC

           'tva_tx': '19.0000', 'seuil_stock_alerte': '0', 'desiredstock': '0', 'status_buy': '1', 'barcode': 'barcode'}

 ret_val = dolibarr_inst.call_create_api('products', params)
 print(ret_val)

 # get product list
 product_dict = dolibarr_inst.call_list_api('products')
 print(product_dict)

Develop your own service / API

Adding a new REST service is as easy than adding a file called api_mymoduleobject.class.php into the directory htdocs/mymodule/class. You can take an example into htdocs/commande/class/api_orders.class.php

Note that if you use the modulebuilder tool, this file may be generated for you.

The framework detects automatically the API files and it should be visible into the explorer.

Method and parameters are detected according to introspection done into PHP class of the object (htdocs/mymodule/class/object.class.php) using the annotations found into the class. For a documentation about annotation: https://github.com/Luracast/Restler/blob/master/ANNOTATIONS.md

These are just the basics.

To find all existing API files in Dolibarr, you can search all files htdocs/<directory>/class/api_xxx_class.php