Flow & Invocable Apex

@InvocableMethod exposes Apex as an action in Flow, Process Builder (legacy), the REST API (/services/data/vXX.X/actions/custom/apex/ClassName), and Agentforce (§40).

32.1 Invocable methods

@InvocableMethod exposes Apex as an action in Flow, Process Builder (legacy), the REST API (/services/data/vXX.X/actions/custom/apex/ClassName), and Agentforce (§40).

Rules: one @InvocableMethod per class; the method is public/global static; it takes one parameter that is a List (of primitives, sObjects, or classes with @InvocableVariable) and returns a List (or nothing). Flow bulkifies interviews: when 200 records trigger a flow, your method receives a list of 200 requests — write it bulk-safe and return results in the same order.

public with sharing class CalculateShippingAction {

    public class Request {
        @InvocableVariable(label='Order Id' description='Order to price' required=true)
        public Id orderId;
        @InvocableVariable(label='Express shipping?')
        public Boolean express;
    }

    public class Result {
        @InvocableVariable(label='Shipping cost')
        public Decimal cost;
        @InvocableVariable(label='Carrier')
        public String carrier;
    }

    @InvocableMethod(label='Calculate Shipping' description='Returns a shipping quote for an order'
                     category='Orders' callout=false)
    public static List<Result> calculate(List<Request> requests) {
        Set<Id> orderIds = new Set<Id>();
        for (Request r : requests) orderIds.add(r.orderId);
        Map<Id, Order> orders = new Map<Id, Order>(
            [SELECT Id, TotalAmount FROM Order WHERE Id IN :orderIds WITH USER_MODE]);

        List<Result> results = new List<Result>();
        for (Request r : requests) {                        // one result per request, same order
            Result res = new Result();
            Decimal base = orders.containsKey(r.orderId) ? orders.get(r.or
…

32.2 Calling Flows from Apex

Map<String, Object> inputs = new Map<String, Object>{ 'recordId' => acc.Id, 'notify' => true };
Flow.Interview.Account_Onboarding flow = new Flow.Interview.Account_Onboarding(inputs);
flow.start();
String status = (String) flow.getVariableValue('outStatus');

// dynamic
Flow.Interview dyn = Flow.Interview.createInterview('Account_Onboarding', inputs);
dyn.start();

32.3 Flow vs Apex decision guide

Simple field updates (before-save flows are very fast) Complex algorithms, heavy loops, large data volumes Admin-maintainable logic, screens Precise transaction control, savepoints

Notifications, approvals, simple record creation Integrations with complex auth/parsing

Reusable logic exposed to Flow via invocable actions