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 Really Simple Systems CRM API v4.0 (depending on the pricing plan you are using and the modules you have enabled):

Record Type Price Plan Object name
Accounts All Price Plans  accounts
Activities All Price Plans  activities
Contacts All Price Plans  contacts
Campaigns Starter, Professional, and Enterprise Plans (with Marketing module)  campaigns
Campaign Details Starter, Professional, and Enterprise Plans (with Marketing module)  campaigndetails
Campaign Stages Starter, Professional, and Enterprise Plans (with Marketing module)  campaignstages
Cases Professional and Enterprise Plans (with Service & Support module)  cases
Documents All Price Plans  documents
Opportunities All Price Plans  opportunities
Opportunity Histories All Price Plans  opportunityhistories
Opportunity Lines All Price 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 Authorization 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 setup 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.

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.

Enable API for Users

  • 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://onlinecurl.com 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"
}

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.

API V4 Alerts