Skip to content

CleverTap

Connect CleverTap to JustAI to run AI-optimized copy experiments in your existing campaigns. CleverTap fetches the best content variant for each recipient at send time through Linked Content, and JustAI learns from the opens, clicks, and conversions you send back.

  1. You create a Linked Content API in CleverTap that points to JustAI’s content endpoint.
  2. At send time, CleverTap calls JustAI for each recipient and exposes the returned copy (subject, preheader, HTML body, and a copy ID) to your Email, Push, SMS, and In-app messages as Linked.JustAI.* Liquid variables. (CleverTap User Docs)
  3. You split each campaign with CleverTap’s A/B & Multivariate Testing: the control group keeps your current copy, and the treatment group uses the JustAI variables. (CleverTap User Docs)
  4. CleverTap streams or exports campaign events (sends, opens, clicks, and more) back to JustAI via webhooks or S3 exports. (CleverTap User Docs)
  5. JustAI joins those events with its record of which copy each recipient received, and serves better-performing copy over time.
  • Your JustAI org slug — usually your company name in lowercase (ask us if you’re not sure).
  • A JustAI API key (JustAI Console → Settings → API Keys).
  • The template ID (template_id) of the JustAI template you want to serve.
  • Access to CleverTap Settings (to add a Linked Content API) and to campaign creation.

This is one-time setup: point CleverTap at JustAI’s content endpoint, then set up the flow of campaign events back to JustAI.

  1. In CleverTap, go to Settings → Setup → Linked Content → + Linked Content.

  2. Set the API Name to JustAI.

  3. Set the Endpoint (GET) — recommended for Linked Content:

    https://worker.justwords.ai/api/generate/<org_slug>?template_id=<template_id>
  4. Auth: add your JustAI API key as X-Api-Key (the CleverTap UI supports adding an access key/params on the API).

  5. Add the query params to include:

    • user_id={{Profile.Identity}}
    • Any attributes you want JustAI to personalize on — see Personalization.
  6. Test the API in the Linked Content UI and use Auto-fill objects so CleverTap exposes Linked.JustAI.* labels in Liquid. The response is parsed as JSON and exposed to Liquid. (CleverTap User Docs)

JustAI returns copy.id and copy.vars.{…} fields such as subject, preheader, and body, which you access in CleverTap as Linked.JustAI.copy.*:

{
"copy": {
"id": "uuid",
"vars": {
"subject": "...",
"preheader": "...",
"body": "<html>…</html>"
}
}
}

Send engagement events for both control and treatment back to JustAI so it can measure which copy wins. Pick any one option (or combine them).

Option A — Custom events webhook (near-real-time)

Section titled “Option A — Custom events webhook (near-real-time)”

After JustAI confirms the payload mapping for your organization, create a Webhook campaign in CleverTap and post events to the generic JustAI events endpoint:

  • CleverTap → Campaigns → +Campaign → WebhooksGo To Editor.
  • Destination: https://worker.justwords.ai/api/webhook/events/<org_slug>
  • Auth header: X-Api-Key: <JUSTAI_API_KEY>
  • Send only the event types and fields included in your validated mapping. The following payload is illustrative; do not assume raw CleverTap events are accepted without that mapping:
{
"platform": "clevertap",
"channel": "email",
"event": "{{EventName}}",
"campaign_id": "{{Campaign.campaignId}}",
"variant_hint": "{{wzrk_pivot}}",
"user_id": "{{Profile.Identity}}",
"email": "{{Profile.Email}}",
"timestamp": "{{now}}",
"justai_copy_id": "{{ Linked.JustAI.copy.id }}"
}

You define the body in the Webhook Editor, and you can include identity, profile, and event properties. (CleverTap User Docs)

Option B — Post Action Webhooks (Push campaigns)

Section titled “Option B — Post Action Webhooks (Push campaigns)”

