# Combining Flow and Apex for business logic

*Platform Developer Study Guide · Process Automation and Logic · Last updated October 15, 2026 · https://www.certifyforce.com/study-guide/platform-developer/process-automation-and-logic/combining-flow-and-apex*

How to expose Apex to Flow with @InvocableMethod and @InvocableVariable, why invocable actions take and return lists that line up with the flow's interviews, how flows start from Apex, and where to draw the line between the flow and the code.

- Certification: Salesforce Platform Developer
- Exam section: Process Automation and Logic
- Study guide: https://www.certifyforce.com/study-guide/platform-developer

**Official exam objective:**

> Given a scenario, use declarative functionality and Apex together to automate business logic.

## What the exam expects

- Make Apex available to Flow Builder as an Apex action with `@InvocableMethod`, and pass structured inputs and outputs with `@InvocableVariable`.
- Apply the invocable rules: static, public or global, one per class, one list parameter, a list result that matches the inputs in size and order.
- Predict how a record-triggered flow calls an Apex action for 200 records, and which limits the action shares.
- Start a flow from Apex with the `Flow.Interview` class.
- Given a scenario, decide which part of the logic stays in the flow and which moves to Apex.

Key terms: **invocable method** (an Apex method annotated `@InvocableMethod` that runs as an action); **Apex action** (the Action element in Flow Builder that calls it); **invocable variable** (a field of a request or response class annotated `@InvocableVariable`); **flow interview** (one running instance of a flow); **bulkification** (grouping many interviews' work into one operation).

## Key facts

| Fact | Detail | Source |
|---|---|---|
| Method modifiers | static, and public or global; outer class only | [InvocableMethod Annotation](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableMethod.htm) |
| Per class | Only one `@InvocableMethod` | [InvocableMethod Annotation](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableMethod.htm) |
| Other annotations | Only `@Deprecated` can accompany `@InvocableMethod` | [InvocableMethod Annotation](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableMethod.htm) |
| Parameters | At most one, and it is a list or a list of lists | [InvocableMethod Annotation](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableMethod.htm) |
| Outputs | Same size and order as the inputs | [InvocableMethod Annotation](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableMethod.htm) |
| Running user | Needs access to the Apex class via profile or permission set | [InvocableMethod Annotation](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableMethod.htm) |
| Invocable variables | public or global members; `required` defaults to false; name matches the flow, case-sensitive | [InvocableVariable Annotation](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableVariable.htm) |
| Process.Plugin | Legacy; no bulk operations; `@InvocableMethod` recommended | [Let Flows Execute Apex Actions](https://help.salesforce.com/s/articleView?id=platform.flow_build_extend_apex.htm&type=5) |
| Limit hit by one interview | All interviews in the transaction fail and roll back | [Flow Bulkification](https://help.salesforce.com/s/articleView?id=platform.flow_concepts_bulkification.htm&type=5) |
| `Interview.start()` limits | Shared with the other operations in the transaction | [How Flows Run in Transactions](https://help.salesforce.com/s/articleView?id=platform.flow_concepts_transaction.htm&type=5) |

## Check yourself

- Why must an invocable method return its results in the same order as its inputs?
- When do you need `@InvocableVariable`?
- What happens to the other interviews when one interview in a bulk flow transaction hits a governor limit?
- Why does a subscriber org's Flow Builder not show a public invocable method from a managed package?

## Sources

- [InvocableMethod Annotation](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableMethod.htm)
- [InvocableVariable Annotation](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableVariable.htm)
- [Let Flows Execute Apex Actions](https://help.salesforce.com/s/articleView?id=platform.flow_build_extend_apex.htm&type=5)
- [Flow Bulkification in Transactions](https://help.salesforce.com/s/articleView?id=platform.flow_concepts_bulkification.htm&type=5)
- [How Flows Run in Transactions](https://help.salesforce.com/s/articleView?id=platform.flow_concepts_transaction.htm&type=5)
- [Flow Namespace](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_namespace_Flow.htm)
- [Before-Save Record-Triggered Flows](https://help.salesforce.com/s/articleView?id=platform.flow_concepts_trigger_record.htm&type=5)
- [Improve Business Processes with Salesforce Automation](https://trailhead.salesforce.com/content/learn/modules/flow-basics/go-with-the-flow-th)
- [Trigger and Bulk Request Best Practices](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_bestpract.htm)
- [Triggers and Order of Execution](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm)

## About the full unit

The "Core concepts", "Exam traps" and "Worked scenario" sections of this unit, its 7 linked practice questions, and unlimited timed mock exams are included with the Platform Developer pack (USD $19): https://www.certifyforce.com/practice-exams
