SugarCRM API CheatSheet

SugarCRM provides a robust Rest API and we will try to explain the most frequently used API functionalities with examples.

SugarCRM API CheatSheet

TLDR: Download the REST client files directly from our Github Repo:
seven-tunes-labs/sugarcrm-rest-client
Rest Client files for IntelliJ/VS Code to call SugarCRM - seven-tunes-labs/sugarcrm-rest-client
69246249

Using REST Client

This article uses REST client (IntelliJ/VSCode) - using which you can run REST requests directly from the IDE. Github link is provided at the end of the article.

Rest client uses dynamic variable substitution by providing a settings json file. For IntelliJ, create a http-client.private.env.json with the following values

{
  "local": {
    "rest_url": "http://localhost/rest/v10",
    "username": "sugar",
    "password": "sugar"
  }
 }
Settings JSON for Rest Clients (IntelliJ / VSCode)

For VSCode, open your settings as JSON and enter the JSON from above in rest-client.environmentVariables

SugarCRM provides multiple API versions (starting from v10) - all the REST APIs provided in this article are from v10, but you can always use the latest API version as part of your SugarCRM version.


Login API

SugarCRM APIs are restricted and you will need OAuth Token to access any of the data APIs.

### @name loginAPI
### Auth - Login to Sugar and get the Auth URL
POST {{rest_url}}/oauth2/token
Content-Type: application/json

{
  "grant_type": "password",
  "client_id": "sugar",
  "client_secret": "",
  "username": "{{username}}",
  "password": "{{password}}",
  "platform": "base"
}

> {% client.global.set("access_token", response.body.access_token); %}
### VS Code - @access_token = {{loginAPI.response.body.access_token}}
Login API

Response

{
  "access_token": "704a29e7-c908-40f4-84bd-a873d426fd35",
  "expires_in": 3600,
  "token_type": "bearer",
  "scope": null,
  "refresh_token": "bdaf8ada-4508-4440-992d-620ab7b172a7",
  "refresh_expires_in": 1209599,
  "download_token": "9b3407f0-47c2-4ba7-9980-71e95147f1fd"
}
Login API Response

The API will return refresh_token and access_token just like any OAuth API - and you will need the access_token to access the remaining REST APIs. Once the token expires, use refresh_token to get a new access_token.

The OAuth Token can now be used in all APIs by passing this header  OAuth-Token: {{access_token}}


Simple CRUD

  • Create - HTTP POST
### 1. Simple Create Request for a record - POST
POST {{rest_url}}/Contacts
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "name": "Clark Kent",
  "email": [
    {
      "email_address": "clark@kent.com",
      "primary_address": true
    }
  ]
}

> {% client.global.set("record_id", response.body.id); %}
Create New Record

  • Read - HTTP GET
### 2. Simple Get Request for a record - All Fields - Slow
GET {{rest_url}}/Contacts/{{record_id}}
OAuth-Token: {{access_token}}
Get Record
Tip: Pass the fields parameter to speed up the API - this will only return the fields you need. Eg: fields=name,email

  • Update - HTTP PUT
### 4. Update a Contact - Get Request for a record - Use PUT
PUT {{rest_url}}/Contacts/{{record_id}}
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "website": "seventunes.com"
}
Update Record

  • Delete - HTTP DELETE
### 5. Delete API - use DELETE
DELETE {{rest_url}}/Contacts/{{record_id}}
OAuth-Token: {{access_token}}
Delete Record

Searches/Filters

SugarCRM uses the term Filters to search content.

filter parameter is considered an array, and you have to specify the array index. Eg: filter[0][name] which defines the first filter for a field name
### 1. Simple filter using GET with "equals"
GET {{rest_url}}/Contacts?filter[0][first_name]=Maria&fields=name
OAuth-Token: {{access_token}}
Filtering/Searching Records using GET

Here is the same request as a POST, which is a bit easier to understand:

### 2. Same request as POST, using JSON
POST {{rest_url}}/Contacts/filter&fields=name
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "filter": [
    {
      "first_name": "Maria"
    }
  ]
}
Filtering Records using POST

