Intercom Fin + ContextDB
Fin answers from your help center. ContextDB remembers your customer.
Fin is strong at resolving questions from knowledge content. What it does not carry is durable, per-customer memory with trust attached: the plan change they confirmed last month versus the discount they only asked about. Wire Fin's actions to a backend that checks evidence before it mutates anything.
recall_for_action, and write durable customer facts back with
remember when conversations close.
The gated action
Check the customer's confirmed credit before paying it.
A customer writes "you said I'd get a credit." Maybe someone did, in which case there is a confirmed memory with evidence. Maybe nobody did, in which case the gate returns nothing and Fin asks or escalates instead of paying out. Either way, the outcome lands in the decision log with the evidence attached.
# backend endpoint behind a Fin custom action from contextdb_cloud_client import CloudClient @app.post("/fin/actions/issue-credit") async def issue_credit(req: Request): body = await req.json() customer = body["customer_id"] async with CloudClient(BASE_URL, api_key=KEY) as cdb: evidence = await cdb.recall_for_action( customer, f"credit of {body['amount_label']} promised" ) if not evidence: # no trusted promise on file → Fin asks or escalates return {"outcome": "not_authorized", "say": "I can't find a confirmed credit on this " "account. Let me connect you with the team."} credit = await billing.issue_credit(customer, body["amount_label"]) return {"outcome": "issued", "reference": credit.ref, "evidence": [m.content for m in evidence]}
Writing memory
Save the important customer details when a conversation ends.
When a conversation resolves, store what should outlive it: the commitment an agent made becomes an agent-sourced fact, the customer's stated preference becomes a user-stated one. A support teammate's promise recorded today is tomorrow's evidence for the gate.
@app.post("/fin/on-conversation-closed")
async def on_closed(req: Request):
convo = await req.json()
customer = convo["customer_id"]
async with CloudClient(BASE_URL, api_key=KEY) as cdb:
# a promise made by your team → sourced to the agent
await cdb.remember(
customer,
"one-month service credit approved for the March outage",
source="agent_inferred",
confidence=0.9,
)
# a wish stays a wish until someone confirms it
await cdb.remember(
customer,
"asked whether annual billing gets a discount",
source="user_stated",
confidence=0.4,
)
return {"ok": True}
Action map
Add memory at four points in a Fin conversation.
| Moment | Fin surface | ContextDB call |
|---|---|---|
| Conversation starts | Custom action: fetch context | recall → customer snapshot for Fin |
| Credit, refund, plan change | Custom action: gated mutation | recall_for_action → act, ask, or abstain |
| Customer confirms in-thread | Custom action: confirm | confirm → fact graduates, decision recorded |
| Conversation closes | Your webhook handler | remember with source and confidence |
Questions
Fin-specific questions.
Fin already has conversation history. Why add memory?
History is a transcript; memory is curated fact with trust attached. The question at credit time is not "did someone mention a credit?" but "is there a confirmed, sourced promise this account may act on?" Transcripts answer the first. The gate answers the second.
Does this work alongside human teammates in the inbox?
Yes, and it works best that way: teammates' commitments become sourced memories, and pending facts can be approved by operators in the ContextDB console, so a human yes anywhere closes the loop everywhere.
What identity should I use for the customer?
Your canonical customer ID, the same one across chat, email, and phone. Cross-channel identity is where memory earns its keep in support: the person emailing today is the person who called yesterday.
Help Fin remember the customer across every conversation.
Gate one Fin action behind trusted evidence this week.