Skip to content

MoEngage

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

  1. You create a Content API in MoEngage that points to JustAI’s content endpoint.
  2. At send time, MoEngage calls JustAI for each recipient and gets back copy (HTML body, subject, and a copy ID) that you insert into your email.
  3. In Flows, you split traffic: the control path keeps your current email as the baseline, and the treatment path uses the JustAI content.
  4. MoEngage sends campaign events (sends, opens, clicks) back to JustAI via Streams or warehouse exports.
  5. JustAI joins those events with its record of which copy each recipient received to measure control-vs-treatment performance and serve better copy over time.
  • Your JustAI org slug — usually your company name in lowercase (ask us if you’re not sure).
  • A JustAI API key to authenticate MoEngage’s calls (ask us if you don’t have one).
  • The template ID (template_id) of the JustAI template you want to serve.
  • Access to MoEngage Settings (to add a Content API) and to Flows.

Step 1 — Create a Content API pointing to JustAI

Section titled “Step 1 — Create a Content API pointing to JustAI”
  1. In MoEngage, go to Settings → Advanced → Content APIs → Add.
  2. Name it something like JustAI and set the URL to your JustAI content endpoint:
    • https://worker.justwords.ai/api/generate/<org_slug>?template_id=<template_id>
    • Headers: X-Api-Key: <JUSTAI_API_KEY>
  3. Enable the parameters you’ll pass (e.g., user_id, gender, cohort, etc.).

Send engagement events for both control and treatment back to JustAI so it can measure which copy wins.

Section titled “Option A — MoEngage Streams (recommended, near-real-time)”
  1. Ask MoEngage to enable Streams for your account.
  2. Ask JustAI to validate the MoEngage payload mapping for your organization.
  3. Configure Streams → Destination: HTTPS/Webhook to the generic JustAI events endpoint with auth:
    • https://worker.justwords.ai/api/webhook/events/<org_slug>
    • Header: X-Api-Key: <JUSTAI_API_KEY>
  4. Select only the campaign interaction events included in the validated mapping.
  5. Include identifiers in the payload: campaign_id, variation_id (the A/B path), event_time, user_id, email, and any custom properties you add (e.g., justai_copy_id if you inject it into the HTML as a hidden comment or link param).

Example event sent to JustAI (illustrative; the accepted shape depends on your mapping):

{
"platform": "moengage",
"channel": "email",
"event": "email_click",
"campaign_id": "{{campaign_id}}",
"variation_id": "{{variation_id}}",
"user_id": "{{user_id}}",
"email": "{{email}}",
"timestamp": "{{event_time}}",
"metadata": {
"flow_id": "{{flow_id}}",
"link_id": "{{link_id}}",
"justai_copy_id": "{{justai_copy_id}}"
}
}

How JustAI uses these events: JustAI joins Streams events (by user_id/email, campaign_id, and timestamp) with the content-serve logs from the JustAI Content API — the record of which copy each recipient received, including copy_id. That yields per-copy and per-branch (control vs treatment) opens and clicks.

Option B — Warehouse or S3 exports (batch)

Section titled “Option B — Warehouse or S3 exports (batch)”

If Streams isn’t available, configure S3 exports (or Redshift/BigQuery/Snowflake) and JustAI will read daily drops under an org-specific prefix. Export the same event set (sends/opens/clicks/unsubscribes) with campaign_id, variation_id, and user identifiers for attribution.

Build the experiment in Flows, with a control path (your current email) and a treatment path (JustAI copy):

  1. In Flows, add an “A/B Split”. Put your standard email on Path A (Control).
  2. Clone it to Path B (Treatment) and replace the content with a block that calls the JustAI Content API:
{# Call the Content API you added as "JustAI" #}
{% set jw = ContentApi.JustAI({
"params": {
"email": UserAttribute['Email']|default(''),
"user_id": UserAttribute['ID']|default(''),
"gender": UserAttribute['Gender']|default('')
},
"static_params": {},
"dynamic_params": {},
"request_body": {}
}) %}
{# Insert HTML returned by JustAI #}
{{ jw.copy.vars.body }}
{# Optional for analytics/debugging #}
<!-- JUSTAI_COPY_ID: {{ jw.copy.id|default('') }} -->

Notes:

  • You can also personalize the Subject/Preheader using values from UserAttribute[...] and safe defaults.
  • If your workspace exposes a different helper (e.g., contentapi('JustAI', params={...})), adapt the call accordingly.

Pass user attributes to the JustAI Content API so it can tailor copy to each recipient, and use safe defaults anywhere you reference attributes directly in your template.

First-name personalization (with safe fallbacks)

Section titled “First-name personalization (with safe fallbacks)”
{% set first = UserAttribute['First name'] %}
{% if first %}
Hi {{ first }},
{% else %}
Hi there,
{% endif %}

Segment-based personalization (gender or any attribute)

Section titled “Segment-based personalization (gender or any attribute)”
  1. Ensure attributes (e.g., Gender) are tracked on user profiles.
  2. Create segments in Segments → Create Segment (e.g., Gender == 'Male', Gender == 'Female', etc.).
  3. In your treatment path, pass these attributes to the JustAI Content API (gender, cohort, lifecycle_stage, etc.) so JustAI can return segment-specific variants.
  4. Optionally run A/B inside each segment to select segment-specific winners.