Simple Operators

Filter Operators: SugarCRM provides filter operators that can be passed in the API request. Eg: $equals, $not_equals, $starts, $ends, $contains, $in, $lt, $gt, $lte, $gte

By default, the operator is equals if you don't specify one. You can also do wildcard search and perform different kind of filters by passing the operator:

### 4. Filters using Partial Match - You can use $contains/$starts/$ends
GET {{rest_url}}/Contacts?filter[0][first_name][$contains]=Mari&fields=name
OAuth-Token: {{access_token}}
Filters - Using Operators - GET

Using Operators in POST:

### 5. Partial match using POST
GET {{rest_url}}/Contacts/filter&fields=name
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "filter": [
    {
      "first_name": {
        "$contains": "Maria"
      }
    }
  ]
}
Filters - Using Operators - POST

SugarCRM is flexible to support custom operators, but that needs some coding - we are here to help - please contact us.

Logical Operators

You can mix and match criteria using $or / $and operators. Here is an example:

Example using GET

### 6. AND/OR Operators using GET - Gets a little confusing, better to start using POST for complex filters
GET {{rest_url}}/Contacts?filter[0][$or][0][first_name]=Maria&filter[0][$or][1][first_name]=Arnold&fields=name
OAuth-Token: {{access_token}}
"$or" filters

If you use POST, filters get much simpler to understand though:

### 7. AND/OR Operators using POST - Much better to understand
GET {{rest_url}}/Contacts/filter
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "filter": [
    {
      "$or": [
        {
          "first_name": "Maria"
        },
        {
          "first_name": "Arnold"
        }
      ]
    }
  ]
}
"$or" filter using POST

For Array/Dropdown fields, you can use $in operator to get multiple matches. Here is an example using both GET and POST:

### 8. Filtering Array/Dropdown fields - Use $in/$not_in
GET {{rest_url}}/Contacts?filter[0][lead_source][$in][]=Campaign&filter[0][lead_source][$in][]=Email&fields=name
OAuth-Token: {{access_token}}

### 9. $in using POST
POST {{rest_url}}/Contacts/filter&fields=name,email,lead_source
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "filter": [
    {
      "lead_source": {
        "$in": [
          "Campaign",
          "Email"
        ]
      }
    }
  ]
}
Filters - using "$in" operator

Relationship Filters

You can also search by Relate Fields and Relationships. The examples below require an understanding of Relationships in Sugar, and would also need the relatinoship name in most cases. (The examples below uses POST for clarity)

Filter by

To filter by relationships, you can use the relationship_name.field syntax here. Eg: Contacts module has a relationship with emails named email_addresses, so if which has a field named email_address. If you want to search a contact by email address, use this example below:

### 1. Filter Emails
POST {{rest_url}}/Contacts/filter&fields=name,email
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "filter": [
    {
      "accounts.email_address": "clark@kent.com"
    }
  ]
}
Filters - Using Relationships

Similar example using operators - Searches Opportunities by amount field:

### 2. Searching Relationships: Using operators
POST {{rest_url}}/Accounts/filter&fields=name,email,amount,contacts,opportunities
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "filter": [
    {
      "opportunities.amount": {
        "$gt": 5000
      }
    }
  ]
}
Filter using Relationships - using POST

Filter Within

If you want to filter the related records of a particular record, then you can use the link/link_name . This is especially useful for filtering subpanel records, for example.

The example below searches the related records of an account by some specific criteria. Unfortunately, this API is restricted only by GET

### 3. Filter Relationships. Eg: Narrow down related records of an account - "contacts" provided as an example
### Unfortunately POST is not supported yet
GET {{rest_url}}/Accounts/{{account_id}}/link/opportunities/filter?filter[0][amount][$gt]=5000&fields=name,amount
Content-Type: application/json
OAuth-Token: {{access_token}}
Filter a single record's relationship

Another common requirement is to search tags, which is quite simple:

### 4. Search by Tags
POST {{rest_url}}/Accounts/filter
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "filter": [
    {
      "tag": {
        "$in": ["Arts"]
      }
    }
  ]
}

