💬 Shared WhatsApp Inbox on the new PlatformMore
1msg official logo

Start lead qualification via WhatsApp API

This use case sends a new lead an approved WhatsApp template with a personalized greeting: the message substitutes the lead's name and product or source context, and the «Начать» (Start) quick-reply b

Use case overview

This use case sends a new lead an approved WhatsApp template with a personalized greeting: the message substitutes the lead's name and product or source context, and the «Начать» (Start) quick-reply button opens a short qualification flow. After the button is tapped, within the 24-hour session window the system asks follow-up questions one at a time and records each answer via webhook.

Template example

Hello, {{1}}! To find the right solution for {{2}} faster, please answer a few short questions. Tap «Начать» — it takes a couple of minutes.

Start
  • {{1}}
    lead or recipient name
  • {{2}}
    product interest or lead source context (where the request came from, which area is of interest)
  • “Start”
    button — fixed in the Meta template
WhatsApp Business API for lead qualification through key questions

When to use it

Reach for this scenario when a new lead arrives from a form, ad, or CRM with only basic contact data and sales needs a structured profile — budget, timeline, company size, use case — before the first call, but WhatsApp has no open session yet. It fits development teams, small product groups, and agencies wiring WhatsApp into the qualification funnel where one template question cannot capture the full profile.

Compliant first contact without an open chat
An approved template with two body variables — name and product or source context — plus a Start quick-reply button is the only way to open the conversation when no 24-hour session exists yet.
Full qualification profile in one thread
After the lead taps Start, follow-up questions go out one at a time within the session window and each answer arrives via webhook, so budget, timeline, company size and use case land in one structured profile instead of a single template field.
Less form abandonment
The lead answers short questions in WhatsApp after a personalized greeting, rather than completing a long web form they may never finish.
Faster handoff to sales or CRM
Once all key fields are stored in the qualification profile, the integrator passes the completed record to CRM or sales for routing — no rep retypes answers from scattered channels.
Stays inside the session window
Follow-up questions are sent right after each webhook answer while the 24-hour window stays open after the Start tap, so later questions do not require another approved template.

Workflow

  1. Build & send

    When a new lead appears, the system sends a personalized template greeting and an invitation to start a short qualification flow.

    POST /sendTemplate

  2. Status tracked

    The lead taps «Начать» — the event arrives via webhook and a session opens in the 24-hour WhatsApp window.

    status: "read"

  3. Within the session

    Within the session the integrator sends follow-up questions one at a time (budget, timeline, company size, use case).

    POST /sendTemplate

  4. Each answer is captured

    Each answer is captured via webhook and stored in the qualification profile.

    status: "read"

  5. Delivered

    After all key fields are collected the profile is passed to CRM or sales for follow-up.

    delivered

WhatsApp Business API for lead qualification through key questions

Technical implementation

Prerequisites

  1. 1MSG API Key · How to get API Key
  2. WhatsApp Business account · How to Connect WABA
  3. WhatsApp Template · How to Approve WABA Template
  4. Customer opt-in · How to Manage Customers Consent
  5. Webhook endpoint · How to Set Up Webhooks

Code examples

#!/usr/bin/env bash
set -euo pipefail

# === Configuration (replace "___" placeholders) ===

API_BASE_URL="https://api.1msg.io"        # production 1MSG API base URL
CHANNEL_ID="___"                           # channel ID from 1MSG dashboard
API_TOKEN="___"                            # channel JWT token (Bearer)

TEMPLATE_NAME="___"                        # approved template name
TEMPLATE_NAMESPACE="___"                   # template namespace (required — send fails without it)
TEMPLATE_LANGUAGE="___"                    # template language code, e.g. "en"



# === Test data ===
TEST_PHONE="___"                 # client phone in international format
TEST_LEADNAME="___"         # {{1}} lead name
TEST_PRODUCTCONTEXT="___"         # {{2}} product context

PHONE_NORM="$(printf '%s' "$TEST_PHONE" | tr -cd '0-9')"

for pair in "CHANNEL_ID=$CHANNEL_ID" "API_TOKEN=$API_TOKEN" \
            "TEMPLATE_NAME=$TEMPLATE_NAME" "TEMPLATE_NAMESPACE=$TEMPLATE_NAMESPACE" \
            "TEMPLATE_LANGUAGE=$TEMPLATE_LANGUAGE" "TEST_PHONE=$TEST_PHONE" \
            "TEST_LEADNAME=$TEST_LEADNAME" \
            "TEST_PRODUCTCONTEXT=$TEST_PRODUCTCONTEXT"; do
    val="${pair#*=}"
    if [ -z "$val" ] || [ "$val" = "___" ]; then
        echo "Missing configuration value: ${pair%%=*}" >&2
        exit 1
    fi
done

if [ -z "$PHONE_NORM" ]; then
    echo "Error: phone number has no digits after normalization" >&2
    exit 1
fi

URL="${API_BASE_URL%/}/${CHANNEL_ID}/sendTemplate"

# params carries body ONLY. Button text is fixed in the Meta template — no button param.

# {{1}} lead name → ${TEST_LEADNAME}
# {{2}} product context → ${TEST_PRODUCTCONTEXT}
read -r -d '' PAYLOAD <<JSON || true
{
  "phone": "${PHONE_NORM}",
  "template": "${TEMPLATE_NAME}",
  "namespace": "${TEMPLATE_NAMESPACE}",
  "language": { "policy": "deterministic", "code": "${TEMPLATE_LANGUAGE}" },
  "params": [
    {
      "type": "body",
      "parameters": [
        { "type": "text", "text": "${TEST_LEADNAME}" },
        { "type": "text", "text": "${TEST_PRODUCTCONTEXT}" }
      ]
    }

  ]
}
JSON

RESPONSE="$(curl -s -w '\n%{http_code}' -X POST "$URL" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${API_TOKEN}" \
    -d "$PAYLOAD")"

HTTP_CODE="$(printf '%s' "$RESPONSE" | tail -n1)"
BODY="$(printf '%s' "$RESPONSE" | sed '$d')"

case "$BODY" in
    *'"sent":true'*) ok=1 ;;
    *) ok=0 ;;
esac

if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ] && [ "$ok" -eq 1 ]; then
    echo "Message sent to client."
    echo "API response: $BODY"
else
    echo "Send failed. HTTP status: $HTTP_CODE" >&2
    echo "$BODY" >&2
    exit 1
fi

Response and delivery status

HTTP 2xx and JSON "sent": true mean 1MSG accepted the message for sending — not that it already reached the customer's phone. Save the id field (looks like wamid.…) to correlate delivery callbacks.

200 OKResponse
{
  "sent": true,
  "message": "Sent to [email protected]",
  "description": "Message has been sent to the provider",
  "id": "wamid.HBgLMzgwNjM5..."
}
  • sent

    Accepted for sending — not yet on the customer's phone

  • id

    Store it; delivery callbacks and hookInfo are keyed on this

Delivery statuses and webhooks →

Common errors

StatusAPI responseCauseFix
200Message was not sent: template is not definednamespace, template or language is missing from the request body.Send all three. Take namespace and the exact template name from GET /templates; language is an object: {"policy": "deterministic", "code": "en"}.
200template name (…) does not exist in <language>The template is approved in a different language than the one requested.Use the exact language code the template was approved in (for example es_MX is not the same as es). Check it in GET /templates.
200Message was not sent: provide chatId, phone, bsuid, or usernameNo recipient the channel could resolve.Pass exactly one recipient: phone (country code plus number, digits only), chatId (for example [email protected]) or bsuid.

All error codes →

Common questions

Related

Build for WhatsApp in hours
without infrastructure hassle