If you’re testing Push, enable Post Action Webhooks on the push campaign. CleverTap will POST message-level data (including the notification payload and keys such as wzrk_pivot for the A/B variant) after delivery. Point it to your JustAI endpoint. (CleverTap User Docs)

  • Configure Settings → Partners → Exports to Amazon S3 and write a daily scrubbed dataset under a JustAI-provisioned prefix (e.g., s3://justwords-metrics-ingest/<org>). (CleverTap User Docs)
  • Include event_timestamp, event_name, campaign_id, and (if available) linkage such as message/template IDs. JustAI reads these files for attribution. The suggested unified schema and S3 layout are the same across JustAI integrations.

How JustAI uses these events: JustAI joins CleverTap engagement (by user, campaign, and timestamp) with its own serve logs — the record of which copy each recipient received, including copy_id — to compute per-variant lift across control and treatment. Include justai_copy_id when feasible to make the joins trivial.

CleverTap supports Liquid tags across channels (Email, Push, SMS, Webhooks, WhatsApp, Native Display). In the campaign’s What section, map your Linked Content API and then reference values with Liquid: (CleverTap User Docs)

  • Subject (Email “Subject” field): {{ Linked.JustAI.copy.vars.subject | default:"" }}
  • Preheader (Email “Preheader” field): {{ Linked.JustAI.copy.vars.preheader | default:"" }}
  • HTML body (drag-and-drop block → “Customize with Liquid tags”, or source HTML):
{{ Linked.JustAI.copy.vars.body }}
<!-- JUSTAI_COPY_ID: {{ Linked.JustAI.copy.id }} -->

Liquid + Linked Content are available in the drag-and-drop editor too. (CleverTap User Docs)

Use CleverTap’s system labels to gate content if the API is slow or fails:

{% if Linked.JustAI.http_status_code == 200 %}
{{ Linked.JustAI.copy.vars.body }}
{% else %}
{{ Profile.fallback_html | default:"" }}
{% endif %}

Available system labels include http_status_code, JSON, raw, and more. (CleverTap User Docs)

Run each campaign as a split test: the control group keeps your current copy as the baseline, and the treatment group receives JustAI copy.

Option A — Campaign A/B test (most common)

Section titled “Option A — Campaign A/B test (most common)”
  • In your campaign, add A/B & Multivariate Testing.
  • Variant A (Control): your current static content.
  • Variant B (Treatment): the same creative, but replace subject/preheader/body with the Linked.JustAI Liquid tags above.
  • Run a 50/50 test (or your preferred split). CleverTap auto-determines winners by channel-appropriate metrics (clicks; for email, views/opens). (CleverTap User Docs)
  • In a Journey, branch traffic (IntelliNODE or an A/B branch) and place the Linked Content Liquid on the treatment path. (CleverTap User Docs)

Pass recipient attributes as query params on the Linked Content call so JustAI can tailor copy to each person. Use Liquid default filters so a missing profile field never breaks the call.

  • Always include the recipient’s identity: user_id={{Profile.Identity}}
  • Examples of attributes to personalize on:
    • first_name={{Profile.name | default:"there"}}
    • gender={{Profile.gender | default:"unknown"}}
    • cohort={{Profile.segment | default:"default"}}

Linked Content URL (GET)

https://worker.justwords.ai/api/generate/<org_slug>?template_id=<template_id>&user_id={{Profile.Identity}}&first={{Profile.name | default:"there"}}&gender={{Profile.gender | default:"unknown"}}

Liquid variables resolve per recipient; the response appears under Linked.JustAI.*. (CleverTap User Docs)

Email subject / preheader / body

{{ Linked.JustAI.copy.vars.subject | default:"" }}
{{ Linked.JustAI.copy.vars.preheader | default:"" }}
{{ Linked.JustAI.copy.vars.body }}
<!-- JUSTAI_COPY_ID: {{ Linked.JustAI.copy.id }} -->

Run this from a terminal to confirm your template and org are wired up. It returns the same response fields you’ll read in Linked Content:

Terminal window
export JUSTAI_API_KEY=...
curl -X POST "https://worker.justwords.ai/api/generate/<org_slug>" \
-H "X-Api-Key: $JUSTAI_API_KEY" -H "Content-Type: application/json" \
-d '{"template_id":"sample","attrs":{"role":"school"}}'

You can also call the endpoint with GET and template_id in the query string (as the Linked Content API does); the response shape is the same.

If you stream additional custom events to JustAI (for example, conversions such as purchases), a minimal payload looks like:

{
"event_timestamp": 1700000000,
"user_id": "abc123",
"event_name": "purchase"
}

If you prefer batch, write to the shared S3 prefix in parquet and partition by time; include campaign_id/template_id where possible.

  • Content is missing or the fallback always shows — Linked Content waits ~5s and does not retry failed calls. Always include the fallback pattern from Add a fallback. (CleverTap User Docs)
  • Duplicate or delayed webhook events — CleverTap webhooks use a 5s timeout with 2 retries, so retried deliveries can arrive more than once; plan idempotency on the JustAI side. (CleverTap User Docs)
  • A/B results are hard to read — You can test up to three variants; for email, winners often use opens/views, and for push/SMS, clicks. Keep a 50/50 split for clean readouts, or let CleverTap auto-select winners. (CleverTap User Docs)
  • Clicks can’t be tied to a specific variant — Add JUSTAI_COPY_ID as a hidden HTML comment or URL param so any click carries the served copy_id. JustAI also supports joining by user/campaign/timestamp if you prefer batch exports.