Search by Tags

Handling Relationships

Relationships are the special feature of SugarCRM and often there is a need to handle relationships through API.

Adding Relationship

  • Option 1 - If the records are already created and you just want to link them:
### 1. Adding Relationships - Option #1 - If you know the ID
PUT {{rest_url}}/Accounts/{{account_id}}?fields=meetings
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "meetings": {
    "add": ["{{meeting_id}}"]
  }
}
Add Relationship using IDs
  • Option 2 - If you want to create a new record, related to another record, you will have to pass the parent_id, just like how it works for subpanel create button.
### Relationships
### 2. Adding Relationships - If you want to create a new record
POST {{rest_url}}/Accounts/{{account_id}}/link/meetings
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "name": "Customer Relationship",
  "date_start": "2020-08-03T10:00:00Z",
  "date_end": "2020-08-03T11:00:00Z"
}
Create new Related record
  • Option 3 - The usual way of creating a new record by specifying the relationship id:
### 3. Adding Relationships - Option #3 - Just create the record and specify the related record id
POST {{rest_url}}/Meetings
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "name": "Customer Relationship",
  "date_start": "2020-08-03T10:00:00Z",
  "date_end": "2020-08-03T11:00:00Z",
  "parent_type": "Accounts",
  "parent_id": "{{account_id}}"
}
Create new record with Related ID

Deleting Relationship

### 1. Deleting Relationships - Note - this doesn't delete the record, this only deletes the relationship
PUT {{rest_url}}/Accounts/{{account_id}}
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "meetings": {
    "delete": ["{{meeting_id}}"]
  }
}
Delete Relationship

SugarCRM also allows a global search of all records - using elastic search. This is often faster if you have a huge number of records or if you want to search across all fields.

Tip: You can specify only certain modules to search by passing the module_list parameter as a comma separated value. Eg: module_list=Accounts,Contacts

Unified search uses the /search endpoint, which uses both Elastic search and DB Search based on the following criteria:

  • If no module is specified, uses Elastic search
  • If module is specified and if Elastic search is enabled for a module, then it uses Elastic search
  • None of the above - uses Sugar search
### Global Search Option - one module search
GET {{rest_url}}/search?q=Hollywood
OAuth-Token: {{access_token}}
Unified Search

If you would like to use Elastic search only, then you can use the /globalsearch endpoint. It can be used as GET or POST

### Global Search - Search All Modules, or specific modules by passing module_list
GET {{rest_url}}/globalsearch?q=Hollywood&module_list=Accounts,Contacts
Content-Type: application/json
OAuth-Token: {{access_token}}
Elastic Search

Sorting

Sorting works a little differently in elastic search and you will have to pass an additional argument sort with the field name and the sort order. Using POST as an example:


### Global Search Sorting - It works differently here, doesn't work on order_by
### This example uses POST instead
POST {{rest_url}}/globalsearch
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "q": "Mining",
  "module_list": "Accounts",
  "sort": {
    "date_entered": "desc",
    "name": "desc"
  }
}
Using Elastic search with sorting - POST

File Uploads

SugarCRM API allows file upload using APIs. This feature is the least documented of all, but it is actually quite simple if you know how.

File uploads are tied to specific fields in a module. For example, Notes module has a field named filename. Documents module has the same field as well.

File uploads are usually done as Content-Type: multipart/form-data

Using PUT

To upload a file, use the /file/field_name endpoint, with the filename parameter used for the actual name.

### Notice the argument filename= which specifies the file name
PUT {{rest_url}}/Notes/51c9e4ae-c98c-11ea-9162-0242fa516d05/file/filename?filename=file.txt
OAuth-Token: {{access_token}}
Content-Type: multipart/form-data

< ./relative/path/to/local_file.txt
Uploading a file using PUT

Using POST

The POST API works a bit differently but it's all the same. If you want to add some multipart data for backend, you can use POST using boundaries:

### Uploading a file - POST Method, works a bit differently - uses multipart form submission
### Might be useful in case you want to read additional params
POST {{rest_url}}/Notes/51c9e4ae-c98c-11ea-9162-0242fa516d05/file/filename
OAuth-Token: {{access_token}}
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
Content-Disposition: form-data; name="filename"; filename="file.txt"

< ./relative/path/to/local_file.txt
--WebAppBoundary--
Uploading a file using POST Multipart

Bulk Operations

Bulk operations are really useful if you want to combine multiple API calls in one batch. This reduces the total time taken by running all the requests sequentially and returning the results as one.

/bulk endpoint

Here is an example of the /bulk endpoint. Just pass all your requests with url, method and data:

POST {{rest_url}}/bulk
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "requests": [
    {
      "url": "/v10/Accounts/filter?fields=name",
      "method": "GET",
      "data": "{ \"filter\": [ { \"tag\": {\"$in\": [\"Arts\"] } } ] }"
    },
    {
      "url": "/v10/Contacts/filter?fields=name",
      "method": "GET",
      "data": "{ \"filter\": [ { \"tag\": {\"$in\": [\"Arts\"] } } ] }"
    },
    {
      "url": "/v10/Meetings/filter?fields=name",
      "method": "GET",
      "data": "{ \"filter\": [ { \"tag\": {\"$in\": [\"Arts\"] } } ] }"
    }
  ]
}
Bulk API Example

Mass Update

Mass Update is something we do usually via the UI, but we can invoke the same endpoint using APIs as well.

This is useful if you want to update fields for a list of records, or if you want to delete multiple records at once.

But - you should know the IDs, which can be obtained using filters, if you really need it.

### MassUpdate
### Useful if you know several IDs and want to do a mass update
### You can also use MassDelete API to delete multiple ids at the same time
PUT {{rest_url}}/Accounts/MassUpdate
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "massupdate_params": {
    "uid": [
      "31bd6c03-fca9-40f4-a042-0e0a34e349ee",
      "1b642ea8-4555-49ce-bebb-0b70f7a17af3"
    ],
    "lead_source": "Marketing"
  }
}
MassUpdate Example

Miscellaneous

Count

In any API that returns a list of records, you can also fetch just the count instead of the records itself. This is usually faster since there is no data retrieval from the DB.

### Count
GET {{rest_url}}/Opportunities/filter/count?filter[0][amount][$gt]=5000
Content-Type: application/json
OAuth-Token: {{access_token}}
Count records

Ordering

Pass the order_by parameter that can be passed in the URL.

Pagination

Uses the usual offset, max_num parameters

### Pagination
GET {{rest_url}}/Accounts?order_by=name&offset=1&max_num=2&fields=name
Content-Type: application/json
OAuth-Token: {{access_token}}
Pagination Example

Enum Values

If you want to get the list of all possible values for a particular field, the /enum api does just that.

### Enum: Get all possible values for a field - Note this is only possible if you know the field name
GET {{rest_url}}/Contacts/enum/lead_source
OAuth-Token: {{access_token}}
Possible values for a field

Duplicate check

SugarCRM UI uses this feature by default. Uses in-built dupe-check logic, which can be customized in the backend.

### Duplicate Check - Use Sugar's inbuilt duplicate check to find if there are similar records
POST {{rest_url}}/Accounts/duplicateCheck
Content-Type: application/json
OAuth-Token: {{access_token}}

{
  "name": "Hollywood"
}
Duplicate Check

Current User Info

Use /me endpoint to get the current logged-in user info

### Get Current Logged-in user
GET {{rest_url}}/me
OAuth-Token: {{access_token}}
Current User

Using Sugar's documentation

SugarCRM has an inbuilt API documentation in rest/v10/help

Make use of it! It has detailed examples for every single type of API request.


Download from Github

Download the HTTP Rest Client files from our Github Repo and run them from your IDE:

seven-tunes-labs/sugarcrm-rest-client
Rest Client files for IntelliJ/VS Code to call SugarCRM - seven-tunes-labs/sugarcrm-rest-client
69246249

Please reach out to us if you have any questions.

More SugarCRM articles: