Skip to Content
API ReferenceWhatsAppClick-to-WhatsApp Ads

Click-to-WhatsApp Ads (CTWA)

Create Meta ads (Facebook, Instagram, Messenger) that, when tapped, open a WhatsApp chat with your business number. The ad lives on Meta’s Marketing API surface, so the first path segment here is your Meta ad account ID prefixed with act_ (not a WABA or phone number).

The flow is five POSTs in order:

1. Create Campaign → returns CAMPAIGN_ID 2. Create Ad Set → references CAMPAIGN_ID, returns ADSET_ID 3. Create Ad Creative → returns CREATIVE_ID 4. Create Ad → references ADSET_ID + CREATIVE_ID, returns AD_ID 5. Publish Ad → flips AD_ID's status to ACTIVE

Every step has a matching GET for read-back.

1. Create Ad Campaign

POST /api/v25.0/act_{AD_ACCOUNT_ID}/campaigns Authorization: Bearer pk_live_<your-key> Content-Type: application/json
{ "name": "Diwali Sale 2026", "objective": "OUTCOME_ENGAGEMENT", "status": "PAUSED", "special_ad_categories": [] }
FieldNotes
objectiveOUTCOME_ENGAGEMENT is the standard CTWA objective. Other accepted values: OUTCOME_LEADS, OUTCOME_SALES
statusCreate as PAUSED, publish later in step 5
special_ad_categoriesEmpty array unless this ad falls under credit / employment / housing / political categories

Response — 200

{ "id": "23857890123456789" }

Read back

GET /api/v25.0/{CAMPAIGN_ID}?fields=id,name,objective,status,effective_status

2. Create Ad Set

POST /api/v25.0/act_{AD_ACCOUNT_ID}/adsets Authorization: Bearer pk_live_<your-key> Content-Type: application/json
{ "name": "Diwali Sale 2026 — India 25-34", "campaign_id": "23857890123456789", "daily_budget": 100000, "billing_event": "IMPRESSIONS", "optimization_goal": "CONVERSATIONS", "promoted_object": { "page_id": "{PAGE_ID}", "whatsapp_phone_number": "+919876543210" }, "targeting": { "geo_locations": { "countries": ["IN"] }, "age_min": 25, "age_max": 34 }, "status": "PAUSED", "start_time": "2026-10-01T00:00:00+0530" }
FieldNotes
daily_budgetLowest currency unit (paise / cents). 100000 = ₹1,000/day
optimization_goalCONVERSATIONS for CTWA
promoted_object.whatsapp_phone_numberThe number the ad routes to. Must be a registered WhatsApp Business number on your account
targetingMeta Marketing API targeting spec — geo, age, interests, custom audiences

Response — 200

{ "id": "23857890234567890" }

Read back

GET /api/v25.0/{ADSET_ID}?fields=id,name,campaign_id,daily_budget,status,effective_status,optimization_goal,promoted_object,targeting

3. Create Ad Creative

POST /api/v25.0/act_{AD_ACCOUNT_ID}/adcreatives Authorization: Bearer pk_live_<your-key> Content-Type: application/json
{ "name": "Diwali Sale 2026 — Creative v1", "object_story_spec": { "page_id": "{PAGE_ID}", "link_data": { "message": "Diwali offer — 30% off, tap to chat!", "link": "https://wa.me/919876543210?text=I%27d%20like%20to%20know%20more", "image_hash":"<hash from /act_{ID}/adimages upload>", "call_to_action": { "type": "WHATSAPP_MESSAGE", "value": { "app_destination": "WHATSAPP" } } } } }

The link is a wa.me URL — Meta optimises it as a CTWA destination. image_hash comes from uploading an image to /act_{AD_ACCOUNT_ID}/adimages (one extra step not strictly part of the 5-step flow).

Response — 200

{ "id": "23857890345678901" }

Read back

GET /api/v25.0/{CREATIVE_ID}?fields=id,name,object_story_spec,image_hash

4. Create Ad

POST /api/v25.0/act_{AD_ACCOUNT_ID}/ads Authorization: Bearer pk_live_<your-key> Content-Type: application/json
{ "name": "Diwali Sale 2026 — Ad 1", "adset_id": "23857890234567890", "creative": { "creative_id": "23857890345678901" }, "status": "PAUSED" }

Response — 200

{ "id": "23857890456789012" }

Read back

GET /api/v25.0/{AD_ID}?fields=id,name,adset_id,creative,status,effective_status

5. Publish Ad (flip to ACTIVE)

POST /api/v25.0/{AD_ID} Authorization: Bearer pk_live_<your-key> Content-Type: application/json
{ "status": "ACTIVE" }

Response — 200

{ "success": true }

Once effective_status flips to ACTIVE (a few seconds after this call), the ad starts serving. Inbound messages from users who tap through include a referral block in your webhook — see Send Messages — webhook fan-out for the payload shape.

Errors

StatusBodyWhen
400(#100) Invalid parameterMissing required field at any step; check the Meta Marketing API field reference for the exact constraint
400(#200) Permissions errorYour ad account lacks ads_management permission, or the WhatsApp number isn’t linked to the Page
400(#1487749) Insufficient fundsAd account has no active payment method or balance
403id does not belong to your accountThe act_<AD_ACCOUNT_ID> isn’t linked to a customer under your partner account

cURL — full 5-step flow

# 1) Campaign CAMP_ID=$(curl -s -X POST \ "https://api.splashifypro.com/api/v25.0/act_$AD_ACCOUNT_ID/campaigns" \ -H "Authorization: Bearer $SPLASHIFY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Diwali 2026", "objective": "OUTCOME_ENGAGEMENT", "status": "PAUSED", "special_ad_categories": [] }' | jq -r .id) # 2) Ad Set ADSET_ID=$(curl -s -X POST \ "https://api.splashifypro.com/api/v25.0/act_$AD_ACCOUNT_ID/adsets" \ -H "Authorization: Bearer $SPLASHIFY_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"name\":\"India 25-34\", \"campaign_id\":\"$CAMP_ID\", \"daily_budget\":100000, \"billing_event\":\"IMPRESSIONS\", \"optimization_goal\":\"CONVERSATIONS\", \"promoted_object\":{\"page_id\":\"$PAGE_ID\",\"whatsapp_phone_number\":\"+919876543210\"}, \"targeting\":{\"geo_locations\":{\"countries\":[\"IN\"]},\"age_min\":25,\"age_max\":34}, \"status\":\"PAUSED\", \"start_time\":\"2026-10-01T00:00:00+0530\" }" | jq -r .id) # 3) Creative — assumes you've already uploaded the image to /act_$AD_ACCOUNT_ID/adimages CREATIVE_ID=$(curl -s -X POST \ "https://api.splashifypro.com/api/v25.0/act_$AD_ACCOUNT_ID/adcreatives" \ -H "Authorization: Bearer $SPLASHIFY_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"name\":\"Diwali Creative v1\", \"object_story_spec\":{ \"page_id\":\"$PAGE_ID\", \"link_data\":{ \"message\":\"Diwali offer — 30% off!\", \"link\":\"https://wa.me/919876543210\", \"image_hash\":\"$IMAGE_HASH\", \"call_to_action\":{\"type\":\"WHATSAPP_MESSAGE\",\"value\":{\"app_destination\":\"WHATSAPP\"}} } } }" | jq -r .id) # 4) Ad AD_ID=$(curl -s -X POST \ "https://api.splashifypro.com/api/v25.0/act_$AD_ACCOUNT_ID/ads" \ -H "Authorization: Bearer $SPLASHIFY_API_KEY" \ -H "Content-Type: application/json" \ -d "{ \"name\":\"Diwali Ad 1\", \"adset_id\":\"$ADSET_ID\", \"creative\":{\"creative_id\":\"$CREATIVE_ID\"}, \"status\":\"PAUSED\" }" | jq -r .id) # 5) Publish curl -X POST \ "https://api.splashifypro.com/api/v25.0/$AD_ID" \ -H "Authorization: Bearer $SPLASHIFY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "status": "ACTIVE" }'

Notes

  • Ad account must be linked to a customer under your partner account before these endpoints work — until that link exists, the act_<AD_ACCOUNT_ID> resolves to 403. Contact support to onboard an ad account.
  • CTWA attribution comes through on inbound message webhooks as a referral block with source_type: "ad", source_id, and ctwa_clid. Persist ctwa_clid on first contact — it’s the join key for downstream conversion attribution.
  • Targeting + budget follow Meta Marketing API semantics — detailed targeting docs live with Meta, not here.