Process Automation and Logic · Topic 1 of 7
Declarative Automation and Combining Flow with Apex
Flow types a developer must know, and how Flow and Apex work together: invocable methods and variables, calling flows from Apex, and platform events.
- 4 min
- Build new automation in Flow; Workflow Rules and Process Builder are out of support.
- Before-save flows update the triggering record; after-save flows handle related records and actions.
@InvocableMethod: static, public or global, one per class, list in and list out.
What it is
Flow is Salesforce's declarative automation tool. Workflow Rules and Process Builder reached end of support on 31 December 2025; existing ones still run, but new automation is built in Flow or Apex.
A developer must know what Flow can do on its own, and how to extend it with Apex when it cannot: an invocable method lets a flow call Apex, and Apex can start a flow.
How it works
Flow types
| Flow type | Starts when |
|---|---|
| Screen flow | A user launches it; the only type with screens |
| Record-triggered flow | A record is created, updated or deleted |
| Schedule-triggered flow | At a set time and frequency |
| Platform event-triggered flow | A platform event message arrives |
| Autolaunched flow | Called by another flow, Apex, a button, REST API or an agent action |
Record-triggered flows run before save (fast field updates on the triggering record) or after save (related records, actions, email). They can also have scheduled paths and a run asynchronously path.
When Flow is not enough
| Need | Apex is the fit |
|---|---|
| Complex calculations or data structures | Apex collections, maps and classes |
| Callouts with custom parsing or error handling | Apex HTTP callouts |
| Very large data volumes | Batch Apex |
| Logic shared by flows, LWCs and agents | One invocable or @AuraEnabled Apex method |
Invocable methods: Flow calls Apex
public with sharing class TierLookup {
public class Request {
@InvocableVariable(required=true label='Contact Id')
public Id contactId;
}
public class Result {
@InvocableVariable public String tier;
}
@InvocableMethod(label='Get Tier' description='Returns the loyalty tier for each contact')
public static List<Result> run(List<Request> requests) {
Set<Id> ids = new Set<Id>();
for (Request r : requests) ids.add(r.contactId);
Map<Id, Contact> byId = new Map<Id, Contact>(
[SELECT Tier__c FROM Contact WHERE Id IN :ids]);
List<Result> out = new List<Result>();
for (Request r : requests) {
Result res = new Result();
res.tier = byId.containsKey(r.contactId) ? byId.get(r.contactId).Tier__c : null;
out.add(res);
}
return out;
}
}
Rules for @InvocableMethod:
- Static, and public or global.
- Only one invocable method per class.
- Takes at most one parameter, a List (of primitives, sObjects or a class with
@InvocableVariablefields), and returns a List or nothing. - When a record-triggered flow runs for 200 records, the method is called once with a list of 200 inputs. Return one output per input, in the same order.
The same invocable method can be used as an Agentforce agent action; its label and descriptions help the agent choose it and fill its inputs.
Apex starts a flow
Map<String, Object> inputs = new Map<String, Object>{ 'recordId' => acc.Id };
Flow.Interview interview = Flow.Interview.createInterview('Welcome_Pack', inputs);
interview.start();
Platform events connect both sides
Publish an event from Apex with EventBus.publish(event) or from Flow with a Create Records element. Subscribe with an Apex trigger (after insert on the event) or a platform event-triggered flow. Platform event triggers run as the Automated Process user by default.
A worked example
A record-triggered flow on Opportunity must assign a risk score that needs a weighted calculation across related records. The admin keeps the flow, and the developer writes an invocable method that accepts a list of Opportunity Ids, queries everything once, and returns the scores in input order. The flow calls it as an Apex action, then sets the field. Admins keep control of the process; the hard logic stays bulk-safe in Apex.
If a question shows an invocable method that queries inside a loop over its inputs, that is the bug. The method receives the whole batch in one call.
How the exam asks about this
- "Make an Apex method available to Flow."
@InvocableMethod. - "Expose fields of an input class to Flow."
@InvocableVariable. - "How many times is the invocable method called for 200 records?" Once, with a list of 200.
What to remember for the exam
- Build new automation in Flow; Workflow Rules and Process Builder are out of support.
- Before-save flows update the triggering record; after-save flows handle related records and actions.
@InvocableMethod: static, public or global, one per class, list in and list out.- Flows and Apex share the transaction's governor limits.
- Apex starts a flow with
Flow.Interview.createInterview(...).start().
Returning fewer results than inputs, or in a different order, gives flow interviews the wrong values. Return exactly one result per request, in order.
Common mistakes
Writing two invocable methods in one class. Only one is allowed per class.
Accepting a single Id instead of a List. The parameter must be a list, because Flow bulkifies calls.
Assuming a flow's Apex action gets its own limits. It runs in the same transaction.
Check yourself
What annotation makes an Apex method callable from Flow?
@InvocableMethod, on a static public or global method that takes a list.A record-triggered flow runs for 150 records. How is its invocable method called?
Once, with a list holding all 150 inputs.
How can Apex start an autolaunched flow?
With
Flow.Interview.createInterview(flowName, inputs)and thenstart().
Topic 1 of 7 in Process Automation and Logic
Test yourself on Process Automation and Logic
The full Salesforce Platform Developer question bank has 645 questions, with timed practice exams and an explanation for every answer.
This study guide is independent and is not affiliated with, endorsed by, or sponsored by Salesforce. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.