Heavy template — auto-mapped from HubSpot. You can edit this expression directly, or switch to medium mode for a guided builder.
Event source
Filter expression
Test data
Last run: 14 deals matched · 12 contacts not previously called · 2 inside 30d window (excluded)
Audit log
● 2026-05-07 14:32 · created by James
● 2026-05-07 16:21 · amount threshold £3k → £5k by Sarah Lin
● — no other changes —
Each row maps a field in your CRM to a variable the agent sees in its pre-call brief.
From your CRMUsed in the brief as
Contact's full name
HubSpot · firstname + lastname
→
Contact name
{{contact.name}}
edit · remove
Job title
HubSpot · jobtitle
→
Role
{{contact.role}}
edit · remove
Company name
HubSpot · company.name
→
Account
{{account.name}}
edit · remove
Deal close date
HubSpot · deal.closedate
→
Signup date
{{account.signup_date}}
edit · remove
Account manager's email
HubSpot · deal owner
→
AM email
{{account.am_email}}
edit · remove
Last CSAT call summary
celliq history · last outcome
→
Last call summary
{{contact.last_call_summary}}
edit · remove
Auto-built from your Conversation. Two channels: one for every call (the team summary), one for escalations only. Each post auto-renders from the captured items — toggle anything off you don't want surfaced.
Where Slack posts go
Default channel
Escalation channel
Escalate when
Conditions reference fields from your Conversation.
What gets posted
Include
Each captured item becomes a line in the Slack post. Same toggles for default and escalation channels.
Default channel preview
channel#cs-team
posted bycelliq · 14:32
📊 CSAT call · acme.co
Sarah Lin · Head of Customer Success
Score: 9 / 10 ⭐
What's working:
- Fast support
- Easy onboarding
Renewal intent: positive · plans to expand seats
"Strong CSAT call. Onboarding praised; support team called out as fast. Customer wants to expand seats next quarter."
Escalation preview
channel#cs-escalations
posted bycelliq · 14:28
🚨 Escalation · globex.io
Tom O. · Operations Lead
Score: 3 / 10
What needs attention:
- Two open tickets unresolved for 3 weeks
- Support response time
"Multiple unresolved tickets. Renewal at risk if response time doesn't change."
Not configured. CSAT calls don't typically need calendar updates — but you can attach a calendar event after a low-score escalation so the AM has a follow-up booked. Optional.
Trigger
Event type
Attendees
HubSpot · acme.co
workspace 8421 · token refreshed 14m ago · scopes: contacts, deals, companies, timeline
30
contacts written today
230ms
typical write speed
Activity (timeline note)
auto-built from your Conversation
Every call leaves a timeline note on the contact + deal record so AMs see the result inside HubSpot. The note's content auto-renders from your Conversation — toggle which captured items appear in the body, no template syntax to maintain.
Create activity
Include
Each captured item becomes a section in the activity note.
Preview
onacme.co · contact: Sarah Lin · deal #5491
typeNote (timeline activity)
celliq · CSAT call · 9/10
"Strong CSAT call. Onboarding praised; support team called out as fast. Customer wants to expand seats next quarter."
Recorded by celliq integration user · linked to contact #1234 · Wed 7 May 14:32
Activity type
Linked to
contact + deal · auto-resolved from the call's pre-call brief
Recorded by
Property mappings
3 mapped · all idempotent
1
CSAT score outcome.score→ HubSpot contact's CSAT score field
number 1–10
writes on every call
safe to retry
From the call outcome
→
HubSpot contact · CSAT score
transform
none — written as-is (1 to 10)
idempotency
if the contact already has the same score from this call, the write is skipped (won't double-write)
If something fails
retry with backoff for up to 24 hours · then drops into your Inbox
edit →
2
At-risk flag outcome.escalation_required→ HubSpot deal's At-risk field
true / false
writes only when escalated
safe to retry
From the call outcome
→
HubSpot deal · At-risk = true
transform
if call was escalated → set deal At-risk = true · if not escalated → leave deal alone (won't undo prior at-risk flags)
condition
only writes on escalation · low scores from later calls don't undo at-risk flags from earlier calls
also creates
HubSpot task on the deal · "Follow up: CSAT escalation from {{contact.name}}"
idempotency
if the same call already created a follow-up task for this deal, no duplicate is created
edit →
3
Call summary outcome.raw_summary→ HubSpot contact's Last CSAT summary field
text · up to 280 characters
writes on every call
safe to retry
From the call outcome
→
HubSpot contact · Last CSAT summary
edit →
Recent writes
last 7 · 100% success rate
14:32
contact:1234
csat_score = 9
✓
230ms
14:32
contact:1234
last_csat_summary updated
✓
180ms
14:32
deal:5491
timeline activity created
✓
312ms
14:28
deal:5678
at_risk = true
✓
195ms
14:28
deal:5678
task created · "Follow up: CSAT escalation"
✓
240ms
14:28
contact:5678
csat_score = 4
✓
210ms
14:11
contact:9012
csat_score = 8 · already-current (skipped)
↺ idem
15ms
Replays of completed writes are no-ops (key: call_id, hubspot_object_id, property). Failed writes retry exp-backoff for 24h, then DLQ to your Inbox + Today queue.
What this agent captures from each call. Each row is one piece of structured information saved to your CRM, Slack, or email. The tag on each row tells you
how it's captured — asked directly, listened for, computed, or generated after the call. The actual
questions the agent asks live in
State machine; this page is about the data shape and where it lands.
1
CSAT score Asked · step 1 (Ask score)
A number from 1 to 10. Saved to HubSpot's CSAT score field. Required — call goes to Review queue if missing.
customise →
2
What's working Asked · step 2 (when score ≥ 8)
A list of positive feedback themes the customer mentions when prompted. Optional — saved to Slack #cs-team summaries.
customise →
3
What needs attention Asked · steps 3 & 4 (when score ≤ 7)
A list of pain points or improvement areas the customer raises when prompted. Optional — saved to HubSpot's CSAT summary field.
customise →
4
At-risk flag Computed automatically
Set to true when the CSAT score is 5 or below — never asked, just derived. Saved to HubSpot's deal At-risk field, and posts a message in Slack #cs-escalations.
customise →
5
Renewal intent Asked · step 5 (Wrap)
Positive, negative, or unsure. Asked at the end of the call. Saved to HubSpot's deal Renewal signal field.
customise →
6
Do-not-call request Listened for · throughoutcompliance lock
Set to true if the customer says they don't want to be called again — never asked directly, only listened for. Adds the contact to the suppression list. Cannot be removed.
view (locked)
7
Call summary Generated after the call
A short text recap (up to 280 characters), produced by the AI once the call ends — not asked, not listened for. Pushed to HubSpot, Slack, and email.
customise →
Of triggered events, which qualify? Filter is evaluated server-side before the agent is invoked — non-matching events are dropped (no cost, no call).
Quick segment
Filter expression
Test data
14 triggered → 12 qualified → 2 filtered out (called within 30d)
When can this agent dial? Standard policy: 09:00–17:30 prospect's local TZ, weekdays. Calls outside the window are queued for the next valid slot.
Start time
End time
Timezone source
Holidays
Quiet hours
Sources we check before every dial. Adding a source means we check it on every call — slower for high-volume agents, but tighter compliance posture. At least one source is required (compliance).
✓
Internal suppression list
147 entries · auto-add on `dnc_requested = true`
view list →
✓
HubSpot DNC property
contact.hs_email_optout · synced every 15 min
configure →
○
UK National TPS
not enabled · ~5,200,000 numbers · adds 80ms per dial
enable →
○
US TCPA · National DNC
not enabled · adds ~120ms per dial
enable →
○
Custom CSV upload
not enabled · refresh weekly
upload →
DNC checks run pre-dial in parallel — total added latency is the slowest source, not the sum. A `dnc_requested = true` outcome auto-adds the contact to internal suppression (compliance policy).
Compliance disclosures. All five required disclosures are baked in — they fire automatically and cannot be removed. You can edit the wording for the two scripted ones (AI disclosure, recording disclosure). The other three run server-side.
AI disclosure
fires within first 3 turns · cannot be skipped
"Just so you know, I'm an AI assistant from {{account.name}} — we use this to keep up with our customers more often than we could otherwise."
Recording disclosure
fires before any audio is captured
"This call is being recorded for quality and so we can pass any specific feedback back to {{account.am_email}}. Is that OK?"
"Are you human?" intent
auto-routes to human disclosure · default wording (read-only)
DNC honour
runs pre-dial · sources configured separately
Calling window
enforced server-side · configured separately
Our compliance policy forbids removing or weakening these checks. Each gate firing writes a compliance event to the audit trail.
Voice profile. ElevenLabs voice models. Sample each to compare warmth, clarity, and brand fit. Premium voices use the higher-fidelity model.
Sarah
female · UK · warm
▶ play sample
James
male · UK · professional
▶ play sample
Jordan
non-binary · US · calm
▶ play sample
Rachel
female · US · expressive · premium
▶ play sample
Adam
male · US · authoritative
▶ play sample
+ clone
use a custom voice
upload audio →
Barge-in
Tone, pacing, empathy posture. Affects the speaking style and the prompt-system tuning. Doesn't change the words; changes the delivery and the LLM's behavioural prior.
Persona
Stability affects per-turn audio length and the LLM's behavioural prior. Lower values feel more human; higher values feel more consistent.
Auto-built from your Conversation. Every captured item becomes a section in the email — no template syntax to maintain. Toggle anything off you don't want in the AM's inbox; preview updates instantly. Drop into raw template editing only if you really need to.
Sent to
Cc
Send when
Conditions reference fields from your Conversation. Add a captured field there and it appears here automatically. Rename one and this rule updates with it.
Include from the conversation
Each captured item becomes a section in the email. Toggle off anything you don't want in the AM's inbox.
Preview
Fromcelliq notifications
Tobulat@aictrl.dev
celliq · CSAT call · Sarah Lin · 9/10
Hi James,
CSAT call with Sarah Lin (Head of Customer Success at acme.co).
Score: 9 / 10
"Strong CSAT call. Onboarding praised; support team called out as fast. Customer wants to expand seats next quarter."
What's working:
- Fast support
- Easy onboarding
Renewal intent: positive · plans to expand seats next quarter
Custom intro
Custom sign-off
From
What happens to fan-out writes that fail. Applies to every destination (HubSpot, Slack, email, calendar). Idempotency keys mean retries are safe.
Strategy
DLQ destination
Last 7 days: 412 successful writes · 3 retries (all eventually OK) · 0 dropped to Inbox. Typical write speed: 230ms.
Every change to this agent. Versions are auto-created when any cell changes. You can restore any prior version (preserves the current as a new draft, never overwrites silently).
v1.4 · current
2026-05-08 14:00
Sarah Lin
Slack routing
default channel: #revenue → #cs-team
v1.3
2026-05-08 12:30
James S.
Trigger
amount threshold: deal.amount >= 3000 → deal.amount >= 5000
↶ restore this version
v1.2
2026-05-07 16:21
James S.
Voice
voice profile: UK · neutral · ElevenLabs "Daniel" → UK · calm · ElevenLabs "Alice"
stability: 70 → 55
↶ restore this version
v1.1
2026-05-07 15:05
James S.
Brief sources
+ added celliq.history.last_csat_outcome → {{contact.last_call_summary}}
Audience filter
language predicate: + added contact.preferred_language = 'en'
↶ restore this version
v1.0
2026-05-07 14:32
James S.
Created
agent created from PA-001 (CSAT Survey) template · all 18 cells inherit template defaults · heavy path · auto-mapped from connected systems
Audit history is retained for 7 years. Each version snapshot includes the full agent configuration; restoring is non-destructive (creates a new version with the prior contents).
Pre-call research and enrichment. Async fetch of public + permitted data about the contact and their company before the agent dials. Output fields land in the brief alongside CRM data, usable in opening lines and probe prompts ({{company.recent_news}}).
Research engine · Firecrawl + Apify
2 active sources · cache TTL 24h · last warm 14m ago · 73% cache hit rate today
Roadmap. Today: Firecrawl (general web) + Apify (LinkedIn). Coming: a celliq-internal researcher that caches a knowledge graph per business + contact. External vendors keep firing only for new accounts and stale entries; cache hit rate keeps climbing as your account base grows.
Active sources
2 of 5 enabled
1
Company website— reads pages on the customer's site
Firecrawl
2 pages deep
~8 seconds
refreshed daily
Uses your HubSpot company website URL
→
Captures 4 things
Pages we look at
Homepage · About · Pricing · Blog (last 5 posts) · News · Press
What we capture
Recent news · What they do · Tech stack · Press coverage
If a page fails
We log it · the call still happens with whatever info we have
Last 7 days
214 of 218 successful · 4 timed out · 156 served from cache (72%)
collapse
2
LinkedIn company page— pulls company info from LinkedIn
Apify
company profile
~14 seconds
refreshed weekly
Matches by company name + website
→
Captures 3 things
What we capture
Employee count · Recent funding · Industry
Refresh
Once a week (LinkedIn changes slowly)
Last 7 days
198 of 218 successful · 14 no match (private or missing) · 6 rate-limited
edit →
Available
3 sources · click to enable
○
LinkedIn contact page Apify · GDPR-sensitive
Adds: contact.linkedin_summary, recent_role_change · 7d cache · enable per opt-in segment only
enable →
○
Crunchbase requires API key
Adds: company.funding_stage, company.last_round, company.investors · 7d cache
connect →
○
News + press releases Firecrawl + RSS
Adds: company.last_30d_news (deduped) · 12h cache
enable →
+
Custom URL fetcher per-call override
Pull a specific URL or pattern per call (e.g. {{contact.referral_link}}) and extract structured fields
build →
Policy
applies to all sources
Latency budget
90 s · per source
Sources fetch in parallel; budget is the slowest source, not the sum
Research depth
Standard · 2 sources
Light · Standard · Deep — auto-skips slowest source if budget tight
Cache TTL
24 h default · per source override
Same domain within window = free re-use
If something fails
Proceed with baseline brief
Alternative: skip call · queue retry
Recent runs
last 7 · 96% success rate
14:32
acme.co
2 sources · 4 things captured
✓
12s
14:11
pivot.co
2 sources · cache hit (warmed 4h ago)
↺ cache
0s
13:55
hooli.com
website ✓ · LinkedIn timeout
⚠ partial
14s
13:42
northwind.com
2 sources · 5 things captured
✓
11s
13:30
initech.com
DNC pre-empted · research skipped
— skipped
—
13:18
globex.io
2 sources · cache hit (warmed yesterday)
↺ cache
0s
12:45
stark-industries.com
2 sources · 6 things captured
✓
15s
External sources Firecrawl and Apify are registered as sub-processors for this workspace. Internal cached researcher (planned) will reduce dependency over time but not eliminate it for new accounts.
Editor for this cell isn't built in this mock.
In production, every cell opens its own editor in this slide-over — same pattern as Trigger, Brief sources, Slack routing, Calendar update, and State machine. Prompts deep-edit drops to the layered config view (layer.html).