Automate with Invocable Apex

Folio exposes a set of Invocable Apex actions that you can call from Salesforce Flow (and any compatible automation framework) without writing code. These actions let admins query, create, clone, share, Tag, link, and transfer Documents based on real-time business events in Salesforce — so document workflows stay in sync with the records and people they describe.

How to use Folio invocable actions in Flow Builder

  1. Open Flow Builder and create or edit a flow.
  2. Add an Action element.
  3. Search for Folio to list all available invocable actions.
  4. Select the action you want, then map the inputs (record IDs, template ID, Tag name, etc.) to your flow variables.
  5. Capture outputs (such as the new Document Id) into flow variables for downstream use.

Folio invocable actions execute in whichever security context the calling flow is configured to run in. By default, that’s the running user of the transaction that triggered the flow — actions then respect the user’s Salesforce object-, record-, and field-level access and will never grant access they don’t already have. If the calling flow is configured to run in system context, Folio invocable actions inherit that system-level access too. Admins are responsible for choosing the flow configuration that matches their org’s security preferences.

Quick reference

ActionPurposeRequired InputsKey Outputs
Get DocumentsQuery Documents by Tag, parent record, owner, or titleAt least one filter inputdocumentIds, documentRecords
Get Document SharesQuery existing share rows for Documents and/or usersAt least one filter inputdocumentShareIds, documentShareRecords
Clone DocumentCreate copies of existing DocumentssourceDocumentIdssuccess, errorMessage, newDocumentIds
Share DocumentGrant Read or Edit access to users/groupsdocumentIds, shareWithIds, accessLevelsuccess, errorMessage
Apply Tag to DocumentAdd Tags (creating them if needed)documentIds, tagNamessuccess, errorMessage
Link Documents to RecordsCreate record-link JunctionsdocumentIds, recordIdssuccess, errorMessage
Transfer Document to OwnerBulk reassign ownershipdocumentIds, newOwnerIdsuccess, errorMessage
Create Document from TemplateInstantiate Documents from a Template, one per source recordtemplateId, sourceRecordIdssuccess, errorMessage, newDocumentIds
Apply New Owner SharingRe-share linked Documents after a record’s owner changesList of changed record IDs(no output payload)

Core concepts and data model

Before composing flows with these actions, it helps to understand the underlying objects and conventions.

  • folio__Document__c — the parent record for a Folio Document. Includes flags like folio__Is_Archived__c and folio__Is_Template__c that the Get actions use to exclude system noise.
  • folio__Junction__c — the polymorphic Junction object that links a Document to a Salesforce record (Account, Opportunity, Case, custom objects, etc.). Created by Link Documents to Records and Create Document from Template.
  • folio__Tag__c — a Folio Tag record. Apply Tag to Document reuses Tags by normalized name and creates new ones when needed.
  • folio__Document__Share — the standard Salesforce share object for folio__Document__c. Read by Get Document Shares, written by Share Document, and managed implicitly by Transfer Document to Owner and Apply New Owner Sharing.

Text Collections vs Record Collections

Most Folio actions accept Text Collections of IDs as inputs — Document IDs, record IDs, user IDs, group IDs. Flow stores Salesforce IDs as text by design, and using text collections lets you pass IDs from any source: a record-collection loop, a Get Records output, another invocable action, or hard-coded constants.

A small number of outputs return Record Collections (for example documentRecords from Get Documents) when you need actual field values rather than just IDs.

Quick rule: if you only need to act on Documents (share/Tag/link/transfer/clone), pass documentIds. If you need to read fields like Name, OwnerId, or folio__Is_Archived__c for downstream decisioning, use documentRecords.

Bulk-safe by design

The Folio invocables are designed to handle one or many records per transaction with bulk safety in mind. They accept whole collections and process them in a single call — keep them outside Flow Loops and pass the entire collection at once.

If you only need to act on a single record, the invocables still work the same way. Assign that single record ID to a Text Collection variable (a collection of one) and pass that into the action. The invocables only accept Text Collections as inputs, but a collection of one is a perfectly valid input.

Additive sharing model

Share Document, Transfer Document to Owner (with a non-None priorOwnerAccess), and Apply New Owner Sharing are all additive. They never downgrade an existing share — if a user already has Edit access, calling Share at Read level will not remove their Edit. This is intentional: invocables won’t silently strip access someone already has.

