GET /api/v8/schema
JSON API is a specification for how a client should request that resources be fetched or modified, and how a server should respond to those requests.
JSON API is designed to minimize both the number of requests and the amount of data transmitted between clients and servers. This efficiency is achieved without compromising readability, flexibility, or discoverability.
JSON API requires use of the JSON API media type
application/vnd.api+json
for exchanging data.
To validate messages, you can retrieve the JSON Schema file:
GET /api/v8/schema
Clients MUST send all JSON API data in request documents with the
header Content-Type: application/vnd.api+json
without any
media type parameters.
Clients that include the JSON API media type in their
Accept
header MUST specify the media type there at least
once without any media type parameters.
Clients MUST ignore any parameters for the
application/vnd.api+json
media type received in the
Content-Type
header of response documents.
$ch = curl_init();
$header = array(
'Content-type: application/vnd.api+json',
'Accept: application/vnd.api+json',
);
$url = 'https://path-to-instance/api/v8/modules/meta/list';
curl_setopt($ch, CURLOPT_URL, url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');;
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
$output = curl_exec($ch);
The JSON API specifies the errors object to send messages back to the user. SuiteCRM API errors are exceptions which have been thrown. Errors are logged in suitecrm.log and posted back to the client application.
Tue Sep 26 13:51:17 2017 [697][1][FATAL] [ERROR] Code: [8006] Status: [409] Message: [SuiteCRM] [API] [Conflict] ["id" already exist] "11c48ede-e9c6-6c15-fa37-59b66a8dbeab" Detail: ["Unable create record, because it already exists."] Source: [/data/attributes/id]
{
"errors": [
{
"code": 8006,
"title": "[SuiteCRM] [API] [Conflict] [\"id\" already exist] \"11c48ede-e9c6-6c15-fa37-59b66a8dbeab\"",
"detail": "Unable create record, because it already exists.",
"source": {
"pointer": "/data/attributes/id"
},
"status": 409
}
]
}
SuiteCRM offers access to modules resources.
To get a list of modules you can use the following url:
GET https://path-to-instance/api/v8/modules/meta/list
To get a list of records use the following url:
https://path-to-instance/api/{module}
https://path-to-instance/api/v8/modules/Accounts
{
"data": [{
"type": "Accounts",
"id": "1",
"attributes": {
"Name": "JSON API paints my bikeshed!"
}
}, {
"type": "Accounts",
"id": "2",
"attributes": {
"Name": "Rails is Omakase"
}
}]
"links": {
"self": "https://path-to-instance/api/v8/modules/Accounts?page[limit]=20&page[offset]=0",
"first": "https://path-to-instance/api/v8/modules/Accounts?page[limit]=20&page[offset]=0",
"last": null,
"prev": null,
"next": null,
}`
}
SuiteCRM offers a offset-based strategy for pagination, a client MAY use the page[offset] and page[limit] parameter to request for pagination. The following keys MUST be used for pagination links:
first |
the first page of data |
last |
the last page of data |
prev |
the previous page of data |
next |
the next page of data |
Keys MUST either be omitted or have a null value to indicate that a particular link is unavailable.
A client MAY request that an endpoint return only specific fields in the
response on a per-type basis by including a fields[TYPE] parameter. The
value of the fields parameter MUST be a comma-separated (U+002C COMMA,
“,”
) list that refers to the name(s) of the fields to be returned.
GET https://path-to-instance/api/v8/modules/Accounts?fields[Accounts]=name,date_created
SuiteCRM offers sorting via the sort parameter.
GET https://path-to-instance/api/v8/modules/Accounts?sort=name,-date_created
The attribute is sorted in ascending order, however to sort in
descending order you simply add MINUS (-) in front of the attribute
name. The value of the sort parameter MUST be a comma-separated (U+002C
COMMA, “,”
) list.
The JSON Api (v1.0.0) does not specify which strategy to use when filtering, instead the filter query parameter is reserved for filtering. So this section attempts to describe the filtering strategy implemented in SuiteCRM.
You can specify a pre-made filter like so
GET /api/v8/modules/\{module}?filter={name}
{name} represents the name of the filter
Example use the roi filter and sort by total_revenue in descending order
GET /api/v8/modules/Leads?filter=roi&sort=-total_revenue
If you need to retrieve a set of modules you can use the following call
GET /api/v8/modules/{module}?filter[id]=\{id},...
{type} represents represent the module type:
{filter} represents the id for the module type
To get a list of accounts with the id of 1, 2, and 3:
GET /api/v8/modules/Accounts?filter[Accounts]=1,2,3
GET /api/v8/modules/\{module}?filter[{type}.{attribute}]=[[{operator}]]{comparator},...
{type} represents represent the module type:
{attribute} represents an attribute name eg. date_modified
{operator} represents a [[API-8#Operators|filter operation]]
{comparator} represents the attribute value to compare against eg 2017-11-17T11:40:00+00:00
GET /api/v8/modules/{module}?filter[Accounts.date_modified]=[[gt]]2017-11-17T11:40:00+00:00
GET /api/v8/modules/{module}?filter[{type}.{related type}.{attribute}]=[[{operator}]]{comparator},...
GET /api/v8/modules/Accounts?filter[Accounts.Contacts.date_modified]=[[gt]]2017-11-17T11:40:00+00:00
GET /api/v8/modules/{module}?filter[{type}.{related type}.meta.middle_table.{attribute}]=[[{operator}]]{comparator},...
{related type} represents the link for the related module type
{attribute} represents an attribute name eg. date_modified
{operator} represents a [[API-8#Operators|filter operation]]
{comparator} represents the attribute value to compare against eg 2017-11-17T11:40:00+00:00
GET /api/v8/modules/Meetings?filter[Meetings.Users.meta.middle_table.accept_status]=[[eq]]Accept
The operators are represented by string values, so that they are not encoded, plus it will make it easier to extend operations in the future.
Comparators
Operator | Name | Example |
---|---|---|
eq |
Equal |
filter[Accounts.deleted]=[[eq]]1 |
ne |
Not Equal |
filter[Accounts.deleted]=[[ne]]0 |
gt |
Greater Than |
filter[Accounts.date_modified]=[\[gt]]2017-11-17T11:40:00+00:00 |
lt |
Less Than |
filter[Accounts.date_modified]=[[lt]]2017-11-17T11:40:00+00:00 |
gte |
Greater Than or Equal |
filter[Accounts.date_modified]=[[gte]]2017-11-17T11:40:00+00:00 |
lte |
Less Than or Equal |
filter[Accounts.date_modified]=[[lte]]2017-11-17T11:40:00+00:00 |
in |
In List |
filter[Accounts.name]=[[in]]inc,[[in]]ltd |
nin |
Not In List |
filter[Accounts.name]=[[nin]]inc,[[nin]]ltd |
Strings
Operator | Name | Example |
---|---|---|
li |
Like |
filter[Accounts.name]=[[li]]sam% |
nli |
Not Like |
filter[Accounts.name]=[[nli]]bob% |
This convention was taken from the MongoDb syntax.
When you need to create multiple conditions on a field, Due the length limitation of a url, it is recommended that you use the multiple comparator notation.
GET /api/v8/modules/Accounts?filter[Contacts.date_modified]=[[gte]]2017-11-17T11:40:00+00:00,[[lte]]2017-11-18T11:40:00+00:00
When you need to filter by multiple fields, you should use the multiple filters notation.
GET /api/v8/modules/Accounts?filter[Contacts.date_modified]=[[gte]]2017-11-17T11:40:00+00:00&filter[Contacts.last_contacted]=[[lte]]2017-11-18T11:40:00+00:00
List recently viewed records of the currently logged in user for all modules
GET /api/v8/modules/\{module}/viewed
List favourite records of the currently logged in user for all modules
GET /api/v8/modules/\{module}/favorites
To get the definitions of the attributes / fields. This is useful to get the constraints for each attribute
/api/v8/modules/\{module}/meta/attributes
Module Strings
GET /api/v8/modules/{module}/meta/language
Application and Drop Down Strings
GET /api/v8/modules/meta/languages
To consume a record from a module, you can do the standard CRUD operations
Create
POST /api/v8/modules/{module}/{id}
Retrieve
GET /api/v8/modules/{module}/{id}
Update
PATCH /api/v8/modules/{module}/{id}
Delete
DELETE /api/v8/modules/{module}/{id}
To consume a related module records, you can do the standard relationship fetching and updating operations:
Create
POST /api/v8/modules/{module}/{id}/relationships/{link}
Read
GET /api/v8/modules/{module}/{id}/relationships/{link}
Update
PATCH /api/v8/modules/{module}/{id}/relationships/{link}
Delete
DELETE /api/v8/modules/{module}/{id}/relationships/{link}
To create notes and documents, you will need to be able to upload files. This uses fields which have the type set to "file". The SuiteCRM API expects the contents of the file to be assigned to the {fieldname}_file attribute. The contents must be a base64 encoded string. When requesting a note or a document, the API will decode the file in the same request.
{
"data": {
"id": "",
"type": "Notes",
"attributes": {
"name": "Test",
"portal_flag": true,
"filename": "testFile.txt",
"filename_file": "U3VpdGVDUk0gaXMgdGhlIGJlc3Q="
}
}
}
{
"data": {
"id": "",
"type": "Documents",
"attributes": {
"name": "testFile.png",
"document_name": "testFile.png",
"active_date": "2017-11-17T11:40:00+00:00",
"portal_flag": true,
"revision": "1",
"filename": "testFile.txt",
"filename_file": "U3VpdGVDUk0gaXMgdGhlIGJlc3Q="
}
}
To create a meeting, you need to provide the invitees and there accept status.
POST api/v8/modules/Meetings
{
"data": {
"id": "",
"type": "Meetings",
"attributes": {
"name": "RelationshipsTest",
"date_start": "2017-11-07T10:55:43+00:00",
"date_end": "2017-11-07T11:10:43+00:00",
"duration_hours": "",
"duration_minutes": 15,
"assigned_user_id": "1",
"assigned_user_name": "Administrator"
},
"relationships": {
"users": {
"data": [
{
"id": "1",
"type": "User",
"meta": {
"middle_table": {
"data": {
"id": "",
"type": "Link",
"attributes": {
"accept_status": "accept",
"user_id": "1"
}
}
}
}
},
{
"id": "seed_max_id",
"type": "Users",
"meta": {
"middle_table": {
"data": {
"id": "",
"type": "Link",
"attributes": {
"accept_status": "none",
"user_id": "seed_max_id"
}
}
}
}
},
{
"id": "seed_chris_id",
"type": "Users",
"meta": {
"middle_table": {
"data": {
"id": "",
"type": "Link",
"attributes": {
"accept_status": "none",
"user_id": "seed_chris_id"
}
}
}
}
}
]
}
}
}
}
Please ensure that you include the meta middle table in each link in the relationship otherwise it will set all the middle table fields to the first meta object.
Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.