Enrichments
An enrichment adds data no field, related list, metric, or formula can produce. It runs a source — your code, an existing action, a flow — and renders the result as values (labeled scalars — “Open Pipeline Coverage: 2.4x”) or records (a table in the target object’s curated list columns).
Choose a source type
Studio → Enrichments → New Enrichment opens a chooser:
| Source | What it mounts | Status |
|---|---|---|
| Apex Provider | A class implementing EntityEnrichmentProvider | Available |
| Invocable Action | Any existing @InvocableMethod, unchanged | Available |
| Flow | Any active autolaunched flow, unchanged | Available |
| Data 360 | Declarative queries over Data 360 objects | Planned |
| External Objects | OData-backed __x objects | Planned |
The source type is fixed after the first save; to change it, create a new enrichment.
NOTE
Until the declarative Data 360 source ships, an Apex class that queries DMOs registers as an ordinary Apex Provider. DMO reads aren’t governed by CRM sharing. → Security
Apex Provider
The Provider class field lists every class in the org implementing the interface; enter a class from another namespace manually as ns.ClassName. Show example provider class on the Definition tab expands the full contract with a working sample.
Save verifies the class exists, constructs with no arguments, and implements the interface — a typo fails the save, not the first render.
→ Provider SPI reference · Worked example
Invocable Action
Mounts any existing @InvocableMethod unchanged — org-local, ISV, or managed. Pick the action and wire it:
| Setting | What it does |
|---|---|
| Input parameter that receives the record Id | Which parameter gets the record being assembled |
| Outputs to include | Which declared outputs render |
| Records target object | Only used when a selected record-collection output comes back empty |
Managed classes hide their bodies, so cross-namespace actions fall back to free-text wiring. With nothing checked, only result (or the sole output) renders — invocable DTOs often carry plumbing like success and errorMessage that shouldn’t reach agent context.
Flow
Mounts any active autolaunched flow, unchanged; requirements are checked at save. Variable shapes are read from platform metadata, so managed flows wire cleanly. With nothing checked, all outputs render — a flow’s outputs are already curated by its author — and platform plumbing is always filtered out.
What renders
An SObject or list renders as a records table; a multi-line string renders as a block; anything else as a value. A single output takes the element’s label; multiple outputs are labeled from their variable names — total_pipeline becomes “Total Pipeline”.
Return markdown and it stays markdown. An output whose value spans lines is prose, not a property, so it is rendered as its own block under the label rather than squeezed into a labeled bullet — where its second line would break the list open and its headings would not be headings. Write the markdown you want the agent to read; the label is added for you, so the output itself needs no heading.
Records outputs are re-queried. The engine keeps only the returned IDs, re-queries them as the calling user, and renders the target object’s curated list columns; returned field values are discarded. → Security So:
- Select
Id, not display fields. - Return per-row computed values as separate value outputs.
- Rows must be real, persisted records; anything without an ID is dropped.
- Row order is preserved; rows cap at 25 with a truncation flag.
- To change the columns, edit the target object’s entity.
Values are included as returned — the source author owns what they expose.
Set the minimum level
Enrichments default to detailed — sources cost a query per record, so they run only on the full 360. Lower it only for a source you know is cheap.
Preview and add to an entity
Preview on the Enrichments table runs an element against a real or sampled record and shows what it renders, or the structured reason nothing did.
Add it to an entity from the element’s Where Used tab or + Add Enrichment on the canvas. An empty dropdown means everything applicable is added or nothing applies — check Available For.
Error handling
A source that throws never breaks the payload — the engine drops that element’s items and records an element_failure on Issues. Don’t swallow exceptions in your provider; a loud failure with a clear message beats a silently empty section.