Chat CTAs
A Chat CTA is a call-to-action card the assistant renders inside a reply when the conversation earns it. Instead of a banner that shows to everyone, the card appears only when the answer actually touches your offer — so the pitch lands in context, right after a relevant answer.

Above: a visitor asked about real-estate investing, the assistant answered, and because the reply mentioned the configured trigger topics the CTA card appeared underneath it — title, teaser, thumbnail, and a button.
The two kinds
Section titled “The two kinds”The button opens targetUrl in a new tab (with a ref=divinci parameter
appended). Your own landing page handles capture, consent and delivery — no
lead infrastructure needed on the Divinci side. This is the simplest option and
the one shown in the screenshot above.
The card renders an inline lead-capture form in the chat. On a successful
submit Divinci stores the lead, syncs it to the Release’s CRM config, and only
then returns assetUrl.
When the card fires
Section titled “When the card fires”A CTA fires only when all of these hold:
- The Release references the CTA (
chatCTA: { id }). - The CTA doc is
active. - The cadence rules below say yes for this reply.
Cadence is owner-set; every field is optional and the defaults reproduce the original behavior (keyword match, once per conversation):
| Field | Meaning | Default |
|---|---|---|
triggerMode | keywords, interval, or keywords-or-interval | keywords |
triggerKeywords | Case-insensitive substring match against the reply text; first hit wins | — |
intervalMessages | Fire every Nth assistant reply (interval modes) | — |
minMessagesBeforeFirst | Never fire before the Nth reply | — |
maxPerThread | Total fires allowed in one conversation | 1 |
cooldownMessages | Minimum replies between two fires | — |
Matching is substring, not word-boundary, so a short stem like invest also
catches “investing” and “investment”. Narrow it with a longer phrase when that
is too eager.
Where CTAs render
Section titled “Where CTAs render”CTAs fire on both chat surfaces:
- Anonymous / embed chat — visitors on your website through the embed script, including behind the Free-Chat Gate. This is the primary lead-capture audience.
- Signed-in chat — authenticated transcripts in the web client.
Configure one
Section titled “Configure one”-
Create the CTA and attach it to a Release. Every surface below writes the same whitelabel-scoped sub-document and points the Release at it.
Terminal window divinci release update <releaseId> --chat-cta '{"title": "Interested in real estate investing?","teaserText": "Download our free guide — The California Apartment Owner'"'"'s Wealth Playbook.","buttonLabel": "Get instant access","triggerKeywords": ["real estate investing", "1031", "multifamily", "cap rate"],"ctaType": "link-out","targetUrl": "https://lp.example.com/playbook","active": true}'import { DivinciServer } from "@divinci-ai/server";const client = new DivinciServer({ apiKey: process.env.DIVINCI_API_KEY });await client.releases.updateInWorkspace(workspaceId, releaseId, {chatCTA: {title: "Interested in real estate investing?",teaserText: "Download our free guide.",buttonLabel: "Get instant access",triggerKeywords: ["real estate investing", "1031", "multifamily"],ctaType: "link-out",targetUrl: "https://lp.example.com/playbook",active: true,},});updateInWorkspaceGET-then-merges the full Release, creates the CTA sub-document, and points the Release at it in one call.Call the
release_updatetool with achatCTAobject:{"releaseId": "<releaseId>","chatCTA": {"title": "Interested in real estate investing?","teaserText": "Download our free guide.","triggerKeywords": ["real estate investing", "1031"],"ctaType": "link-out","targetUrl": "https://lp.example.com/playbook","active": true}}Any MCP-connected assistant (Claude, Cursor, …) can configure a CTA this way.
Workspace → Setup → Chat CTA to author the card, then attach it on the Release page under the Chat CTA section.
-
Verify it’s attached. The Release should now carry a
chatCTAreference:Terminal window divinci release get <releaseId> -
Ask a question that earns it. Send a message whose answer will contain one of your trigger keywords, and the card renders beneath the reply.
Email-gated downloads
Section titled “Email-gated downloads”Switch ctaType and add the gated asset plus the form config:
{ "title": "Get the 2026 market report", "teaserText": "12 pages of comps, yields and forecasts.", "ctaType": "email-gated-download", "assetUrl": "https://files.example.com/market-report-2026.pdf", "formFields": ["email", "name"], "consentText": "I agree to receive occasional updates.", "requireCaptcha": true, "successMessage": "Thanks! Your download is ready.", "triggerKeywords": ["market report", "comps", "forecast"], "active": true}Captured leads are stored per CTA and pushed to the Release’s configured CRM
(HubSpot / Attio). Narrow the sync to one provider with crmDestination, and
optionally double-write into your own Constant Contact list with
constantContactListId + constantContactAccessToken.
requireCaptcha puts a Cloudflare Turnstile challenge on the submit, reusing
the Free-Chat Gate’s Turnstile infrastructure.
Versioning
Section titled “Versioning”Chat CTAs are versioned like the other whitelabel resources (chat disclaimer,
thread prefix, terms of service). Every update that changes the card’s content
archives the previous revision to versionHistory and advances version, so
you can see what a CTA used to say and restore it from the admin UI.
Rotating only the Constant Contact credential is deliberately not a content revision — it doesn’t cut a new version, and the token never enters history.
Good to know
Section titled “Good to know”- One CTA per Release. The Release holds a single
chatCTAreference; swap the reference to change the offer. activeis the kill switch. An inactive CTA never fires even while the Release still references it — the fastest way to pull an offer without editing the Release.- Saving a Release preserves the CTA. The admin Release form round-trips the
chatCTAreference, so an unrelated edit won’t detach your card. - Links carry
ref=divinciso you can attribute the traffic in your own analytics.
Related
Section titled “Related”- Releases — the Release object that owns the CTA reference
- Embed Client — the widget CTAs render in
- Type Reference — the full
ChatCTAInputshape