Agent Studio
Guides

Marketing Platform Integration

Trigger voice calls directly from CleverTap, MoEngage, Braze, and other marketing platforms

Marketing Platform Integration

This guide covers how to integrate Agent Studio with marketing automation platforms like CleverTap, MoEngage, Braze, and WebEngage to trigger voice calls directly from campaigns.

Overview

Marketing platforms can trigger Agent Studio calls via a webhook ingestion endpoint, eliminating the need for a custom backend service in between.

┌─────────────────┐     Webhook      ┌─────────────────┐     Voice Call    ┌─────────────────┐
│   CleverTap     │ ───────────────► │  Agent Studio   │ ────────────────► │     User        │
│   Campaign      │                  │  /webhooks/     │                   │   (+91...)      │
│                 │                  │   ingest        │                   │                 │
└─────────────────┘                  └─────────────────┘                   └─────────────────┘

Benefits:

  • No custom backend service required
  • Direct integration from marketing platform
  • Multi-tenant: each tenant configures their own campaigns
  • Works with any platform that supports outbound webhooks

Quick Start

1. Create an API Key

  1. Go to Dashboard → Settings → API Keys
  2. Create a key with scope: calls:create
  3. Save the key securely

2. Get Your Webhook URL

Your webhook ingestion URL is:

POST https://api.yourdomain.com/api/v1/webhooks/ingest

3. Configure Your Marketing Platform

In your marketing platform's webhook/campaign settings, configure:

FieldValue
URLhttps://api.yourdomain.com/api/v1/webhooks/ingest
MethodPOST
HeadersAuthorization: Bearer {your_api_key}
Content-Typeapplication/json

Request Format

{
  "workflow_slug": "free-trial-followup",
  "phone_number": "+919876543210",
  "user_id": "user-123",
  "user_context": {
    "name": "John",
    "trial_started_at": "2026-02-01",
    "plan_type": "premium"
  },
  "metadata": {
    "campaign_id": "trial_recovery_jan",
    "source": "clevertap"
  }
}

Required Fields

FieldTypeDescription
phone_numberstringUser's phone number in E.164 format (e.g., +919876543210)

One of These Required

FieldTypeDescription
workflow_slugstringWorkflow to execute (for multi-agent flows)
agent_slugstringSingle agent to use (for simple calls)

Note: Provide either workflow_slug OR agent_slug, not both.

Optional Fields

FieldTypeDescription
user_idstringExternal user identifier for tracking
user_contextobjectData passed to the agent (name, preferences, etc.)
metadataobjectAdditional tracking data (campaign_id, source, etc.)

Response

Success (201 Created)

{
  "call_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending"
}

Errors

StatusMeaning
400Invalid request (missing fields, invalid phone number)
401Invalid or missing API key
403API key lacks calls:create scope
404Workflow or agent not found
422Validation error (e.g., both workflow_slug and agent_slug provided)

Platform-Specific Setup

CleverTap

  1. Go to Settings → Channels → Webhooks
  2. Create a new webhook:
Name: Agent Studio Voice Call
URL: https://api.yourdomain.com/api/v1/webhooks/ingest
Method: POST
Headers:
  Authorization: Bearer as_live_xxxxx
  Content-Type: application/json
  1. In your campaign, use the webhook action with this body template:
{
  "workflow_slug": "free-trial-followup",
  "phone_number": "$Phone",
  "user_id": "$Identity",
  "user_context": {
    "name": "$Name",
    "email": "$Email"
  },
  "metadata": {
    "campaign_id": "$CampaignId",
    "source": "clevertap"
  }
}

MoEngage

  1. Go to Settings → App Settings → APIs
  2. Add a Custom Connector:
Connector Name: Agent Studio
Base URL: https://api.yourdomain.com
Authentication: API Key
Header Name: Authorization
Header Value: Bearer as_live_xxxxx
  1. Create a webhook action in your campaign:
Endpoint: /api/v1/webhooks/ingest
Method: POST
Body:
{
  "workflow_slug": "free-trial-followup",
  "phone_number": "{{UserAttribute['phone']}}",
  "user_id": "{{UserAttribute['user_id']}}",
  "user_context": {
    "name": "{{UserAttribute['name']}}"
  },
  "metadata": {
    "campaign_id": "{{CampaignId}}",
    "source": "moengage"
  }
}

Braze

  1. Go to Settings → Connected Content
  2. In your campaign, use a webhook:
Webhook URL: https://api.yourdomain.com/api/v1/webhooks/ingest
HTTP Method: POST
Headers:
  Authorization: Bearer as_live_xxxxx
  Content-Type: application/json

Body:
{
  "workflow_slug": "free-trial-followup",
  "phone_number": "{{${phone_number}}}",
  "user_id": "{{${user_id}}}",
  "user_context": {
    "name": "{{${first_name}}}"
  },
  "metadata": {
    "campaign_id": "{{campaign.${api_id}}}",
    "source": "braze"
  }
}

