Salesforce to Salesforce REST API Integration

Hi Salesforce Developer!
I am glad you are here. Today I would like to show you how to connect two different Salesforce instances (by REST) or make REST API callouts within the same org.

You could ask me, why should I make callouts within the same org?

And I would answer:
Good question!
– It allows you to get new DML limits!
– You can log in as a different user to get access to objects you normally don’t have access to (you can skip permission)

Let’s begin!

Salesforce REST API Overview

We can configure two types of Salesforce to Salesforce REST API connections.
– Org A to Org B
– Callouts on the same org

Salesforce to Salesforce REST API
Salesforce to Salesforce – The same environment

1. Create your REST API endpoints

The first step is about creating some endpoint. In my example, I have created REST API responsible for GET, DELETE and POST (Add) accounts records.

Below you can find my APEX code.

@RestResource(urlMapping='/Account/*')
global with sharing class AccountAPI {

   @HttpDelete
    global static void doDelete() {
        RestRequest req = RestContext.request;
        RestResponse res = RestContext.response;
        String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
        Account account = [SELECT Id FROM Account WHERE Id = :accountId];
        delete account;
    }

    @HttpGet
    global static Account doGet() {
        RestRequest req = RestContext.request;
        RestResponse res = RestContext.response;
        String accountId = req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
        Account result = [SELECT Id, Name, Phone, Website FROM Account WHERE Id = :accountId];
        return result;
    }

    @HttpPost
    global static String doPost(String name, String phone, String website) {
        Account account = new Account();
        account.Name = name;
        account.phone = phone;
        account.website = website;
        insert account;
        return account.Id;
    }

}

2. Create a Salesforce Connected App

The next step is to create a Connected App. On your org go to Setup > App Manager > New Connected App.

Use the same org which contains endpoint defined in first step!

1. Add new Connected App
  • Select name for your app 🙂
  • Check Enable Oauth Settings.
  • Callback URL – We can use a placeholder https://www.login.salesforce.com/services/authcallback. This field is required but we don’t know the exact URL yet.
  • Set Selected OAuth Scope and adjust it for your purpose.
2. Configure Connected App

Copy Consumer Key and Consumer Secret. Those two keys will be necessary to connect with our app.

3. Copy Consumer Key and Consumer Secret

3. Create Auth. Provider

On org where you want to make callouts – create a new Auth. Provider. You can do that by going to Setup > Auth. Provider > New

In this case, choose Salesforce.

4. Select Salesforce

Fulfill fields like on the screenshot below.

  • Provided Type – It should be a “Salesforce
  • Customer KeyCustomer Key Value from your Connected App
  • Customer SecretCustomer Secret Value from your Connected App
  • Authorize Endpoint URL – https://login.salesforce.com/services/oauth2/authorize
  • Token Endpoint URL – https://login.salesforce.com/services/oauth2/token
    Salesforce endpoints
5. Fulfill fields
6. Check Test-Only Initialization URL and Callback URL

IMPORTANT! Copy Callback URL. Go to org with defined Connected App – Setup > App Manager > Select Your App > Edit. Past Callback URL to proper place and Save

7. Past Callback URL

Note: “Allow from 2-10 minutes for your changes to take effect on the server before using the connected app.” Changes in Your App can take some time.

Test your connection!
Back to Auth. Provider and open Test-Only Initialization URL, you can find it in Salesforce Configuration section – Check screen above (no.6). It allows you to check connections.
If you see that error: “error=redirect_uri_mismatch&error_description=redirect_uri%20must%20match%20configuration” you probably didn’t change Callback URL in your app or you need to wait a little bit (10 minutes).

If everything is ok, you should be able to see salesforce login popup. Log in to Salesforce by your credentials. In an ideal situation, you should have some integration user. 🙂

8. Authorize your app

4. Create Named Credentials

Step four! Named Credentials can help you with authorization.
Salesforce manages all authentication for Apex callouts that specify a named credential as the callout endpoint so that your code doesn’t have to. “
Setup > Named Credentials > New

9. Create new Named Credentials
  • Label – Select name for your API
  • Name – This name will be used in Apex
  • URL – As a URL use salesforce org which provides endpoints. (The same one where you created the Connected App)
  • Authentication Protocol – Select OAuth 2.0
  • Authentication Provider – Select the provider you have created before.
  • Scope – Select the scope you need. Remember you can only use a scope selected in your Connected App. Scopes should be separated by space.
  • Start Authentication Flow on Save – When you check Start Authentication Flow on Save you will be asked to log in to salesforce.

    Click the Save button. Log in to salesforce org where you have defined Connected App and check Authentication Status. As I said earlier in an ideal situation you should be authorized as an Integration User. 🙂
10. Test your authrization

