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

# CTA URL Button Messages

> Send a single call-to-action URL button via WhatsApp

CTA URL button messages map a destination URL to a labeled button. Users never see the raw link — they tap the button and the URL opens in their default browser.

Use this when you want to drive traffic from WhatsApp to a web experience (a booking page, a product page, a checkout flow) without exposing a long, opaque URL in the message body.

## Send a CTA URL Message

<CodeGroup>
  ```typescript TypeScript theme={null}
  const message = await zavu.messages.send({
    to: "+14155551234",
    channel: "whatsapp",
    messageType: "cta_url",
    text: "Tap the button below to see available dates.",
    content: {
      ctaDisplayText: "See Dates",
      ctaUrl: "https://example.com/schedule?ref=zavu",
      ctaHeaderType: "image",
      ctaHeaderMediaUrl: "https://example.com/banner.png",
      footerText: "Dates subject to change."
    }
  });
  ```

  ```python Python theme={null}
  message = zavu.messages.send(
      to="+14155551234",
      channel="whatsapp",
      message_type="cta_url",
      text="Tap the button below to see available dates.",
      content={
          "cta_display_text": "See Dates",
          "cta_url": "https://example.com/schedule?ref=zavu",
          "cta_header_type": "image",
          "cta_header_media_url": "https://example.com/banner.png",
          "footer_text": "Dates subject to change."
      }
  )
  ```

  ```ruby Ruby theme={null}
  message = client.messages.send_(
    to: "+14155551234",
    channel: "whatsapp",
    message_type: "cta_url",
    text: "Tap the button below to see available dates.",
    content: {
      cta_display_text: "See Dates",
      cta_url: "https://example.com/schedule?ref=zavu",
      cta_header_type: "image",
      cta_header_media_url: "https://example.com/banner.png",
      footer_text: "Dates subject to change."
    }
  )
  ```

  ```go Go theme={null}
  message, err := client.Messages.Send(context.TODO(), zavudev.MessageSendParams{
      To:          zavudev.String("+14155551234"),
      Channel:     zavudev.String("whatsapp"),
      MessageType: zavudev.String("cta_url"),
      Text:        zavudev.String("Tap the button below to see available dates."),
      Content: &zavudev.MessageContentParams{
          CtaDisplayText:    zavudev.String("See Dates"),
          CtaURL:            zavudev.String("https://example.com/schedule?ref=zavu"),
          CtaHeaderType:     zavudev.String("image"),
          CtaHeaderMediaURL: zavudev.String("https://example.com/banner.png"),
          FooterText:        zavudev.String("Dates subject to change."),
      },
  })
  ```

  ```php PHP theme={null}
  $message = $client->messages->send([
      'to' => '+14155551234',
      'channel' => 'whatsapp',
      'messageType' => 'cta_url',
      'text' => 'Tap the button below to see available dates.',
      'content' => [
          'ctaDisplayText' => 'See Dates',
          'ctaUrl' => 'https://example.com/schedule?ref=zavu',
          'ctaHeaderType' => 'image',
          'ctaHeaderMediaUrl' => 'https://example.com/banner.png',
          'footerText' => 'Dates subject to change.',
      ],
  ]);
  ```

  ```bash cURL theme={null}
  curl -X POST https://api.zavu.dev/v1/messages \
    -H "Authorization: Bearer zv_live_xxx" \
    -H "Content-Type: application/json" \
    -d '{
      "to": "+14155551234",
      "channel": "whatsapp",
      "messageType": "cta_url",
      "text": "Tap the button below to see available dates.",
      "content": {
        "ctaDisplayText": "See Dates",
        "ctaUrl": "https://example.com/schedule?ref=zavu",
        "ctaHeaderType": "image",
        "ctaHeaderMediaUrl": "https://example.com/banner.png",
        "footerText": "Dates subject to change."
      }
    }'
  ```
</CodeGroup>

## Specifications

| Property            | Requirement                                                                                       |
| ------------------- | ------------------------------------------------------------------------------------------------- |
| Body text (`text`)  | Required, max 1024 chars                                                                          |
| `ctaDisplayText`    | Required, max 20 chars                                                                            |
| `ctaUrl`            | Required, valid URL (HTTPS required by WhatsApp in production)                                    |
| `ctaHeaderType`     | Optional: `text`, `image`, `video`, `document`                                                    |
| `ctaHeaderText`     | Required if `ctaHeaderType` is `text`, max 60 chars                                               |
| `ctaHeaderMediaUrl` | Required if `ctaHeaderType` is `image`, `video` or `document`. HTTPS URL that returns valid media |
| `footerText`        | Optional, max 60 chars                                                                            |

<Tip>
  The sender must have a WhatsApp Business Account connected. Header media URLs are fetched by WhatsApp — they must be publicly reachable and return the declared content type (e.g. `image/png` for an `image` header).
</Tip>

## Header Variants

### Text header

```json theme={null}
"content": {
  "ctaDisplayText": "Book now",
  "ctaUrl": "https://example.com/book",
  "ctaHeaderType": "text",
  "ctaHeaderText": "New workshop dates announced!"
}
```

### Image header

```json theme={null}
"content": {
  "ctaDisplayText": "Shop now",
  "ctaUrl": "https://example.com/sale",
  "ctaHeaderType": "image",
  "ctaHeaderMediaUrl": "https://example.com/sale-banner.jpg"
}
```

### Video header

```json theme={null}
"content": {
  "ctaDisplayText": "Watch more",
  "ctaUrl": "https://example.com/learn",
  "ctaHeaderType": "video",
  "ctaHeaderMediaUrl": "https://example.com/teaser.mp4"
}
```

### Document header

```json theme={null}
"content": {
  "ctaDisplayText": "Open PDF",
  "ctaUrl": "https://example.com/brochure",
  "ctaHeaderType": "document",
  "ctaHeaderMediaUrl": "https://example.com/brochure.pdf"
}
```

## No Webhook on Tap

<Note>
  Unlike reply [Buttons](/guides/whatsapp/messages/buttons) and [Lists](/guides/whatsapp/messages/list), **tapping a CTA URL button does not generate an inbound webhook**. The user is redirected directly to the destination URL inside their browser.

  To track clicks, append tracking parameters to `ctaUrl` (for example `?utm_source=whatsapp&clickID=abc123`) and read them on your landing page.
</Note>

## 24-Hour Window

CTA URL messages are free-form interactive messages. They can only be sent inside an open 24-hour conversation window — typically after the user has messaged you first.

To initiate a conversation outside the window, send a [template message](/guides/whatsapp/templates/sending) first, then follow up with a CTA URL message once the user replies.

## Use Cases

* Drive traffic to a booking or scheduling page
* Link to a checkout or product page from a promotion
* Share long campaign URLs without cluttering the message
* Replace raw URLs in receipts or confirmations with a branded button
* Direct users to a web form, survey, or support portal
