CRM API Version 4.0
The CRM API version 4.0 is a RESTful (Representational State Transfer) API allowing you to make requests to Create, Read, Update and Delete your CRM edition’s records.
The following record types can be Created, Read, Updated and Deleted via the SpotlerCRM API v4.0 (depending on the pricing plan you are using and the add-on options you have enabled):
Record Type | Price Plan | Object name |
Accounts | Professional, and Enterprise Plans | accounts |
Activities | Professional, and Enterprise Plans | activities |
Contacts | Professional, and Enterprise Plans | contacts |
Campaigns | Professional, and Enterprise Plans (with Marketing tool) | campaigns |
Campaign Details | Professional, and Enterprise Plans (with Marketing tool) | campaigndetails |
Campaign Stages | Professional, and Enterprise Plans (with Marketing tool) | campaignstages |
Cases | Professional and Enterprise Plans (with Service & Support tool) | cases |
Documents | Professional, and Enterprise Plans | documents |
Opportunities | Professional, and Enterprise Plans | opportunities |
Opportunity Histories | Professional, and Enterprise Plans | opportunityhistories |
Opportunity Lines | Professional, and Enterprise Plans | opportunity_lines |
The CRM API v4.0 accepts requests in JSON format. You will need to understand how to make HTTP requests in order to use the API although we have provided some introductory information and useful links (in addition to a comprehensive guide to the methods available to you) to assist you or your developers.
OAuth 2.0
You can only access the V4 API with an OAuth 2.0 Access Token, we have OAuth webflow enabled for integrating with external systems, such as Zapier.
To get an Access Token without using webflow you can use the following method:
Login to the your CRM system and go to; Settings / Integrations / API V4.
This will allow you to enable your users to access the API and generate Access Tokens with a single click.
Once you have an Access Token, it will need to be inserted as an Authorisation header when making any request.
E.g: Authorization: Bearer {access_token}
Data Dictionary
You can get all the fields for a record type by making a GET request to the URL below by using its object name:
/datadictionary/{object_name}
This will return all the field names and types you can retrieve or submit to the API for each record type, it will tell you if the field is also required.
Lookup lists/dropdowns
You can retrieve the values from any lookup list/dropdown you have or is attached to a form field within your CRM, this is done by making a GET request to the URL below by using its object name and lookup list name:
GET /lookup/{object_name}/{field_name}
Example:
GET /lookup/accounts/type
This call would return all the types that have been set up for an account.
Appending to lookup list/dropdown
You may also automatically append items to your lists/dropdowns by making a PATCH request to the URL below:
Request URL (PATCH):
/lookup/{list_name}
Request body (JSON):
{ "items": [ "Item 1", "Item 2" ] }
Response (JSON):
{ "message": "Lookup values added", "items": [ { "value": "new one", "id": "new one" }, { "value": "another new one", "id": "another new one" } ] }
Making Requests
Making a request is simple, choose the record type you want and take a note of the object name, then simply send a GET, POST, PATCH, DELETE request to the servers.
The URL structure is the same for all type of requests, just the method changes.
e.g:
GET /accounts
GET /contacts
POST /accounts
PATCH /accounts/123456
DELETE /accounts/123456
Record Limits and Pagination
All GET requests are limited to 100 records at a time and defaulted to 10. You can change this limit by passing limit in the URL.
GET /accounts?limit=50
Due to the limits above, you can also pass a page number.
GET /accounts?page=2
This will return your accounts starting from the 2oth record by default. You can combine limits and pages together to get more results for a particular page.
GET /accounts?limit=100&page=4
This will return your accounts starting at the 400th record.
If the page cannot be found, no records will be returned.
Opportunity Lines
You can return the line items for an opportunity inline under the key of ‘lines’ by passing the request parameter of lines=true
GET /opportunities?lines=true
GET /opportunities/{id}?lines=true
The returned JSON will include the ‘lines’ key similar to below.
"lines": [ { "id": 1, "opportunityid": 1, "product": "User Subscription", "quantity": 30, "unitprice": 420 } ]
Filtering results
Filtering is as simple as sending a request with the query parameter set in the URL, the parameter consists of fields and operators in JSON format that make up a complete query. The field or fields you provide must match a field in the objects data dictionary.
Quick example
GET /accounts?q={"name": "Test"}
Which is the same as asking for all accounts with the name “Test”.
You can match on a single field. ?q={“name”: “Test”}
Or you can match on multiple fields. ?q={“name”: “Test”, “sector”: “Design”}
In addition to simple fields, you can use special operators to provide move complex queries.
Logic Operators
Operator | Description | Example |
---|---|---|
$not | Negation logical operator |
{"field": {"$not": val}} |
$in | Match any value in array |
{"field": {"$in": [value1, value2, ...]}} |
$nin | Not match any value in array |
{"field": {"$nin": [value1, value2, ...]}} |
$or | Logic operator |
{"$or": [{"field": value}, {"field": value}]} |
Conditional Operators
Operator | Description | Example |
---|---|---|
$gt | Greater than |
{"field": {"$gt": 1000}} |
$gte | Greater than or equal |
{"field": {"$gte": 1000}} |
$lt | Less than |
{"field": {"$lt": 1000}} |
$lte | Less than or equal |
{"field": {"$lte": 1000}} |
$bt | Between value1 and value2 inclusive |
{"field": {"$bt": [1000, 2000]}} |
$sw | Starts with |
{"field": {"$sw": "tes"}} |
$ew | Ends with |
{"field": {"$ew": "tes"}} |
$con | Contains |
{"field": {"$con": "tes"}} |
Ordering
You can pass in the query parameter of ?order to order the results, this needs to be in JSON format and consist of a field and direction.
The direction can be either asc or desc.
Quick example:
GET /accounts?order={"field": "asc"}
You can order by many fields by passing multiple into the query.
GET /accounts?order={"field": "asc", "field2": "asc", ...}
GET Requests
This will only ever return information to you.
To get a list of all your records for a certain type, send a GET request for the record using the object name.
GET /{object_name}
Above will return a list of all your accounts based on your permission level.
GET /{object_name}/12345
Above will return the record which has the ID of 12345 or nothing. Refer to the example tab above to see what this would look like.
POST Requests
You can use POST request when you wish to create records. You POST a JSON encoded string to the servers and it will return a single instance of the record.
POST /{object_name}
If all the validation and subscription limit checks pass, the newly created record will be returned. Refer to the example tab above to see what this would look like.
N.B. It is required to include all mandatory fields, in an API Call which creates a new CRM record, via POST.
PATCH Requests
These are used to update records that already exist within your CRM system. It still requires a JSON encoded string to be submitted to the servers but the url must include the ID of the record to be updated.
PATCH /{object_name}/123456
Without the ID, the request will fail.
If the request is successful, a single instance of the record will be returned.
DELETE Requests
Similar to a PATCH request but this doesn’t need any content, it just needs the ID of the record you wish to delete.
DELETE /{object_name}/12345
The request will fail without the id.
If successful, it will also not return any content, just a status code of 200.
Error Responses
If bad request is made or there has been an error handling your request, you will get an error similar to below.
{ "type": "Invalid Request error", "code": 500, "message": "Invalid record type (accountss)" }
The code may be different and the message itself, but it will return a JSON object and always have a message index letting you know what has gone wrong.
If an error had been encountered you will received a status code higher then or equal to 3xx. A status code of 200 or 201 means your request was successful.
Response status codes
Code | Meaning |
---|---|
500 | Internal server error, something has gone wrong at our end. |
422 | Validation Error, please check the information you have provided |
405 | Not Allowed, please check the request type (GET, POST, PATCH, DELETE) |
404 | Record or page not found |
402 | Forbidden, please check your access token |
400 | Bad request, please check the url and data submitted |
301 | Redirect, may happen when trying to login |
201 | Created successfully |
200 | Successful request |
On a 422 error response, the JSON response will also contain validation information letting you know what went wrong.
{ "type": "Validation error", "code": 422, "message": "The given data was invalid.", "validation": { "accountid": [ { "Required": [] } ] } }
Quick Start
Enable your Users
Login to your CRM system and navigate to Settings / Integrations / API V4 then “Enable API Access to Users”.
Select the User you want to give access to and click Enable.
Get your Access Token
Navigate to Settings / Integrations / API V4 then “Manage API Keys and Alerts” and click the ‘generate new key’ button on the right.
In the popup window, select the User you want the Access Token for and click ‘generate’.
You will be presented with an Access Token. Make a note of this as it’s only shown to you once.
Make a GET Request
Visit: https://insomnia.rest/download and enter https://apiv4.reallysimplesystems.com/accounts into the ‘Curl Command URL’ field.
Click the add option button and select ‘–header (-H)’ and put the following into the ‘insert attributes’ field replacing {access_token} with your token:
Authorization: Bearer {access_token} and click ‘Start your curl’ below.
Results
Scroll to the bottom of the page and you should see a Response body section with the results of the test. If it starts with ‘{“metadata”:{“url”:”\/account”‘ then it was successful.
Examples
GET Your Accounts
Request URL (GET):
/accounts
Request Body:
Nothing is required
Response JSON:
{ "metadata": { "url": "/account", "object_type": "list", "total_count": 100, "has_more": true }, "list": [ { "metadata": { "url": "/accounts/95920978", "list_url": "/accounts", "parent": "/", "object_type": "record", "record_type": "account" }, "record": { "id": 95920978, "name": "test", "addressline": null, "addresscity": "", "addresscounty/state": "", "addresspostcode/zip": "", "addresscountry": "", "ownerid": 90505, "source": "", "notes": null, "phone": null, "website": null, "type": null, "sector": null, "createddate": "2018-09-17 11:29:59", "modifieddate": "2018-09-17 11:29:59" } }, ... ] }
Create a New Account
Request URL (POST):
/accounts
Request Body (JSON):
{ "name": "testing API", "ownerid": 1 }
N.B. It is required to include all mandatory fields, in an API Call which creates a new CRM record, via POST. Please email us on support@spotlercrm.com for a current list of mandatory fields on the CRM.
Response (JSON):
{ "metadata": { "url": "/accounts/95950731", "list_url": "/accounts", "parent": null, "object_type": "record", "record_type": "account" }, "record": { "id": 95950731, "name": "testing API", "addressline": null, "addresscity": "", "addresscounty/state": "", "addresspostcode/zip": "", "addresscountry": "United Kingdom", "ownerid": 90505, "campaignid": 0, "source": "", "notes": null, "slaid": 125357, "phone": null, "website": null, "type": null, "sector": null, "createddate": "2018-09-27 08:48:22", "modifieddate": "2018-09-27 08:48:22" } }
Update an Account
Request URL (PATCH):
/accounts/95950731
Request Body (JSON):
{ "name": "testing API Updated" }
Response (JSON):
{ "metadata": { "url": "/accounts/95950731", "list_url": "/accounts", "parent": null, "object_type": "record", "record_type": "account" }, "record": { "id": 95950731, "name": "testing API Updated", "addressline": null, "addresscity": "", "addresscounty/state": "", "addresspostcode/zip": "", "addresscountry": "United Kingdom", "ownerid": 90505, "campaignid": 0, "source": "", "notes": null, "slaid": 125357, "phone": null, "website": null, "type": null, "sector": null, "createddate": "2018-09-27 08:48:22", "modifieddate": "2018-09-27 08:55:38" } }
DELETE an Account
Request URL (DELETE):
/accounts/95950731
Request Body:
Nothing is required
Response Body (JSON):
{}
Returned with a status code of 200
API Alerts
Usage Alerts
You can set Usage Alerts that send an email to your selected user when you have reached a given percentage of your call limit. In Settings/Integrations/API V4 select “Manage API keys and alerts”. Here, click the down arrow to open the “Usage Alert” box, then simply select the user and the usage limit percentage when you want to trigger the alert, then save. This will email the user when you have reached that level. You can also manually add an email address and name to be alerted.
Failed API Call Alerts
Similarly, you can set up alerts to trigger a message to a user should you encounter a failed API call. Click on the down arrow to open the “Failed API Call Alert” box and select the user from the dropdown list, or add their details manually, then save.