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