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.

Most Folio invocable inputs require Text Collection variables. Inputs like shareWithIds, tagNames, recordIds, and byParentRecordIds are typed as Text Collections and only accept a Flow Text Collection variable. They will not accept simple Text variables, Constants, formulas, or any other variable type. Declare a Text Collection variable, add one or many values to 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 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 Transform element to map the record IDs into a Text Collection — 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 folio__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.

Create a Close Plan on Stage change

When an Opportunity moves to a late-stage like Legal Negotiation, sales reps benefit from a structured Close Plan tied to the deal. This pattern instantiates a Close Plan Template the moment the Opportunity hits that stage, sets the Opportunity owner as the Document owner, and emails them a deep link to start filling it in.

  • Trigger:
    Record-triggered flow on Opportunity (StageName becomes “Legal Negotiation”).

  • Step 1 — Instantiate the Close Plan Template.
    Call Create Document from Template with templateId = {Close Plan Template}, sourceRecordIds = {Opportunity Id} (Text Collection of one), and newOwnerId = {Opportunity.OwnerId}. The Close Plan Template should have a Close Plan Tag configured on it so the new Document inherits the Tag automatically. With the right Admin Panel settings, the rest of the linking and sharing happens for you with no extra Flow steps:

    • The new Document is default-linked to the Opportunity (the Source Record).
    • If Auto-link from Opportunity to Account is enabled, the package also links the new Document to the Opportunity’s parent Account.
    • If Auto-Share Level with Record Owner on the Account Linkable Object is set to Read or Edit, the Account Owner is automatically granted that level of access on the new Document as well.

    Net effect: the Document is created from the Template, linked to both the Opportunity and the Account, and shared with both the Opportunity Owner and the Account Owner — all automatically.

  • Step 2 — Email the Opportunity owner.
    Send an email to the Opportunity owner prompting them to complete their Close Plan by the target close date. Include the new Document’s Document Deep Link field in the email body so they can click to easily access the Document in Folio Home without hunting for it.

  • Business outcome:
    Every late-stage Opportunity has a structured Close Plan ready for the rep the moment they need it, pre-tagged for downstream filtering and reporting in Folio Home.

Share Case Documents on escalation

  • 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.

Share Documents with users in a custom user lookup field

It’s common practice to track role-specific ownership on a record using a custom user lookup that’s distinct from the standard Owner — for example a Customer Success Manager, Solution Consultant, Implementation Manager, or Renewal Manager on an Account, Opportunity, or Case. Because these users aren’t the record Owner, Folio’s built-in auto-share rules and Account Team sharing don’t always cover them. To grant read or edit access to the user sitting in any custom user-lookup field, use the pattern below.

  • Trigger:
    Record-triggered after-save flow on folio__Junction__c (the object that links a Document to a record), firing on Created events.
  • Step 1 — Filter to the right parent object.
    Add a Decision element that checks whether the new Junction’s parent record ID begins with the Salesforce key prefix for the object you care about (e.g. 001 for Account, 006 for Opportunity, 500 for Case). If not, exit the flow.
  • Step 2 — Look up the parent and the custom user-lookup field.
    Use a Salesforce Get Records on the parent object, filtered by the Junction’s parent record ID, retrieving the custom user-lookup field(s) you want to share with — Customer Success Manager, Solution Consultant, Implementation Manager, Renewal Manager, or any other role-specific user lookup.
  • Step 3 — Share the Document.
    Build a Text Collection containing the user IDs from those lookup fields, then call Share Document with documentIds = {The Junction's Document Id}, shareWithIds = {User Id Collection}, and accessLevel = "Edit" (or "Read" depending on your access policy).
  • Business outcome:
    Every Document attached to the parent record is shared with the role-specific users the moment it’s linked, without manual sharing or relying on Account Team membership. The same pattern works for any custom user-lookup field on any Linkable Object.

Tag Account Documents by industry

  • 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.
  • 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.
  • Optional — remove the link to the prior Account at the same time.
    Linking the Documents to the new Account does not remove the existing link to the prior Account, so by default the Documents stay linked to both. If you want the move to also drop the old link, follow the link step with a Salesforce Get Records on folio__Junction__c filtered by Document = {Documents linked to Opportunity} AND Linked Record = {Prior AccountId}, then Delete Records on the returned Junctions. Every other relationship on those Documents (Opportunity, Tags, other linked records) is left untouched.
  • Business outcome:
    Existing Opportunity Documents now appear in the Folio Document Editor component on the new Account’s record page — and, if you opt into the cleanup step, no longer appear on the previous Account’s record page.

Reassign Documents when a rep leaves

  • 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.

Create a Sales-to-CS Handoff on close

  • 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.

Re-share Documents on custom-object owner change

  • 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.
  • Prerequisite:
    Apply New Owner Sharing only does anything when the target object is configured as a Linkable Object and its Auto-Share Level with Record Owner is set to Read or Edit. If auto-share with the record owner is disabled for that object, the action is a no-op.
  • Business outcome:
    Documents linked to the project are auto-shared to the new project owner per admin auto-share configuration.

Related: Automate with Invocable Apex · Handle Invocable Apex Errors · Manage Templates · Set up Real-Time Updates

Continue reading
Handle Invocable Apex Errors