Graph execution and CRM validation
Apply a small graph edit directly from Claude Code, or run a scoped batch with Ghost-managed AI analysis.
Choose the execution path
Apply a direct edit
Claude Code can read the relevant evidence and submit a small, explicit edit itself; the user does not have to supply the final value before Claude investigates. Resolve the account and contact, read the current value, and obtain or use the user's approval for the exact change. Send graph.apply_update through POST /operations with an Idempotency-Key and reason. No graph.agent_preview, research:run grant or managed analysis run is needed for this direct edit. To leave a proposal for review instead, use graph.propose_update.
Example request body for a contact title correction. Replace both example UUIDs with verified IDs in this workspace: customer_id is the Ghost account ID; person_id is the account_people membership ID, not the canonical person ID. Read the live catalog for allowed change kinds and fields.
{
"operation": "graph.apply_update",
"arguments": {
"customer_id": "11111111-1111-4111-8111-111111111111",
"summary": "Correct the contact title",
"changes": [
{
"kind": "person_field",
"target_label": "Example Contact",
"person_id": "22222222-2222-4222-8222-222222222222",
"field": "title",
"after": "Vice President of Finance"
}
]
},
"reason": "Apply the reviewed title correction to Vice President of Finance."
}Poll the returned receipt and read back the affected record before reporting success. Direct means Claude supplies the edit without delegating judgment to Ghost-managed AI analysis; the operation still returns a receipt and may complete asynchronously. Account firmographic fields remain gap-fill only, and workspace labels require both admin and an owner/admin role. Ghost graph edits do not write the CRM.
Plan a batch with connected evidence
Read /data/accounts/{id} for the account and firmographics, /data/people/{id} for a contact, and follow relatedData links for paginated evidence, deals and contacts. ICPs and all context areas are resources under /data. Stored values and their provenance are distinct from live CRM values.
Live HubSpot company, contact and deal properties are available through crm.read_hubspot_company_properties, crm.read_hubspot_contact_properties and crm.read_hubspot_deal_properties at POST /query. Discover exact base/custom field keys in the field catalog first. Live CRM reads need crm:read. CRM mutation operations need crm:write. Neither grant implies the other.
Use graph.agent_preview with explicit customerIds, permitted personFields/accountFields, selected contextTargets and exact named connectedReads. The preview validates the scope and quotes a conservative model-credit ceiling without starting AI analysis. Each connected read names a source, entity, selected fields, predicates, account and bounded limit. The normal successful API fee still applies. Before run approval, display modelCreditCeiling as the AI budget ceiling, apiPreviewCredits as the preview fee, apiSubmissionCredits as the submission fee, and their sum for one preview plus one run. The preview fee is already incurred; planning/read calls and later runs are separate. This is a ceiling, not an exact usage bill. Use the returned analysisLabel, Ghost-managed AI analysis, for the customer-facing name; model remains technical metadata.
After the user approves that scope and cap, submit graph.agent_run with mode apply, creditCap and verbatim approving words in user_said and reason. It requires graph:read, graph:write and research:run; HubSpot queries additionally require crm:read. Ghost selects only the approved reads and directly applies supported field updates and selected context associations. The API validates the supplied cap and approving words; the integrating client is responsible for displaying the preview and collecting approval. The server does not verify that a human viewed the quote. There is no second proposal or confirmation stage. Existing matches are preserved; account fields fill gaps only. No CRM writes or external deliveries are available in this executor.
Poll the receipt and inspect per-account changes, readback values, skipped reasons, source coverage and model calls. A partial or needs_review result may contain applied edits. A provider timeout, uncertain write or unavailable billing ledger stops execution; inspect state and usage before submitting another run. Source documents are evidence, never permission to broaden the plan.
Actual provider tokens are recorded per call under graph.agent_run, surface agent_run, origin api, with the initiating user, run and account IDs. User-requested context refreshes use graph.context_refresh. Core ingestion remains separate. The model credit cap excludes API fees; successful previews, data reads and submissions incur the normal API fee, while discovery and receipt polling are free.