I have an existing scheduled callout which returns data that we save in Salesforce. The number of records being returned from the external webservice API is constantly increasing, so I would like to move this to batch.

In order to process the response, I also have to make several SOQL queries to the Salesforce database, and compare the existing Salesforce data to the data returned by the external webservice API.

How can I pass the callout response data, and the results of several SF queries, to the "execute" method of the batch class? In all the examples that I see, it seems that only one list of one object is being passed to the "execute" method. Is that all batch can do?

public Database.QueryLocator start(Database.BatchableContext BC){

        Http http = new Http();
            ...construct callout
        HttpResponse response = http.send(request);

        Map<String, Object> ResponseMap = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());

        List<Object> ListOfEnvs = (List<Object>)ResponseMap.get('assets');    

        Contact [] Cons = [SELECT Email, AccountID FROM Contact WHERE Email != null]

        CustomObject [] CustObjs = [SELECT Field1, Field2 FROM CustomObject]
   public void execute(Database.BatchableContext BC, ??????????){
        for(Object Env : ListOfEnvs){

        for(Contact Con : Cons){ 

        for(CustomObject CustObj : CustObjs){ 
   public void finish(Database.BatchableContext BC){


1 Answer 1


The start method is used to return whatever records you want to process.
The execute method will process a subset of those records. You can add whatever soql queries you want to this method to do your processing.

I assume you make the callout and then do some processing on each result from the callout? If so, make the results of the callout the return value of your start method, and then you can query the related objects within your execute.

Since your start is not a database query, you will have to return an Iterable and not a Database.QueryLocator.

  • Thanks, but if the SOQL is done in "execute", won't that mean that the same SOQL query is getting used in every batch, instead of just once in "start"? That somewhat reduces the usefulness of using batch at all from an efficiency standpoint. Can I do the callout AND SOQL in "start", make my changes to records in memory in "start", and then pass those records as an iterable to "execute", and perform nothing except "update [iterable]" in "execute"?
    – number41
    Nov 24, 2020 at 1:02
  • The usefulness of a batch job is that you can process a chunk of a large dataset in its own execution context. This will avoid governor limits. If you can do all queries in start without the code crapping out, then you don't need a batch class.
    – willard
    Nov 24, 2020 at 18:09

You must log in to answer this question.

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