Invocable Methods: How to Send Data Between Flow and Apex

Invocable methods used with Flow allow you to launch something in an admin friendly format that uses the massive power of Apex. For example, you have an intake screen that collects answers to a few questions, then you use Apex to loop through many related records dispersing those answers in places hard to reach from Flow.

Creating an invocable method in a nutshell: First you write an apex class with @invocable method (label and description) and whatever code you want the apex to do (easy, right?) Then make your Flow including your input and output variables. Then add an Apex action in Flow to send/receive those variables.

Here are some things I learned about sending data between Flow and Apex.

SentSent FromReceived by Received
Record Variable.idFlowApexList<Id> listOfIds
Record Collection VariableFlowApexList<List<Opportunity>> nameOfThis
List containing 1 sObject recordApexFlowRecord (single) variable
List of Lists of sObjectApexFlowRecord Collection Variable

This is NOT an exhaustive list at all. I didn’t try sending a record variable (not just the ID from Flow), but I assume that will work. There are also generic sObjects that are pretty special, but I didn’t try.

Here are two examples of invocable methods used with Flows. Note that what you send to apex does not impact what you can receive, as far as I know.

Example One: Send One Id, Get Back a Record Collection

In this Flow, I tried using an Apex Action to avoid having a DML statement inside a loop. You may notice that there is also a loop inside another loop. So this Flow is not an example I want you to go out and copy (I ended up moving the whole thing to Apex), but I got the Apex Action to work and I learned a ton!
  • I sent a record id stored in a record variable from Flow to Apex.
  • The apex receives it as a List of Ids, even though it is just one id. (The apex input parameter is (List <Id> nameOfList)
  • To return a List of Lists start by making a list of an sObject type. [The next part is just an example. Substitute whatever code fits your needs.] I used SOQL to make a list for all Opportunities whose Primary Contact is the recordId sent from the Flow.
  • Add that List to a “List of Lists” of that same sObject type (yeah, weird, right?)
  • So my original List has one item, and my List of Lists has only one List. You with me?
  • My method returns that List of Lists of Opportunities and the Flow receives it as a Collection Variable!
This image is from the Apex Action inside the Flow.
public class contactsListAction {
    //this invocable method takes a single contact id from Flow from a record variable
    //and returns a list of lists of opportunities associated with that contact.
    //the list of lists is stored as a collection variable in the Flow.
    @InvocableMethod (label = 'SendContactsGet Opps' description = 'returns opps for this contact.')
    //this method returns a List of Lists of Opps to the flow and receives a List of Ids
    public static List<List<Opportunity>> getContactIds (List<ID> ids) {
        //Store in a list the id, closedate and Amounts of opps whose Primary Contact came in the variable "ids"
        //and who have a stage of Clsoed Won and a Close Date of this year
        List<Opportunity> opps = [SELECT id,CloseDate,Amount
                                  FROM Opportunity                                   
                                  WHERE npsp__Primary_Contact__c in :ids 
                                  AND StageName = 'Closed Won' 
                                  AND CloseDate = THIS_YEAR]; 
        //declare a new list of lists of opps
        List<List<Opportunity>> itemListList = new List<List<Opportunity>>();
        //add the list opps to the list of lists
        // send list of lists to the Flow	
        return itemListList;        

Example Two: Send a Collection, Receive Back One Record

  • I sent a record collection variable from the Flow to Apex.
  • The apex receives it as a List of Lists of type Opportunity.
  • [This part is just an example so can substitute whatever code you want here.] I’m finding the first List in the List of Lists, then finding the first Opp in that List and saving that as an opportunity record. I modify the value of the opp here.
  • I now have one opportunity record that I need to add to a new list of Opportunities.
  • I return that List (that just has one item in it) to the Flow.
public class sendManyGetOne {
    @InvocableMethod (label = 'Send Many Get One' description = 'send a collection of records to Apex, get one record back.')
    //this method returns a List containing one opportunity 
    //the parameters are a List of Lists of Opportunities. The flow sends this as a collection variable of opps.
    public static List<Opportunity> getOppId ( List<List<Opportunity>> listOppLists) {
        //get the first List from the List of Lists
        List<Opportunity> oppsList = listOppLists.get(0);
		//get the id and Amount from the Opp in that first List. 
        List<Opportunity> opps = [SELECT id,Amount
                                  FROM Opportunity                                   
                                  WHERE id in :oppsList]; 
        //convert that to an opportunity
        Opportunity newOpp = opps.get(0);
        //change a value on it
        newOpp.Amount = 800;
        //instantiate a new list 
        List <Opportunity> returnOpps = new List <Opportunity> ();
        //add that modified opp to the new list
        //send the new list of just one opp back to the Flow
        return returnOpps;

Learn More

Official Documentation on Invocable Methods.

Published by


Jessie is Success Content Specialist at All opinions expressed on this blog are her own or those of the contributors. For fourteen, she has specialized in CRM, email marketing and fundraising platforms. Jessie co-led the Seattle Salesforce Non-Profit User Group in 2015-2016. She wrote a sh*tty first draft of a novel and hopes to do something with it some day.

2 thoughts on “Invocable Methods: How to Send Data Between Flow and Apex”

  1. This is extremely useful, thank you so much! I find it weird that when I wish to send a collection, the matching datatype in Apex has to be a collection of collections. And it is not exactly properly documented by Salesforce anywhere, or at least I could not find it. Thanks for this.

    1. Exactly! I write most of my posts with the documentation could use some additional help 🙂

Leave a Reply to Sankalita Cancel reply