5. Remote Site Settings (Optional)

If the callout specifies a named credential as the endpoint, you don’t need to configure remote site settings. A named credential specifies the URL of a callout endpoint and its required authentication parameters in one definition. To set up named credentials, see “Define a Named Credential” in the Salesforce Help. ~ Salesforce

Before tests, we need to add our endpoint URL to Remote Site Settings, otherwise, Salesforce doesn’t allow you to make a callout (if we don’t have Named Credentials).
Setup > Remote Site Settings > New Remote Site

11. Set Remote Site Settings

Remote Site URL – Should be the same as your salesforce instance which contains endpoints.

Done! Test Your App!

Create a new Apex class on salesforce org where you have defined Auth. Provider, Named Credentials and Remote Site Setting.

public with sharing class AccountWebService {

    public static Http http = new Http();
    public static HTTPResponse response;
    public static HttpRequest request;

    public class NewAccountRequestWrapper {
        public String name {get; set;}
        public String phone {get; set;}
    }

    public static void getAccount(Id accId) {

        request = new HttpRequest();
        request.setMethod('GET');
        request.setEndpoint('callout:SalesforceAccount/services/apexrest/Account/' + accId);

        response = http.send(request); 

        System.debug(response.getBody());
    }

    public static void addAccount(NewAccountRequestWrapper newAccount) {

        request = new HttpRequest();
        request.setMethod('POST');
        request.setEndpoint('callout:SalesforceAccount/services/apexrest/Account');
        request.setHeader('Content-Type', 'application/json;charset=UTF-8');
        request.setBody(JSON.serialize(newAccount));

        response = http.send(request); 

        System.debug(response.getBody());
    }

    public static void deleteAccount(Id accId) {

        request = new HttpRequest();
        request.setMethod('DELETE');
        request.setEndpoint('callout:SalesforceAccount/services/apexrest/Account/' + accId);

        response = http.send(request); 

        System.debug(response.getBody());
    }

}

Use anonymous apex to invoke methods.

//Add a new Account
AccountWebService.NewAccountRequestWrapper newAccount = new AccountWebService.NewAccountRequestWrapper();
newAccount.name = 'TestAccount';
newAccount.phone = '123456789';
AccountWebService.addAccount(newAccount);
//get Account details based on Id
AccountWebService.getAccount('123123123');
//delete Account based on Id
AccountWebService.deleteAccount('12121212');

Resource

Was it helpful? Check out our other great articles here.

4.8 21 votes
Article Rating
Subscribe
Notify of
guest
30 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
trackback

[…] Salesforce to Salesforce REST API Integration … […]

Shail
Shail
1 month ago

Awesome step-by-step description.
I am getting this error trying to send a request:
CustomException/n 302
System.HttpResponse[Status=Found, StatusCode=302]

Would appreciate your help here.

[Resolved: I was using domain name URL in named credential URL. Your’s is the correct one. Thanks heaps 🙂 ]

Last edited 1 month ago by Shail
Cherisse
Cherisse
3 months ago

I am running this as a scheduled job. It works for a couple of days and then I receive the following error:  [{“message”:”Session expired or invalid”,”errorCode”:”INVALID_SESSION_ID”}]. The only way it will start to work again, is by manually resetting my named credential, and I have to keep doing this every few days. Any ideas? My scope is set to “full refresh_token”

Narendra Sa
Narendra Sa
5 months ago

Thanks for the refference and direction, but the details i pass goes to the destination org but not in source org, what is happening and how do you update same in source org, usin anynomous window its only showing data in destination org

Sajal
Sajal
7 months ago

Why you are using Remote site setting , when you are already using Named Credential ?

Manish
Manish
10 months ago

System.CalloutException: Unable to tunnel through proxy. Proxy returns “HTTP/1.1 503 Service Unavailable” getting error after following the same above steps

Last edited 10 months ago by Manish
Ansh
Ansh
10 months ago

I am getting this error on the give line(response = http.send(request); )

System.UnexpectedException: Script-thrown exception

Rakesh
Rakesh
1 year ago

Hi, I am facing issue in passing multiple parameters and reading the same. Please help me out with this.

Rakesh
Rakesh
1 year ago

Am getting this error when i try to run the code in anon apex window.
00:37:31:586 NAMED_CREDENTIAL_RESPONSE_DETAIL [{“message”:”Session expired or invalid”,”errorCode”:”INVALID_SESSION_ID”}]
00:37:31:629 CALLOUT_RESPONSE [18]|System.HttpResponse[Status=Unauthorized, StatusCode=401]

Rahul Reddy
Rahul Reddy
1 year ago

I think we dont need to register endpoint in remote site settings

Close Menu
30
0
Would love your thoughts, please comment.x
()
x