If you need to remove access, do that explicitly via separate logic; the Folio invocables are not the right tool for revoking Document access.

Get actions exclude archived and template Documents

Both Get Documents and Get Document Shares exclude:

  • Documents where folio__Is_Archived__c = true
  • Documents where folio__Is_Template__c = true

This means automation cannot accidentally pull templates into operational flows, and archived items stay out of the way.

Validation expectations

Folio actions enforce safety checks before performing writes:

  • Active users only — share/transfer targets must be active Salesforce users with the Folio Docs User permission set assigned (see Assign Permissions).
  • Public groups only — group IDs passed to Share Document must be Regular public groups (not queues, role groups, or territory groups).
  • Linkable objects — record IDs passed to Link Documents to Records must be of object types configured as Linkable Objects in the Admin Panel.
  • Template / source compatibilityCreate Document from Template validates that each sourceRecordIds entry’s object type is supported by the chosen template’s Source Object configuration.
  • Sharing/FLS context — Get actions run in the running user’s context; users only see Documents they already have access to.

Invocable actions in detail

Get Documents

Query Documents by one or more filter dimensions. Filters are AND-combined, and empty/null inputs are ignored. If every filter is empty, the action returns an empty result rather than every Document in the org.

Inputs

  • byTags (Text Collection) — Document Tag names to match. Case-insensitive.
  • byParentRecordIds (Text Collection) — IDs of records the Documents are linked to (via folio__Junction__c).
  • byOwnerIds (Text Collection of User IDs) — Document owners to match.
  • byTitle (Text) — Title match using a SOQL LIKE operator: folio__Title__c LIKE '%<entered value>%'. Matches any Document whose title contains the value as a substring (case-insensitive per SOQL LIKE semantics).

Outputs

  • documentIds (Text Collection)
  • documentRecords (Record Collection of folio__Document__c)

Behavior notes

  • Excludes archived and template Documents.
  • Runs in the user’s sharing/FLS context — won’t return Documents the running user can’t already see.
  • Use documentIds for downstream invocable chaining; use documentRecords when you need field values for decisions.

Get Document Shares

Look up existing folio__Document__Share rows by user, by Document, or both.

Inputs

  • byUserIds (Text Collection)
  • byDocumentIds (Text Collection)

Outputs

  • documentShareIds (Text Collection)
  • documentShareRecords (Record Collection of folio__Document__Share)

Behavior notes

  • AND-combined when both filters are supplied; if both are empty, returns empty.
  • Excludes shares pointing at archived or template Documents.

Clone Document

Create independent copies of one or more Documents, with optional carry-over of Tags, sharing, and record links.

Inputs

  • sourceDocumentIds (Text Collection, required)
  • cloneTags (Boolean) — when true, the source Document’s Tag links are cloned onto the new Document. When false, Tags are not carried over. Blank defaults to false.
  • cloneSharing (Boolean) — when true, the source Document’s manual user/group share rows are cloned onto the new Document. When false, sharing is not carried over. Blank defaults to false.
  • cloneRelationships (Boolean) — when true, the source Document’s record-link Junctions are cloned onto the new Document. When false, record links are not carried over. Blank defaults to false.
  • newOwnerId (Text, optional) — User ID that will own the new cloned Documents. If blank, the owner of each source Document is set as the default owner of its new clone.

Outputs

  • success (Boolean)
  • errorMessage (Text)
  • newDocumentIds (ID Collection)

Behavior notes

  • Clones are titled Copy of {original title}.
  • If more than one ID is passed in sourceDocumentIds, each source Document gets its own clone created in the same invocable run.
  • A newOwnerId assignment applies to all clones created in that invocable instance — this action does not support different owners for different clones in a single call.
  • Source IDs and newOwnerId are validated; invalid inputs surface in errorMessage.
  • This action does not instantiate from a template — for that, use Create Document from Template.

Share Document

Grant Read or Edit access to users and/or public groups.

Inputs

  • documentIds (Text Collection, required)
  • shareWithIds (Text Collection, required) — User IDs and/or Public Group IDs.
  • accessLevel (Text, required) — Read or Edit.

