Review Invocable Apex Use Cases
Practical patterns for combining Folio invocable actions in Salesforce Flow. Start with the chaining recipes for the variable mappings you’ll use repeatedly, then read the business scenarios for end-to-end examples grouped by action.
If you haven’t read the per-action reference yet, start with Automate with Invocable Apex. For failure handling, see Handle Invocable Apex Errors.
Get-then-Use recipes
Most real flows look up Documents first, then act on them, which is exactly what the Get Documents and Get Document Shares actions were created for. First retrieve what you need, then pass the output into another invocable to perform an action on those records. The patterns below are the chains you’ll use repeatedly. In each one, the documentIds Text Collection from Get Documents maps directly into the next action’s documentIds input.
Heads-up on Flow Constants vs Text Collections. Several Folio invocable inputs (
shareWithIds,tagNames,recordIds,byParentRecordIds, etc.) are typed as Text Collections. Flow Constants are single-value only — you cannot use a Constant directly where a Text Collection is required. Instead, declare a Text Collection variable and add your value(s) into it via an Assignment element, then pass that variable into the action.
Get Documents, then Share them
Look up Documents by filter conditions, then grant a set of users or groups Read or Edit access to all of them in one step.
filter by parent record, owner, Tag, or title"] -->|documentIds| Z["Share Document
+ shareWithIds: Text Collection of User and/or Group IDs
+ accessLevel: Read or Edit"]
Get Documents, then Apply a Tag to them
Look up Documents by filter conditions, then apply one or more Tags to all of them so they can be grouped, searched, and filtered together in Folio Home.
filter by parent record, owner, Tag, or title"] -->|documentIds| Z["Apply Tag to Document
+ tagNames: Text Collection of Tag names"]
Idempotent — safe to rerun if the flow loops or retries.
Get Documents, then Link them to additional records
Look up existing Documents by filter conditions, then attach them to one or more additional Salesforce records so they surface on those records’ pages too.
filter by parent record, owner, Tag, or title"] -->|documentIds| Z["Link Documents to Records
+ recordIds: Text Collection of Salesforce record IDs"]
The target object type must be configured as a Linkable Object in the Admin Panel.
Get Documents, then Transfer their Owner
Look up Documents by filter conditions (typically by current owner), then bulk reassign ownership to a different user, optionally retaining Read or Edit access for the prior owner during the transition.
filter by current owner (or any other filter)"] -->|documentIds| Z["Transfer Document to Owner
+ newOwnerId: User ID of the new owner
+ priorOwnerAccess: Read, Edit, or None"]
Get Documents, then Clone them
Look up Documents by filter conditions, then create copies of all of them — optionally with their relationships preserved and ownership reassigned to a different user — so a team has pre-populated starting points instead of blank Documents.
filter by parent record, owner, Tag, or title"] -->|documentIds → sourceDocumentIds| Z["Clone Document
+ cloneRelationships: true / false
+ newOwnerId: User ID of the clone's owner (optional)"]
If you only want to clone the most recent matching Document, pair this with a Get Records step on folio__Document__c ordered by LastModifiedDate DESC and capped to 1 — Get Documents itself does not provide a sort/limit interface.
Clone Documents, then Share, Tag, or Link the new ones
Clone Document returns newDocumentIds. Use it as the documentIds input on any modify-action — share the new clones with a group, apply Tags, link them to additional records, etc.
Share Document, Apply Tag to Document,
or Link Documents to Records
+ remaining inputs for the chosen action"]
The same pattern works for Create Document from Template — feed its newDocumentIds into any modify-action’s documentIds.
Get Document Shares, then downgrade everyone to Read except the Owner
Look up existing share rows on a set of Documents, filter the result down to rows where the user is not the record owner and the access level is Edit, then update those rows to Read access. Useful for locking down a Document set after a project closes, or for enforcing a periodic access review.
Because Share Document is additive only and never downgrades, the actual downgrade has to be performed via a Salesforce Update Records step on the folio__Document__Share records returned by Get Document Shares.
filter by Document IDs"] -->|documentShareRecords| F["Filter in Flow
UserOrGroupId ≠ OwnerId
AND AccessLevel = Edit"] F -->|matching share rows| Z["Update Records (Salesforce standard action)
Object: folio__Document__Share
Set AccessLevel = Read"]
Common chaining mistakes
- Empty/null collections. Passing an empty
documentIdsfrom an upstream Get is a no-op, but make sure your Decision node checks for emptiness so the flow logs reflect “no Documents matched” rather than silently doing nothing. - Wrong ID type.
shareWithIdsaccepts User IDs and Regular public Group IDs; passing role IDs or queue IDs will fail validation. - Overbroad filters. Leaving every Get Documents filter empty returns empty (by design). Always supply at least one filter.
- Mixing record-collection loops with text-collection inputs. If you have a Record Collection from a Get Records step, use a Loop + Assignment to build a Text Collection of IDs — don’t try to map the record collection directly into a
documentIdsslot.
Business use cases
The recipes below are examples of real business problems and how Folio’s invocable Apex actions can be combined in Flow to solve them. Each example highlights a primary action, but most production flows chain several together — use these as starting points and adapt the inputs and triggers to fit your org’s processes.
Account Plan refresh
Functionally, this flow freezes last year’s Account Plan, spins up a fresh one from a clone of it, and notifies the owner to start updating the new copy — all 90 days before the Account’s renewal.
- Trigger: Scheduled flow that runs daily and identifies any Account whose renewal date is exactly 90 days out.
- Step 1 — Find the most recent Account Plan. Call Get Documents filtered by
byParentRecordIds = {Account Id}andbyTags = ["Account Plan"]. Use a follow-up Get Records onfolio__Document__cordered byCreatedDate DESCand limited to 1 to pick the most recent matching Document. - Step 2 — Clone it into a new Account Plan. Call Clone Document with
sourceDocumentIds = {That Doc Id},cloneTags = trueandcloneRelationships = trueso the new clone inherits theAccount PlanTag and the existing Account record link, andcloneSharing = falseso the new Document starts shared only with the owner by default (plus any Account Team sharing that applies automatically). - Step 3 — Lock down the original. Use the Get Document Shares, then downgrade everyone to Read except the Owner recipe on the original Document so the prior year’s plan can no longer be edited by anyone except the Owner. Note this doesn’t technically prevent the Owner from editing the Document. If the original truly needs to be fully locked, transfer it to a system administrator user via Transfer Document to Owner with
priorOwnerAccess = "Read"so the Account owner retains read access but loses edit access. - Step 4 — Mark the original as historical. Use Salesforce Update Records on the original Document to prepend
Old —(or your preferred convention) to itsTitle__cso it’s clearly archived. Optionally apply aHistoricalTag as per your organization’s preferences using Apply Tag to Document. - Step 5 — Email the owner. Pull the new Document’s Document Deep Link field and email it to the Account owner. The Document Deep Link opens the new Document directly inside Folio Home, so the owner doesn’t have to hunt for it.
Audit external sharing on sensitive Documents (Get Document Shares)
- Trigger: Scheduled flow, weekly.
- Inputs used:
byDocumentIds = {Documents tagged "Confidential"},byUserIds = {External User IDs}. - Action sequence: Get Document Shares → if any rows are returned, post to a Slack/Chatter compliance channel via your messaging integration.
- Business outcome: Security team gets continuous visibility into who has access to confidential docs.
- Why this fits: Inspecting share rows declaratively without writing custom Apex.
Renewal-Opportunity playbook starter (Clone Document)
- Trigger: Record-triggered flow on Opportunity (
StageNamechange to “Renewal Open”). - Inputs used:
sourceDocumentIds = {Latest Account Plan Doc on the parent Account},cloneRelationships = true,newOwnerId = {Renewal Owner}. - Action sequence: Get Documents (latest Account Plan on Account) → Clone Document → Apply Tag (
Renewal Draft) → Link Documents to Records (new Opportunity). - Business outcome: Renewal team starts with the most recent context instead of a blank doc.
- Why this fits: Clone preserves body content and (optionally) relationships and Tags; templates can’t carry forward narrative content the team has already written.
Auto-share Case Documents with the support manager on escalation (Share Document)
- Trigger: Record-triggered flow on Case (
IsEscalatedbecomestrue). - Inputs used:
documentIds = {Documents linked to Case},shareWithIds = {Support Manager Group ID},accessLevel = "Edit". - Action sequence: Get Documents (
byParentRecordIds = {Case Id}) → Share Document. - Business outcome: Escalation managers get immediate access to all Case context without manual sharing.
- Why this fits: Salesforce Account/Case Teams don’t always cover the right groups; this fills the gap.
Apply industry Tags to Account Documents in bulk (Apply Tag to Document)
- Trigger: Record-triggered flow on Account (
Industryfield change). - Inputs used:
documentIds = {Documents linked to Account},tagNames = "{Industry name}". - Action sequence: Get Documents → Apply Tag to Document.
- Business outcome: Documents become filterable in Folio Home by industry without manual tagging.
- Why this fits: Idempotent and creates the Tag if it doesn’t yet exist.
Re-link Documents when an Opportunity moves Accounts (Link Documents to Records)
- Trigger: Record-triggered flow on Opportunity (
AccountIdchange). - Inputs used:
documentIds = {Documents linked to Opportunity},recordIds = {New AccountId}. - Action sequence: Get Documents → Link Documents to Records.
- Business outcome: Existing Opportunity Documents now also appear under the new Account’s related list.
- Why this fits: No way to do this declaratively without invocable Apex; Salesforce reparenting doesn’t propagate to Folio’s polymorphic Junctions.
Reassign Documents when a sales rep leaves (Transfer Document to Owner)
- Trigger: Screen flow run by an Ops admin from the user’s record page.
- Inputs used:
documentIds = {Documents owned by departing user},newOwnerId = {New owner User Id},priorOwnerAccess = "Read". - Action sequence: Get Documents (
byOwnerIds = {departing user}) → Transfer Document to Owner. - Business outcome: Ownership transitions cleanly with a Read window for the original owner during handoff.
- Why this fits: Bulk transfer plus retained-access handling in one step.
Auto-create Sales-to-CS Handoff doc on Opportunity close (Create Document from Template)
- Trigger: Record-triggered flow on Opportunity (
StageNamebecomes “Closed Won”). - Inputs used:
templateId = {Sales-to-CS Handoff Template},sourceRecordIds = {Opportunity Id},newOwnerId = {Assigned CSM Id}. - Action sequence: Create Document from Template → Apply Tag (
Handoff) → Share Document with the CS team Group. - Business outcome: A pre-filled handoff doc is waiting for the CSM the moment the deal closes.
- Why this fits: This is the canonical use of Folio invocable Apex — bridging a Salesforce moment to a structured Document.
Re-share Documents when a custom-object record changes owner (Apply New Owner Sharing)
- Trigger: Record-triggered flow on a custom object (e.g.,
Project__c) whereOwnerIdchanges. - Inputs used: Text Collection containing the changed record’s ID.
- Action sequence: Apply New Owner Sharing.
- Business outcome: Documents linked to the project are auto-shared to the new project owner per admin auto-share configuration.
- Why this fits: Standard CDC-driven auto-sharing only covers Account/Contact/Case/Opportunity; this action extends that behavior to any object via Flow.
Related: Automate with Invocable Apex · Handle Invocable Apex Errors · Manage Templates · Set up Real-Time Updates