Building Flow Actions (Invocable Actions) – Home Page
Creating an Invocable Action in Apex
To create an invocable action, first build an apex class that carries out a useful piece of work. It’s a recommended practice to orient this class around a single, focused activity that can be expressed as a verb-object phrase, such as Post to Chatter or Send SMS via Twilio.
There are two key mechanisms that turn an ordinary apex class into an invocable action:
1) Adding an InvocableMethod interface to one of the methods
The InvocableMethod interface signals to Salesforce that this class should be exposed to consumers of invocable actions like the Flow Builder. You will place it on a single method in your apex class. InvocableMethod is discussed here.
2) Defining and marking the variables that will be exposed as input and output variables
You expose a variable as a public input or output on your action by marking it with the InvocableVariable interface, described here.

Recommended Practices
1) Choose names for your Apex Class with clarity in mind
When your invocable action shows up in Flow and other action consumers, it will display the name of your class. Pick a class that follows the Verb-Noun Phrase pattern described above
2) Put your input and output properties in Request and Response inner classes
The invocable action interface is designed to support bulk operations, and part of this manifests itself in the fact that the input type of an invocable action is always a List of some type. If you have more than one input variable the way I like to handle it is to define a separate apex class that contains the definitions of all of the input variables. You then can pass back a List of this class. There’s a good example of this on the InvocableVariable doc page. Here’s another example:
a) here, we create a ‘Request’ class to hold all of the inputs to our action:

Here’s where the invocable method defines its readiness to receive a List of these sets of inputs:
global class ConvertLeadAction { @InvocableMethod(label=’Convert Leads’) global static List convertLeads(List requests) { . . . }
Similarly, you can see how the above method signature defines the expected results as a List of a class called ConvertLeadActionResult class. We define this ‘Result’ class to hold all of the expected outputs:

In this example, when the action is called, the list of request sets is passed to the ConvertLeadAction method. For each request set, a corresponding results set is initialized and then populated with the results of the action’s processing:

Adding a Custom Property Editor
You can add a custom property editor to your action and vastly increase its ease of configuration. Learn more.

Directory of Resources
Video: Apex Hours Deep Dive
Video: Power of Invocable Methods in Flows
Video: Execute Apex from Flow Actions
Video: Create a Custom Flow Action (Official Salesforce)
Video: How to Invoke Apex from Flows Using InvocableMethod Annotation (Official Salesforce)
Invocable Action Deep Dive with James Simone
Developing “Local” Flow Actions in Javascript
Calling Omniscripts from Flow with Invocable Actions
Video Demo: Building a Flow Action in Apex