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.

flowchart TB A["Get Documents
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.

flowchart TB A["Get Documents
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.

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.

flowchart TB A["Get Documents
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.

flowchart TB A["Get Documents
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.

flowchart TB A["Get 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 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.

flowchart TB A["Clone Document"] -->|newDocumentIds| Z["Any modify-action
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.

flowchart TB A["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 documentIds from 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. shareWithIds accepts 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 documentIds slot.

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} and byTags = ["Account Plan"]. Use a follow-up Get Records on folio__Document__c ordered by CreatedDate DESC and 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 = true and cloneRelationships = true so the new clone inherits the Account Plan Tag and the existing Account record link, and cloneSharing = false so 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 its Title__c so it’s clearly archived. Optionally apply a Historical Tag 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 (StageName change 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 (IsEscalated becomes true).
  • 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 (Industry field 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.
  • Trigger: Record-triggered flow on Opportunity (AccountId change).
  • 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 (StageName becomes “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) where OwnerId changes.
  • 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

Continue reading
Handle Invocable Apex Errors