Outputs

  • success (Boolean)
  • errorMessage (Text)

Behavior notes

  • Additive — never downgrades existing higher access.
  • Idempotent — re-sharing with an existing Document share row is skipped, so it’s safe to call repeatedly without creating duplicate or noisy share rows.
  • Users must be active and have Folio permission.
  • Groups must be public groups of type Regular (not queue, role, or territory).

Apply Tag to Document

Apply one or more Tags to one or more Documents.

Inputs

  • documentIds (Text Collection, required)
  • tagNames (Text, required) — comma-separated Tag names.

Outputs

  • success (Boolean)
  • errorMessage (Text)

Behavior notes

  • Tags are matched by normalized name; existing Tags are reused.
  • Missing Tags are created on the fly.
  • Idempotent — re-running with the same inputs does not apply duplicate Tags to the Document.

Create Junction links between Documents and any combination of Salesforce records.

Inputs

  • documentIds (Text Collection, required)
  • recordIds (Text Collection, required) — IDs of any object configured as a Linkable Object.

Outputs

  • success (Boolean)
  • errorMessage (Text)

Behavior notes

  • Creates a Junction from every Document in documentIds to every record in recordIds. For example, passing 3 Documents and 2 records produces 6 Junction links (every Document gets linked to every record).
  • Object types are validated; passing a record whose object isn’t on the Linkable Object Allowlist will fail.
  • Idempotent — existing links are de-duped, so reruns won’t create duplicates.

Transfer Document to Owner

Bulk reassign Document ownership to a single new owner, optionally retaining access for prior owners.

Inputs

  • documentIds (Text Collection, required)
  • newOwnerId (Text, required)
  • priorOwnerAccess (Text, optional) — None (default), Read, or Edit.

Outputs

  • success (Boolean)
  • errorMessage (Text)

Behavior notes

  • All input Documents are transferred to the same newOwnerId.
  • When priorOwnerAccess is Read or Edit, the prior owner is added as a manual share at that level.
  • Updates the new owner’s Last Viewed tracker so the Documents surface naturally for them in Folio Home.

Create Document from Template

Instantiate one new Document per source record from a chosen template.

Inputs

  • templateId (Text, required)
  • sourceRecordIds (Text Collection, required)
  • newOwnerId (Text, optional)

Outputs

  • success (Boolean)
  • errorMessage (Text)
  • newDocumentIds (ID Collection)

Behavior notes

  • Resolves merge placeholders (Record Links, Live Fields, Related Lists) against each source record at instantiation. See Manage Templates for the full merge-syntax walkthrough.
  • Validates that each source record’s object type matches the template’s configured Source Object.
  • Optionally assign the new Document to a specific newOwnerId. Defaults to the Owner of the Source Record. Each Document created in an invocable run assigns to the same newOwnerId if entered.
  • Updates the new owner’s Last Viewed tracker so the Documents surface naturally for them in Folio Home.

Apply New Owner Sharing

Re-applies Folio’s owner-share rules after a record’s owner has changed, for objects that aren’t covered by the package’s out-of-the-box automation.

Out of the box, Folio uses Change Data Capture to automatically share linked Documents with the new owner whenever an Account, Contact, Opportunity, or Case changes owner. The level of access granted comes from the Auto-Share Level with Record Owner setting configured on each Selected Object under the Linkable Objects section of the Admin Panel. See Set up Real-Time Updates for the full out-of-the-box behavior.

This invocable fills the gap for every other object. If you want the same owner-share behavior on a custom object (or any non-default standard object), call this action from a flow whenever that object’s OwnerId changes — and Folio will share all Documents linked to the input record with the new owner at the access level configured on that object’s Selected Object entry.

Input

  • A Text Collection of changed record IDs (records whose OwnerId changed).

Output

  • No explicit output payload.

Behavior notes

  • For each input record ID, Folio looks up Documents linked to that record and shares them with the record’s new owner at the Auto-Share Level with Record Owner configured on that object’s Selected Object entry.
  • The input object must be configured as a Linkable Object with an Auto-Share Level with Record Owner value set, otherwise the action has nothing to apply.
  • Additive — does not strip access from prior owners.

Example: custom object Custom__c

