I went through some questions here like System.CalloutException: You have uncommitted work pending which provide answer where the callout can be split into asynchronous way.

Based on the information in below URL, https://help.salesforce.com/articleView?id=000079772&type=1

callout  <---- fails here

I am doing below:

insert (this insert is based on response from first callout, response is being used in second callout and response also gets upserted in custom object in FUTURE method)

Above scenario fails even though I am trying to split the insert operation into a Future/ Queueable method. I cannot have the second callout happening in asynchronous way as the response of second callout should be presented in UI

UseCase: 1) Callout - Retrieve accesstoken - valid for next 5 hours, so u want to reuse this 2) DML - Insert the accesstoken in custom object for reusing 3) Callout - Use the retrieved access token to get the actual response and pass to UI

When my method finds there is a valid active token in database, it is going to skip step 1 from above and proceed to Step 2 and 3. This scenario works perfectly.

It fails when there is no active token found and it has to begin from Step 1.

Any suggestions ?

  • How is this transaction invoked? Is this originating from a visualforce page?
    – Bob Lopez
    Commented Jan 11, 2018 at 21:19
  • Yes, it gets invoked from VF Page but there is one scenario where token is retrieved from custom object and is used for making callout. At this time, for some reason token gets invalidated, I will get 401 error from 2nd callout which means i need to get new access token before calling out 2nd time meaning complete step1 to 3 again !!
    – sf_user
    Commented Jan 11, 2018 at 21:34
  • 1
    It sounds like you don't need to do your insert before your second callout. Make callout 1, create custom sObject with token, but do not insert yet, make callout 2, then do your DML insert. (BTW, storing an access token in the database doesn't seem very secure) Commented Jan 12, 2018 at 3:00

2 Answers 2


Splitting the insert operation into a Future/Queueable method is (believe it or not!) actually performing an insert... an insert into the queue!

To solve your problem, do your first callout and the insert in the same transaction, then do your second callout in a Future/Queueable method.

The way I remember and avoid the dreaded "uncommited work pending" exception is for any given transaction, we have to do ALL the callouts first, followed by any DML (or queueing!) operation.

  • Thanks John for your reply. I understand your solution works and is also recommended approach. But as i said, I will need the response from the second callout. So i cannot have them in future/ Queueable
    – sf_user
    Commented Jan 11, 2018 at 21:35
  • Can you switch it to callout1, callout2, insert in some way? For example, set up all the fields of the objects about the be inserted, call any methods called by the trigger, do the second callout and finally insert the needed record?
    – Jochen
    Commented Jan 11, 2018 at 21:37
  • Thanks John. I think it makes more sense in my case to postpone DML to end of transaction after completing callouts
    – sf_user
    Commented Jan 12, 2018 at 3:22

Refer my blog post Visualforce webservice callout synchronously & asynchronously

If you want to achieve as follows and want to display the response of the 2nd callout on UI, without using Future/Queueable method then here is the approach.



Create a Visualforce and command button action will call FirstCalloutAndSave method to perform callout and DML operation.

Then oncomplete method will perform perform2ndCallOut calling submit method (in a separate transaction) and results of the 2nd callout will be displayed on UI.

<apex:page id="MyVisualforcePage" controller="myExampleController"  showHeader="false">
    <apex:pageMessages id="msgId"/>
        function performSecondCallOutMethod()
    <apex:form id="myForm">
        <apex:actionFunction name="perform2ndCallOut" action="{!submit}" reRender="script-block,msgId"/>
        <!--fields on the UI -->
        <apex:commandButton value="Save" action="{!FirstCalloutAndSave}"
             oncomplete="return performSecondCallOutMethod();" reRender="msgId"/>


public class MyController

    public PageReference FirstCalloutAndSave()
         //1. perform firstout
         //2. perform DML

    public PageReference submit()
           //perform 2ndCallout and show the result in the visualfore page
           return null
        catch (Exception ex)
           System.debug('Error in submit ' + ex);
                                ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.Error, ex.getMessage());
                                return null;
  • This is even easier with Lightning components! Commented Jan 12, 2018 at 2:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .