Post originally written by sugarmajed.
Welcome to the School of REST - our first installment in the Sugar 7 Cookbook Series! We've always believed that DATA belongs to you and it should always be accessible to you! With Sugar 7 we've added a completely revamped REST API. Today we are going to cover all the basics of pushing data into and getting data out of your SugarCRM instance. For each of the API calls we'll show how to do it in curl, a generic HTTP Request, as well as showing you the response. Also, before we get started you can always hit /rest/v10/help for detailed documentation on all the APIs.
In this Guide we will be creating an Account "Burger Palace" and relating it to a Contact "Bob Burger". We will then show you the ins and outs of Creating and Updating Records, Filtering Lists, Creating Relationships, Filtering on Relationships, Marking Records as Favorites, and Deleting Records.
This guide is broken into 3 sections.
Part 1 - Connecting, Creating Records, and Filtering Lists
Part 2 - Retrieving, Updating, and Relating Records
Part 3 - Filtering on Relationships, Favorites, and Deleting Records
You may want to download PostMan for Chrome to follow along interactively from http://www.getpostman.com/
You can download Our Cookbook1 PostMan collection from https://gist.github.com/mitani/f39e8d94df9fbda4d97d
Step 1. Connecting/Authenticating
Sugar 7 uses two-legged OAuth2 for authentication. You simply need to do a POST to /rest/v10/oauth2/token with the following params:
grant_type | String | Type of request. Available grant types are "password" and "refresh_token". |
client_id | String | The client_id of "sugar" will automatically create an OAuth Key in the system and can be used for "password" authentication. The client_id of "support_portal" will create an OAuth Key if the portal system is enabled and will allow for portal authentication. Other client_id's can be created by the administrator in the OAuthKeys section in the Administration section and can be used in the future for additional grant types, if the client secret is filled in, it will be checked to validate use of the client id. |
client_secret | String | The clients secret key. |
username | String | The username of the user authenticating to the system. |
password | String | The plaintext password the user authenticating to the system. |
platform | String | Defaults to "base" allows you to have custom meta-data per platform |
So, first we are going to login using a grant_type of "password".
CURL.sh
curl -X POST -H Cache-Control:no-cache -H Postman-Token:a6ae8f76-442f-06cf-1072-db18b0ad29a3 -d '{ "grant_type":"password", "client_id":"sugar", "client_secret":"", "username":"username", "password":"password", "platform":"base" }' http://server/pro720/rest/v10/oauth2/token
POST token.http
POST /pro720/rest/v10/oauth2/token HTTP/1.1
Host: Server
Cache-Control: no-cache
Postman-Token: 83a606e1-26f6-ff21-dd5d-f25f6cb735eb
{ "grant_type":"password", "client_id":"sugar", "client_secret":"", "username":"username", "password":"password", "platform":"base" }
response.json
{
"access_token": "5ee48ec7-023e-ecff-5184-530bd0358868",
"expires_in": 3600,
"token_type": "bearer",
"scope": null,
"refresh_token": "5f197357-0167-f7a6-7912-530bd03275b6",
"refresh_expires_in": 1209600,
"download_token": "5f531625-e301-e3ea-1b11-530bd098be41"
}
Once you get the response you'll need to hold onto the access_token and the refresh_token. Anytime the access_token is invalidated, you'll want to make another request to the token endpoint with a grant_type of "refresh_token". Store just the refresh_token in long term storage - not the username and password.
For all the following requests we are going to pass in a header of OAuth-Token: {{your access token here}}
2. Create an Account - Burger Palace
Now that we have the access_token we can start having some fun! Let's create a new customer - "Burger Palace" as an Account.
Being that everything is RESTful creating a new record is just a POST away. In this case we just do a POST to /rest/v10/Accounts.
For this example we will be posting an id as part of the record. You do not need to do this as SugarCRM will automatically generate an id for your record.
CURL Accounts.sh
curl -X POST -H OAuth-Token:9126cdb4-0c4e-4796-1a4f-530bccd48060 -H Cache-Control:no-cache -H Postman-Token:cb3331fa-7e62-1f11-9fae-cb9731bc3500 -d '{ "id":"demo_burger_palace", "name":"Burger Palace", "account_type":"Customer", "description":"My Example Account", "email":[{"email_address":"burgers@example.com"}] }' http://server/pro720/rest/v10/Accounts
POST Accounts.http
POST /pro720/rest/v10/Accounts HTTP/1.1
Host: server
OAuth-Token: 9126cdb4-0c4e-4796-1a4f-530bccd48060
Cache-Control: no-cache
Postman-Token: 90329f95-f2a9-fd87-c4cf-421fdd9f24ae
{ "id":"demo_burger_palace", "name":"Burger Palace", "account_type":"Customer", "description":"My Example Account", "email":[{"email_address":"burgers@example.com"}] }
Response.json
{
"id": "demo_burger_palace",
"name": "Burger Palace",
"date_entered": "2014-02-25T10:51:51-08:00",
"date_modified": "2014-02-25T10:51:51-08:00",
"modified_user_id": "1",
"modified_by_name": "Administrator",
"created_by": "1",
"created_by_name": "Administrator",
"doc_owner": "",
"user_favorites": "",
"description": "My Example Account",
"deleted": false,
"assigned_user_id": "",
"assigned_user_name": "",
"team_count": "",
"team_name": [
{
"id": 1,
"name": "Global",
"name_2": "",
"primary": true
}
],
"email": [
{
"email_address": "burgers@example.com",
"invalid_email": false,
"opt_out": false,
"primary_address": false,
"reply_to_address": false
}
],
"email1": "burgers@example.com",
"email2": "",
"invalid_email": false,
"email_opt_out": false,
"facebook": "",
"twitter": "",
"googleplus": "",
"account_type": "Customer",
"industry": "",
"annual_revenue": "",
"phone_fax": "",
"billing_address_street": "",
"billing_address_street_2": "",
"billing_address_street_3": "",
"billing_address_street_4": "",
"billing_address_city": "",
"billing_address_state": "",
"billing_address_postalcode": "",
"billing_address_country": "",
"rating": "",
"phone_office": "",
"phone_alternate": "",
"website": "",
"ownership": "",
"employees": "",
"ticker_symbol": "",
"shipping_address_street": "",
"shipping_address_street_2": "",
"shipping_address_street_3": "",
"shipping_address_street_4": "",
"shipping_address_city": "",
"shipping_address_state": "",
"shipping_address_postalcode": "",
"shipping_address_country": "",
"parent_id": "",
"sic_code": "",
"duns_num": "",
"parent_name": "",
"campaign_id": "",
"campaign_name": "",
"my_favorite": false,
"_acl": {
"fields": {}
},
"following": true,
"_module": "Accounts"
}
And of course you can add any additional fields that you would like to set.
3. Retrieve a list of Accounts
Great, now that we have records in our system let's fetch them back. Being RESTful you just need to do a GET request to /rest/v10/Accounts. Don't forget to pass in the OAuth-Token header. To speed things up be specific about the fields that you want. Let's just fetch the name, account type, and description by passing in fields=name,account_type,description. We'll pass in max_num to specify that we only want 3 records at a time. By default if max_num isn't set it will return 20 records. In this case the request will look like /rest/v10/Accounts?fields=name,account_type,description&max_num=3
CURL Accounts.sh
curl -X GET -H OAuth-Token:df488865-4a70-6d88-036c-530ce62453d0 -H Cache-Control:no-cache -H Postman-Token:19a88a98-b2bf-da03-a1f9-ab22730bd3e2 http://server/pro720/rest/v10/Accounts?fields=name,account_type,description&max_num=3
GET Accounts.http
GET /pro720/rest/v10/Accounts?fields=name%2Caccount_type%2Cdescription&max_num=3 HTTP/1.1
Host: server
OAuth-Token: df488865-4a70-6d88-036c-530ce62453d0
Cache-Control: no-cache
Postman-Token: 74200fe5-a926-a5d4-d07d-d899bb1a573e
Response.json
{
"next_offset": 3,
"records": [
{
"id": "demo_burger_palace",
"name": "Burger Palace",
"date_modified": "2014-02-25T10:51:51-08:00",
"description": "My Example Account",
"account_type": "Customer",
"_acl": {
"fields": {}
},
"_module": "Accounts"
},
{
"id": "ec125a78-f202-250b-e75e-530ca4d7d1d0",
"name": "Ink Conglomerate Inc",
"date_modified": "2014-02-25T06:11:00-08:00",
"description": "",
"account_type": "Customer",
"_acl": {
"fields": {}
},
"_module": "Accounts"
},
{
"id": "ebc56ea4-ef13-b024-c07d-530ca40c97e4",
"name": "Constrata Trust LLC",
"date_modified": "2014-02-25T06:11:00-08:00",
"description": "",
"account_type": "Customer",
"_acl": {
"fields": {}
},
"_module": "Accounts"
}
]
}
Excellent! If we wanted to paginate we could just add the offset parameter to the request. That is the number of records you want to skip in the list before returning anything. So passing an offset of 3 would get us to the next page of records.
4. Filter a list of Accounts by Name
Now, let's filter our list for records that have the name "Burger Palace". To do this we just need to do a GET request to /rest/v10/Accounts and to pass in the filter parameter. In this case the request would look like /rest/v10/Accounts?filter[0][name]=Burger Palace&fields=name,account_type,description
CURL Accounts Filter.sh
curl -X GET -H OAuth-Token:34b05aba-e8be-0db8-5fbe-530d19787689 -H Cache-Control:no-cache -H Postman-Token:347571b3-c873-f846-b469-c002810f4538 http://server/pro720/rest/v10/Accounts?filter[0][name]=Burger Palace&fields=name,account_type,description,email
GET Accounts Filter.http
GET /pro720/rest/v10/Accounts?filter%5B0%5D%5Bname%5D=Burger%20Palace&fields=name%2Caccount_type%2Cdescription%2Cemail HTTP/1.1
Host: server
OAuth-Token: 34b05aba-e8be-0db8-5fbe-530d19787689
Cache-Control: no-cache
Postman-Token: 548a67ec-ebfe-fa37-51a3-698783eaff16
Response.json
{
"next_offset": -1,
"records": [
{
"id": "demo_burger_palace",
"name": "Burger Palace",
"date_modified": "2014-02-25T14:32:25-08:00",
"description": "My Example Account",
"email": [
{
"email_address": "burgers@example.com",
"invalid_email": false,
"opt_out": false,
"primary_address": false,
"reply_to_address": false
}
],
"account_type": "Customer",
"_acl": {
"fields": {}
},
"_module": "Accounts"
}
]
}
You'll notice in the response that the next_offset in the response is set to -1 which means that there are no more records in the collection.
5. Filter a list of Accounts by Names starting with "B" and a specific email address
Now, let's pass in multiple filter conditions and let's use some of the filter operations.
Sugar 7 supports the following filter operations
$equals | Performs an exact match on that field. |
$not_equals | Matches on non-matching values. |
$starts | Matches on anything that starts with the value. |
$in | Finds anything where field matches one of the values as specified as an array. |
$not_in | Finds anything where field does not match any of the values as specified as an array. |
$is_null | Checks if the field is null. This operation does not need a value specified. |
$not_null | Checks if the field is not null. This operation does not need a value specified. |
$lt | Matches when the field is less than the value. |
$lte | Matches when the field is less than or equal to the value. |
$gt | Matches when the field is greater than the value. |
$gte | Matches when the field is greater than or equal to the value. |
So to filter for Account names starting with the letter "B" we'll use the $starts operator. So instead of "filter[0][name]=Burger Palace" we can use filter[0][name][$starts]=B.
SugarCRM stores email addresses as normalized values. To search for an Account with an email address we need to search using the relationship for email addresses which is email_addresses. Specifically, we want to filter on the field email_address within that relationship. So to do an exact match on a specific email address we pass in filter[0][email_addresses.email_address]=burgers@example.com. Our request will look like /rest/v10/Accounts?filter[0][name][$starts]=B&filter[0][email_addresses.email_address]=burgers@example.com&fields=name,account_type,description,email . You will notice that we also added email to the list of fields that we wish to have returned which will cause it to return a collection of all the email addresses that are associated with this record.
curl -X GET -H OAuth-Token:e2505ba8-fc56-de05-ce9f-530d1bf56227 -H Cache-Control:no-cache -H Postman-Token:cb452a8c-2bb9-ebf6-ae66-a0700b10cdcc http://honey-b/pro720/rest/v10/Accounts?filter[0][name][$starts]=B&filter[0][email_addresses.email_address]=burgers@example.com&fields=name,account_type,description,email
GET /pro720/rest/v10/Accounts?filter%5B0%5D%5Bname%5D%5B%24starts%5D=B&filter%5B0%5D%5Bemail_addresses.email_address%5D=burgers%40example.com&fields=name%2Caccount_type%2Cdescription%2Cemail HTTP/1.1
Host: server
OAuth-Token: e2505ba8-fc56-de05-ce9f-530d1bf56227
Cache-Control: no-cache
Postman-Token: 29bd612a-828d-ad84-7f6a-dd8ba2314956
{
"next_offset": -1,
"records": [
{
"id": "demo_burger_palace",
"name": "Burger Palace",
"date_modified": "2014-02-25T14:32:25-08:00",
"description": "My Example Account",
"email": [
{
"email_address": "burgers@example.com",
"invalid_email": false,
"opt_out": false,
"primary_address": false,
"reply_to_address": false
}
],
"account_type": "Customer",
"_acl": {
"fields": {}
},
"_module": "Accounts"
}
]
}
Continue to Part 2 - Retrieving, Updating, and Relating Records