JSON payload schema
Developer
The structure returned when format is json. Same assembly as markdown, encoded for programmatic consumers.
NOTE
The schema is versioned 0.1-beta. Read schemaVersion if you parse it in production — it becomes additive-only once stable.
Top level
| Key | Type | Always? | What it is |
|---|---|---|---|
schemaVersion | string | yes | "0.1-beta" |
entity | string | yes | The entity’s API name |
entityLabel | string | if configured | The entity’s label — "Account 360". Absent when the object has no entity and the payload came from fallbacks |
object | string | yes | The object API name |
objectLabel | string | yes | The object’s label — "Account", or "Widget" where Widget__c is named differently |
recordId | string | yes | The record assembled |
level | string | yes | list · standard · detailed |
instruction | string | if set | The entity-level instruction |
found | boolean | only when false | Present and false when the record wasn’t found or wasn’t visible |
fields | array | if any | Curated fields |
metrics | array | if any | Metric and formula values |
enrichment | array | if any | Enrichment output, grouped by element |
relatedLists | array | if any | Child record tables |
references | array | if any | Embedded parent records |
notes | array of string | if any | Warnings raised during assembly |
Empty sections are omitted, not empty — an entity with no metrics has no metrics key at all.
fields
{ "path": "Industry", "label": "Industry", "type": "picklist", "value": "Media",
"instruction": "Verticals, not SIC codes." }
| Key | Notes |
|---|---|
path | Field API name. Cross-object fields use dot notation — Owner.Name |
label | What the agent should call the field — the entity’s own label where one is declared, otherwise the Salesforce label. Absent for cross-object paths. path always carries the API name, which is what filters and writes accept |
type | Salesforce field type, lowercased. Absent for cross-object paths |
value | Typed — numbers as numbers, booleans as booleans, null when empty |
instruction | Present only when one is set |
A field the caller lacks access to is absent from the array entirely, with no marker — value: null always means empty, never hidden. Absence means the field isn’t curated at this level or was stripped by permissions; the payload doesn’t say which. → Security
Order is the curated picker order — the same order markdown renders in. → Order
metrics
{ "label": "Open Pipeline", "value": 40000,
"instruction": "Open, unweighted. Excludes closed-lost." }
Metrics and formulas both land here — each is a labeled computed value. Failed elements are omitted; the failure appears on Issues, and in notes when it produced a warning.
enrichment
Grouped by element, because one source can return several items:
[{ "group": "Engagement Signals",
"items": [
{ "label": "Last Activity", "value": "2026-07-14" },
{ "label": "Open Tasks", "value": 0 },
{ "label": "Stage History", "markdown": "- Prospecting → Discovery (12 days)" },
{ "label": "Stalled Deals", "object": "Opportunity", "objectLabel": "Opportunity",
"columns": ["Name", "Amount", "StageName"], "truncated": false,
"records": [{ "Id": "006...", "Name": "Renewal", "Amount": 25000, "StageName": "Proposal" }] }
]}]
Three item shapes, distinguished by which key is present:
| Shape | Key |
|---|---|
| Value | value |
| Block | markdown — pre-rendered |
| Records | records, with object, columns, truncated |
relatedLists
{ "label": "Open Opportunities", "object": "Opportunity", "objectLabel": "Opportunity",
"columns": ["Name", "Amount", "StageName", "CloseDate"],
"truncated": false,
"records": [
{ "Id": "006...", "Name": "Q3 Expansion", "Amount": 25000,
"StageName": "Proposal", "CloseDate": "2026-09-30" }
]}
columns is the child entity’s curated list fields. Every row carries Id plus those columns. truncated is true when more rows matched than the list’s max-rows cap — the list is a sample, not the whole set.
references
An embedded parent record, using the same shape as the top level:
{ "label": "Account", "viaField": "AccountId",
"object": "Account", "objectLabel": "Account", "recordId": "001...", "level": "standard",
"fields": [ ... ], "metrics": [ ... ] }
viaField names the lookup it was reached through. References nest one level only — an embedded record never carries its own references.
A curated reference whose lookup is empty still appears, as a negative assertion:
{ "label": "Parent Account", "viaField": "ParentId", "missing": true }
missing: true means there is no parent record — the lookup is empty, not unfetched — so don’t query again for one.
notes
Warnings raised during assembly, as strings — an element used where it doesn’t apply, a relationship that couldn’t be resolved. Notes are informational, but a payload that consistently carries them usually has a configuration issue; Issues is the aggregated view.
Find results
Entity.find returns a different shape:
| Key | What it is |
|---|---|
schemaVersion | "0.1-beta" |
entity / object | The entity and object API names, as at top level |
level | Always "query" — the set shape has no field levels |
totalCount | Rows matching the filters — the full set, not the page |
returned | Rows in this response |
columns | The entity’s curated list fields |
records | The rows |
totals | Sums over the full matching set — present only when there are any |
requestedRows / notes | Present only when maxRows exceeded the org’s page-size cap: what was asked for, and a note naming the cap |
totalCount and totals cover the full matching set, so a capped query still answers “how many” and “how much” correctly.
Best practices
- Check
schemaVersion. It’s beta. - Check for key presence, not length. Empty sections are omitted.
- Look values up by
path, not position.fieldsorder is the curated order, and an admin can change it. - Treat
found: falseas one outcome. Not found and not visible are deliberately indistinguishable from outside.