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:

SourceWhat it mountsStatus
Apex ProviderA class implementing EntityEnrichmentProviderAvailable
Invocable ActionAny existing @InvocableMethod, unchangedAvailable
FlowAny active autolaunched flow, unchangedAvailable
Data 360Declarative queries over Data 360 objectsPlanned
External ObjectsOData-backed __x objectsPlanned

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:

SettingWhat it does
Input parameter that receives the record IdWhich parameter gets the record being assembled
Outputs to includeWhich declared outputs render
Records target objectOnly 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.

What’s next