APIv3 REST¶
APIv3 Deprecation
API version 3 is now deprecated. Version 4 is recommended.
Overview¶
Get started with APIv3 Explorer
CiviCRM has a built-in tool for working with APIv3 (Support => Developer => APIv3 Explorer
). You may use
this to generate complete HTTP/REST examples that are tuned to your instance of CiviCRM.
This documentation provides a deeper explanation of the HTTP/REST interface.
CiviCRM APIv3 provides HTTP/REST bindings, enabling remote applications to read and write data. To use it, we must understand the end-point URLs, the authentication protocols, and the API data.
Is APIv3 a REST-ful interface?
HTTP-based APIs are sometimes described as "REST-ful" if they closely follow certain HTTP conventions. CiviCRM APIv3 is not REST-ful.
Never-the-less, it is generally used for reading and writing resource records, and (by tradition) the subsystem is referred to as "REST".
Examples¶
As we review the structure of an APIv3 REST call, it may help to have a few examples. Here is a representative example:
1: GET https://www.example.org/sites/all/modules/civicrm/extern/rest.php
2: ?key=ABCD1234&api_key=ZYXW9876
3: &entity=Contact&action=get&json=%7B%22id%22%3A10%7D
In line 1, we see an end-point URL. Line 2 provides the authentication parameters. Line 3 conveys the specific API call (entity, action, parameters).
Similar elements should appear in any API call, but the content of each can differ. Here is another example:
1: POST https://crm.example.org/civicrm/ajax/rest
2: Authorization: Basic dXNlcjpwYXNz
3: X-Requested-With: XMLHttpRequest
4:
5: entity=Activity&action=create&json=%7B%22subject%22%3A%22hello%22%7D
Here, we have a different end-point URL (line 1) along with a different authentication style (line 2). The specific API also differs (line 5).
Compatibility¶
As we proceed through this chapter, we will consider different API features. When choosing which features to use, you may wish to consult back to this compatibility matrix.
End-Point URL | civicrm/ajax/* |
extern/rest.php (deprecated) |
WP REST |
---|---|---|---|
APIv3 | Yes | Yes | Yes |
APIv4 | Yes | No | No |
Authentication: AuthX | Yes (v5.36+) | No | No |
Authentication: Session-Cookie | Yes | No | No |
Authentication: Traditional Keys | Yes (v5.47+) | Yes | Yes |
CMS: Backdrop | Yes | Yes | No |
CMS: Drupal 7 | Yes | Yes | No |
CMS: Drupal 8+ | Yes | Unofficial, Deprecated | No |
CMS: Joomla | Partial | Yes | No |
CMS: WordPress | Yes | Deprecated | Yes (v5.25+) |
End-Point URL¶
For help choosing an end-point, see also: Compatibility
All requests should be submitted to an APIv3 end-point URL.
Requests are typically submitted with HTTP POST, but read-only operations may use HTTP GET.
You may choose among a handful of end-point URLs. Expand the sections below for more detailed information.
APIv3 REST via normal HTTP route: civicrm/ajax/rest
The civicrm/ajax/rest
end-point works like any regular page in CiviCRM. On Drupal, Backdrop, and some WordPress deployments, you may access it with a clean URL.
https://example.org/civicrm/ajax/rest
In other deployments, you may need a verbose URL - such as these WordPress and Joomla URLs:
https://wordpress.example.org/wp-admin/admin.php?page=CiviCRM&q=civicrm/ajax/rest
https://joomla.example.org/administrator/index.php?option=com_civicrm&task=civicrm/ajax/rest
The civicrm/ajax/rest
end-point is frequently used for browser-based API calls ("AJAX"). In newer versions (CiviCRM v5.36+), it can also be used for remote applications.
Stylisitcally, this is similar to APIv4 REST end-point.
APIv3 REST via standalone script: extern/rest.php
As of v5.47+, there should be no reason to use extern/rest.php
- other end-points should be more compatible and more featureful. See APIv3 Changelog for migration notes.
The extern/rest.php
end-point is a standalone PHP script. It generally lives in the CiviCRM source tree, although the location will depend on the specific deployment.
## Typical Backdrop URL
https://example.org/modules/civicrm/extern/rest.php
## Typical Drupal 7 URL
https://example.org/sites/all/modules/civicrm/extern/rest.php
## Typical Joomla URL
https://example.org/administrator/components/com_civicrm/civicrm/extern/rest.php`
## Typical WordPress URL
https://example.org/wp-content/plugins/civicrm/civicrm/extern/rest.php
This end-point is broadly compatibile with many versions (CiviCRM v3+). However, it is incompatible with APIv4 and with some environments. Specifically, Drupal 8+ and some configurations of WordPress have difficulty with it.
APIv3 REST via WordPress service
WP REST (CiviCRM v5.25+) replaces all extern/*.php
scripts with WordPress-optimized equivalents. These end-points support
clean URLs, and they provide wider compatibility with more WordPress environments.
## Typical WP REST URL
https://example.com/wp-json/civicrm/v3/rest
Authentication¶
For help choosing an authentication protocol, see also: Compatibility
Every request for APIv3 should include authentication details. These may be submitted in a few forms.
Authenticate via AuthX (API Key, JWT, Username/Password)
The core extension "AuthX" (v5.36+) provides extended authentication support. If configured, it can accept credentials in several different formats, such as:
/* Conventional HTTP header */
Authorization: Bearer MY_API_KEY
Authorization: Bearer MY_JSON_WEB_TOKEN
Authorization: Basic B64(USER:PASS)
/* Civi HTTP header */
X-Civi-Auth: Bearer MY_API_KEY
X-Civi-Auth: Bearer MY_JSON_WEB_TOKEN
X-Civi-Auth: Basic B64(USER:PASS)
/* HTTP parameter */
?_authx=Bearer+MY_API_KEY
?_authx=Bearer+MY_JSON_WEB_TOKEN
?_authx=Basic+B64(USER:PASS)
AuthX is compatible with normal CiviCRM routes like civicrm/ajax/rest
.
Authenticate via CMS session/cookie
Browser-based users typically access CiviCRM by logging in to a colocated CMS (Drupal, WordPress, etc). This process creates a session-cookie which authenticates the user.
This style of authentication is important for AJAX. However, for remote applications, this style can be problematic because (a) each CMS has a different login process and (b) site-builders often customize the login experience.
Authenticate via traditional REST keys
CiviCRM v4+ supports authentication using a combination of two keys. A valid request must present both keys as URL parameters. For example:
?key=THE_SITE_KEY
&api_key=MY_API_KEY
The site key is a general pre-requisite, and it will be the same for all traditional REST users. The API key uniquely identifies the user or agent making the request.
Support for traditional REST keys is limited to specific end-points and versions:
End-Point URL | Support Traditional REST Keys? |
---|---|
civicrm/ajax/rest |
Yes (v5.47+) |
extern/rest.php |
Yes (All versions) |
WP REST | Yes (v5.25+) |
X-Requested-With¶
To ensure broad compatibility, APIv3 REST clients should set this HTTP header:
X-Requested-With: XMLHttpRequest
The header is not required for all requests, but sometimes it is required, and there is generally no harm to setting it.
For more complete details, see Cross-Site Request Forgery (CSRF) and specifically CSRF: APIv3/APIv4 REST.
API Data¶
As you may recall, APIv3 is built around the triplet ($entity
, $action
, $params
), e.g.
$result = civicrm_api3($entity, $action, $params);
$result = civicrm_api3('Contact', 'get', ['id' => 10]);
The triplet corresponds to three HTTP parameters (&entity=
, &action=
, and &json=
). If we adapt the
above example and apply appropriate escaping rules, the corresponding HTTP parameters will be:
&entity=Contact
&action=get
&json=%7B%22id%22%3A10%7D
Even if there are no $params
, one should pass a placeholder value for &json=1
.
Deprecated: Extra Key-Value Parameters
Any unrecognized parameters in the URL are passed through to the $params
. The previous example could be written as:
&entity=Contact
&action=get
&id=10
This format looks easy, and it is retained for backward compatibility. Never-the-less, JSON is recommended because:
- Extra params cannot accurately indicate special values (
true
,false
,null
,[]
,{}
). - Extra params are prone to naming conflicts (e.g. if an API requires an input
$params['action']
). - Extra params require special encoding for nested fields (e.g.
&options[limit]=25&options[offset]=50
).
JSON addresses all these issues, and it has very broad support across many tools/environments/clients.
Response¶
The response will be a JSON document, e.g.
{
"is_error": 0,
"version": 3,
"count": 1,
"values": [
{
"contact_id": "10",
"contact_type": "Individual",
"contact_sub_type": "",
"display_name": "Example Person",
...
Deprecated: XML Responses
If you omit the &json=...
parameter, then the APIv3 REST will send responses in XML format. This is retained for
backward compatibility, but JSON format is generally recommended.
Example: XML response after searching for contact
<?xml version="1.0"?>
<ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Result>
<contact_id>1</contact_id>
<contact_type>Individual</contact_type>
<sort_name>Doe, John</sort_name>
<display_name>John G Doe</display_name>
<do_not_email>0</do_not_email>
<do_not_phone>0</do_not_phone>
<do_not_mail>0</do_not_mail>
<do_not_trade>0</do_not_trade>
<is_opt_out>0</is_opt_out>
<home_URL>[http://www.example.com]</home_URL>
<preferred_mail_format>Both</preferred_mail_format>
<first_name>John</first_name>
<middle_name>G</middle_name>
<last_name>Doe</last_name>
<is_deceased>0</is_deceased>
<email_id>2</email_id>
<email>jdoe@example.com</email>
<on_hold>0</on_hold>
</Result>
...
<Result>
<contact_id>N</contact_id>
<contact_type>Individual</contact_type>
<sort_name>test@example.org</sort_name>
<display_name>test@example.org</display_name>
<do_not_email>0</do_not_email>
<do_not_phone>0</do_not_phone>
<do_not_mail>0</do_not_mail>
<do_not_trade>0</do_not_trade>
<is_opt_out>0</is_opt_out>
<preferred_mail_format>Both</preferred_mail_format>
<is_deceased>0</is_deceased>
<email_id>4</email_id>
<email>test@example.org</email>
<on_hold>0</on_hold>
</Result>
</ResultSet>
Example: XML response to creating a new contact
<?xml version="1.0"?>
<ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Result>
<contact_id>4</contact_id>
<is_error>0</is_error>
</Result>
</ResultSet>