> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ondial.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Send WhatsApp and email

> Lead setup checks this campaign’s profile + template, then you POST /leads. No dial.

Templates stay in Omni Channel. The API only **lists** them and **sends**.

<Steps>
  <Step title="Dashboard (once)">
    Omni Channel: verified email mailbox and/or WhatsApp profile + templates.

    Start an **API / Custom CRM** campaign. Copy `campaignId`.
  </Step>

  <Step title="Lead setup — does this campaign’s template exist?">
    Paste `campaignId` into [Lead setup](/api-reference/endpoint/outbound/lead-setup) (Try it).

    ```bash theme={"system"}
    curl -sS -H "Authorization: Bearer $ONDIAL_API_KEY" \
      "$ONDIAL_BASE_URL/api/v1/campaigns/YOUR_CAMPAIGN_ID/lead-setup"
    ```

    Read `checks`: `ok: true` means that profile/template **exists**. `readyFor.email` / `readyFor.whatsapp` tells you which channels you can send.

    Copy **`email.lead`** or **`whatsapp.lead`**. Fill `email` / `phone` (and `whatsappParams` using `paramLabels`).

    Optional: [Validate lead](/api-reference/endpoint/outbound/validate-lead) with that body — nothing is created. `ok: true` means POST /leads will pass.

    To browse **every** template: `GET /api/v1/omni/templates` (add `?campaignId=` to mark `selected`). Copy `email.templates[].lead` or `whatsapp.templates[].lead`.
  </Step>

  <Step title="POST /leads">
    ```bash theme={"system"}
    curl -sS -X POST "$ONDIAL_BASE_URL/api/v1/leads" \
      -H "Authorization: Bearer $ONDIAL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "campaignId": "YOUR_CAMPAIGN_ID",
        "phone": "+919876543210",
        "email": "asha@example.com",
        "name": "Asha",
        "channels": ["whatsapp", "email"],
        "emailTemplateId": "YOUR_EMAIL_TEMPLATE_ID",
        "emailProfileId": "YOUR_EMAIL_PROFILE_ID",
        "templateVariables": {
          "contact_name": "Asha",
          "company_name": "Acme",
          "agent_name": "Roshni"
        },
        "whatsappTemplateId": "YOUR_WHATSAPP_TEMPLATE_ID",
        "whatsappProfileId": "YOUR_WHATSAPP_PROFILE_ID",
        "whatsappParams": ["Asha", "30", "inventory plan"]
      }'
    ```

    | Only this     | Body                                                                                  |
    | ------------- | ------------------------------------------------------------------------------------- |
    | WhatsApp      | `"channel": "whatsapp"` + `phone` (no `consent`)                                      |
    | Email         | `"channel": "email"` + `email` (no `consent`; `phone` optional, not dialed)           |
    | Both, no call | `"channels": ["whatsapp","email"]` as above — needs `phone` **and** `email`           |
    | Call          | `"channel": "call"` + `phone` + `consent.outboundCall: true` — no first-touch message |

    Passing a wrong `emailTemplateId` / `whatsappTemplateId` returns `422` (`*_not_found`) instead of silently using another template.
  </Step>

  <Step title="Check status">
    `201` repeats the template ids. Poll `GET /api/v1/contacts/{contactId}` for `whatsappQueueStatus` / `emailStatus`.

    Sandbox keys accept but never send.
  </Step>
</Steps>

Omit template ids to auto-pick Omni defaults. Pass ids when the CRM must choose a specific template.