WebEngage

  1. Go to Data Platform → Integrations → REST API
  2. Configure the webhook:
URL: https://api.yourdomain.com/api/v1/webhooks/ingest
Method: POST
Headers:
  Authorization: Bearer as_live_xxxxx
  Content-Type: application/json

Payload Template:
{
  "workflow_slug": "free-trial-followup",
  "phone_number": "${user.phone}",
  "user_id": "${user.userId}",
  "user_context": {
    "name": "${user.firstName}"
  },
  "metadata": {
    "campaign_id": "${journey.journeyId}",
    "source": "webengage"
  }
}

Using Agent Context

Data passed in user_context is available to your agents via template variables:

In Agent Prompts

You are calling {{user.name}} about their {{user.plan_type}} trial
that started on {{user.trial_started_at}}.

In Tool Actions

{
  "type": "api_call",
  "url": "https://your-api.com/calls/log",
  "body": {
    "phone": "{{context.phone_number}}",
    "user_id": "{{user.user_id}}",
    "campaign": "{{metadata.campaign_id}}"
  }
}

Available Variables

VariableSource
{{user.*}}From user_context in request
{{context.phone_number}}Phone number being called
{{metadata.*}}From metadata in request
{{params.*}}Tool parameters (during tool execution)

Workflow vs Agent

Use workflow_slug when:

  • You have multi-agent flows with handoffs
  • Different scenarios route to different agents
  • You need shared context across agents
{
  "workflow_slug": "customer-support",
  "phone_number": "+919876543210"
}

Use agent_slug when:

  • Simple single-agent calls
  • Testing individual agents
  • No handoffs needed
{
  "agent_slug": "trial-followup-agent",
  "phone_number": "+919876543210"
}

Tracking Calls

Via Metadata

Include tracking data in metadata:

{
  "workflow_slug": "trial-followup",
  "phone_number": "+919876543210",
  "metadata": {
    "campaign_id": "jan_trial_recovery",
    "variant": "A",
    "source": "clevertap",
    "segment": "high_value"
  }
}

This data appears in:

  • Call detail view in dashboard
  • Call status webhooks (if configured)
  • Analytics exports

Via Call Status Webhooks

Configure Call Status Webhooks to receive notifications when calls complete:

{
  "type": "call.completed",
  "data": {
    "call_id": "...",
    "metadata": {
      "campaign_id": "jan_trial_recovery",
      "source": "clevertap"
    },
    "duration_seconds": 120,
    "transcript": [...]
  }
}

Rate Limits

LimitValue
Requests per minute600
Concurrent callsBased on your plan

For high-volume campaigns, consider:

  1. Staggering campaign sends
  2. Using campaign scheduling in your marketing platform
  3. Contacting support for limit increases

Error Handling

In CleverTap

Configure retry settings:

  • Retry on: 5xx errors, timeouts
  • Max retries: 3
  • Backoff: Exponential

Monitoring Failed Calls

  1. Check Dashboard → Calls for failed status
  2. Review error reasons in call details
  3. Set up Call Status Webhooks for call.failed events

Security Best Practices

  1. Use separate API keys per platform - Easier to rotate and audit
  2. Use Live keys for production - Test keys have rate limits
  3. Restrict key scopes - Only grant calls:create
  4. Monitor API key usage - Review in dashboard settings
  5. Rotate keys periodically - Especially if team members leave

Example: Free Trial Recovery Campaign

Workflow Setup

Create a workflow free-trial-followup with an agent that:

You are a Tap Health voice assistant conducting a brief follow-up call.

The user {{user.name}} started their free trial on {{user.trial_started_at}}
but didn't complete activation.

1. Greet them briefly
2. Mention they started a free trial but didn't complete it
3. Ask if they faced any issues
4. Offer to help them complete it
5. Thank them and end the call

Use the capture_lead_response tool to record their feedback.

CleverTap Campaign

Trigger: User property trial_status = incomplete AND days_since_trial_start > 1

Webhook body:

{
  "workflow_slug": "free-trial-followup",
  "phone_number": "$Phone",
  "user_id": "$Identity",
  "user_context": {
    "name": "$Name",
    "trial_started_at": "$trial_start_date",
    "plan_type": "$selected_plan"
  },
  "metadata": {
    "campaign_id": "trial_recovery_v2",
    "source": "clevertap",
    "segment": "$user_segment"
  }
}

Result Tracking

Configure a call status webhook to receive results:

@app.post("/webhooks/call-results")
async def handle_call_result(request: Request):
    event = await request.json()
    
    if event["type"] == "call.completed":
        data = event["data"]
        
        # Update CleverTap with call result
        await clevertap.profile_push({
            "identity": data["user_id"],
            "properties": {
                "last_voice_call": datetime.now().isoformat(),
                "voice_call_status": "completed",
                "voice_call_duration": data["duration_seconds"],
            }
        })

On this page