You have a custom object Custom__c that’s already configured as a Linkable Object in Folio with an Auto-Share Level with Record Owner of Edit. You want owner changes on Custom__c records to propagate share access to every linked Document automatically.

  1. Build an after-save record-triggered flow on Custom__c that fires only when OwnerId is changed.
  2. Assign the changed record’s Id into a Text Collection of one.
  3. Call Apply New Owner Sharing with that Text Collection.

Result: every Document linked to that Custom__c record is shared with the new owner at Edit, matching the behavior the package ships with for Account/Contact/Opportunity/Case.

Where to go next

Best practices and guardrails

  • Capture the new Document Id from Create Document from Template or Clone Document so you can chain follow-up actions (apply a Tag, share with a group, link to additional records) in the same flow.
  • Combine actions. A single flow can create from a template → apply a Tag → share with a group → link to a related record, all in one run — that’s the point of the framework.
  • Test in a sandbox first. Invocable actions run as the user that triggers the flow; sandbox testing avoids surprising production users with auto-created Documents.
  • Always supply at least one filter to Get Documents. Returning the entire org is intentionally not allowed — protect your bulkification quotas by being specific.
  • Prefer Apply New Owner Sharing for owner-change cases on custom objects. The standard CDC-wired auto-share path covers Account/Contact/Case/Opportunity out of the box as long as you turn on Change Data Capture on those objects (see Set up Real-Time Updates); use this invocable to extend the same pattern to any other object.
  • Tag automatically created Documents (e.g., Auto-created, Renewal Draft, Handoff) so users can filter and audit them in Folio Home.
  • Set a clear ownership policy before turning on auto-creation — decide who should own auto-created Documents and pass newOwnerId accordingly to avoid orphaned content.

FAQ

Do these actions run in the running user’s context, or as a system user? Whichever context the calling flow is configured for. By default, flows run as the running user, and Folio invocables respect that user’s Salesforce sharing, FLS, and Folio permissions. If the flow is set to system context (with or without sharing), Folio invocables inherit that elevated access. Choose the flow configuration that matches your org’s security model.

What happens if I pass an empty Text Collection? The action treats it as “no filter” (for Get actions) or as “nothing to do” (for write actions). It is not an error, but downstream Decision nodes should branch on emptiness so the flow logs are explicit.

Can I share with a Salesforce Queue or Role? No — Share Document only accepts User IDs and Public Group IDs. When you need to share a Document with a pool of Users, use a Public Group.

Will Share Document overwrite an existing Edit share with Read? No — sharing is additive and never downgrades. To remove or downgrade access, use a separate revocation path: call Get Document Shares to retrieve the relevant folio__Document__Share records, then loop over them and update each record’s AccessLevel field to the desired value (or delete the share row to revoke access entirely).

How do I share with a Salesforce Account/Opportunity/Case Team? Use the Automatic Document Sharing section on the Folio Admin page to automatically share Documents with the Team Members of linked Accounts, Opportunities, and Cases. For any other sharing automation needs, use the Share Document invocable action.

Can Get Documents return archived Documents? No — both Get actions exclude archived and template Documents by design. To work with archived Documents, use a Get Records element directly on folio__Document__c filtered by folio__Is_Archived__c = true (subject to user access).

Why do most inputs use Text Collections of IDs instead of Record Collections? IDs are stored as text in Flow, and Text Collections accept IDs from any source — Get actions, Get Records loops, manually-entered constants. Record Collections are returned where you need field values for downstream decisions.

Does Apply New Owner Sharing remove the prior owner’s access? No — it is additive. If you need to remove the prior owner, do that explicitly via separate logic.

Are Folio invocables bulkified? Yes — they’re designed to accept collections and process them in bulk. Keep them outside Flow Loops and pass the whole collection in one call. For single-record use, wrap the one record ID in a Text Collection of one and pass that — the inputs only accept Text Collections, but a collection of one is fine.

Where do I find the in-org help text and parameter labels? Inside Flow Builder, after adding the action element, expand the input/output panels to see the latest authoritative description for each parameter as it ships.

Related: Review Invocable Apex Use Cases · Handle Invocable Apex Errors · Manage Templates · Configure the Admin Panel · Set up Real-Time Updates

Continue reading
Review Invocable Apex Use Cases