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

# WhatsApp Notifications API

> Official documentation for using Lovi's API with WhatsApp via Postman

## Introduction

This section provides the official documentation for using Lovi's API with WhatsApp via Postman. It includes detailed instructions on how to set up and test API requests for WhatsApp integration, ensuring smooth communication through the platform. Authentication is performed using tokens that enable basic authentication for the API services. For more details on how to authenticate, please refer to the [Authentication](./authentication) page.

The Lovi API supports WhatsApp notifications with multimedia content, dynamic placeholders, scheduled delivery, and conversation flow integration.

### Key Features:

* WhatsApp notifications with multimedia support
* Dynamic content personalization with placeholders
* Scheduled message delivery with timezone support
* Conversation flow integration
* Two data structure formats (nested and flat)

***

## 📣 Send WhatsApp Notification

To send a notification via the Lovi API, make a POST request to the endpoint with the necessary parameters and authentication.

> **Method**: POST **Format**: JSON

### Endpoint

```
POST https://cloud.lovi.ai/functions/v1/notify?access_key={YOUR_ACCESS_KEY}
```

### Query Parameters

| Parameter    | Required | Description                                                                                                                                    |
| ------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `access_key` | Yes      | Your unique API access key.                                                                                                                    |
| `unflatten`  | No       | If set to `true`, the body must contain flat variables (no nested objects). If set to `false` or omitted, the body can contain nested objects. |

**Example URLs:**

```
POST https://cloud.lovi.ai/functions/v1/notify?access_key=your-api-key
POST https://cloud.lovi.ai/functions/v1/notify?access_key=your-api-key&unflatten=true
```

### Headers

| Key          | Value            | Required | Description                                        |
| ------------ | ---------------- | -------- | -------------------------------------------------- |
| Content-Type | application/json | Yes      | Indicates that the request body is in JSON format. |

**Note**: Authentication is handled via the `access_key` parameter in the URL, not through headers.

***

## 📋 Request Parameters

The API supports two data structure formats controlled by the `unflatten` parameter.

### Required Parameters

| Parameter               | Type            | Description                                                                  | Example                                       |
| ----------------------- | --------------- | ---------------------------------------------------------------------------- | --------------------------------------------- |
| `contact` OR `contacts` | Object OR Array | Single number contact (object) OR Multiple numbers contacts (array, max 100) | See below                                     |
| `language_template`     | String          | Language code for the template                                               | `"es_ES"`, `"en_US"`, `"es"`, `"es"`          |
| `name_template`         | String          | Name of the approved template                                                | `"welcome_user"`                              |
| `recipient_id`          | String          | Sender's ID number or phone number                                           | `"34666033135"`                               |
| `notification_type`     | String          | Type for analytics                                                           | `"marketing"`, `"transactional"`, `"utility"` |
| `campaign_name`         | String          | Campaign identifier name                                                     | `"Black Friday 2024"`                         |

**Important**: You must use either `contact` (for single recipient) OR `contacts` (for multiple recipients), but NOT both.

### Optional Parameters

| Parameter           | Type     | Description                         | When to Use                                         | Example                 |
| ------------------- | -------- | ----------------------------------- | --------------------------------------------------- | ----------------------- |
| `contact.name`      | String   | Contact's name for personalization  | For personalized messages                           | `"Juan Pérez"`          |
| `contact.email`     | String   | Contact's email                     | For additional contact data                         | `"juan@email.com"`      |
| `name_event`        | String   | Event to trigger conversation flows | When you want to start a specific conversation flow | `"intent-general-push"` |
| `datetime_sending`  | DateTime | Scheduled delivery time (ISO 8601)  | When you want to schedule the message for later     | `"2024-12-25T10:30:00"` |
| `timezone`          | String   | Timezone for scheduled delivery     | When using `datetime_sending`                       | `"Europe/Madrid"`       |
| `components_push.*` | Mixed    | Template components (text, media)   | When template requires dynamic content              | See components section  |

***

## 👥 Single vs Multiple Recipients

### Using `contact` - Send to One Person

Use `contact` when you want to send a notification to **one recipient**.

**Structure**:

```json theme={null}
{
  "contact": {
    "number": "34666033135",
    "name": "John",
    "email": "john@example.com"
  }
}
```

* `contact` is an **object** (not a list)
* Required field: `number`
* Optional fields: `name`, `email`, and any custom fields

***

### Using `contacts` - Send to Multiple People (Bulk Sending)

Use `contacts` when you want to send the same notification to **multiple recipients** at once.

**Structure**:

```json theme={null}
{
  "contacts": [
    {
      "number": "34666033135",
      "name": "John"
    },
    {
      "number": "34777044246",
      "name": "Sarah"
    },
    {
      "number": "34888055357",
      "name": "Michael"
    }
  ]
}
```

* `contacts` is a **list/array** (not a single object)
* **Maximum**: 100 contacts per request
* Each contact in the list must have a `number`
* Optional fields: `name`, `email`, and any custom fields

**Important Restrictions**:

* ⚠️ **Cannot use `unflatten=true` with `contacts`** - Bulk sending only works with nested structure
* ⚠️ **Cannot use both `contact` and `contacts`** in the same request - choose one
* ⚠️ **`contacts` list cannot be empty** - must have at least 1 contact

***

## 🔄 Data Structure Formats

The API supports two formats based on the `unflatten` parameter:

### Nested Structure (unflatten=false or omitted)

When `unflatten=false` or not specified, use nested objects:

```json theme={null}
{
  "contact": {
    "number": "34666033135",
    "name": "Juan Pérez",
    "email": "juan@email.com"
  },
  "components_push": {
    "header_text_0": "Welcome Message",
    "body_text_0": "Hello {{name}}",
    "body_text_1": "Your order is ready!",
    "footer_text_0": "Support Team"
  },
  "language_template": "es_ES",
  "name_template": "order_ready",
  "recipient_id": "34666033135",
  "notification_type": "transactional",
  "campaign_name": "Order Notifications"
}
```

### Flat Structure (unflatten=true)

When `unflatten=true`, all nested objects must be flattened using dot notation:

```json theme={null}
{
  "contact.number": "34666033135",
  "contact.name": "Juan Pérez",
  "contact.email": "juan@email.com",
  "components_push.header_text_0": "Welcome Message",
  "components_push.body_text_0": "Hello {{name}}",
  "components_push.body_text_1": "Your order is ready!",
  "components_push.footer_text_0": "Support Team",
  "language_template": "es_ES",
  "name_template": "order_ready",
  "recipient_id": "34666033135",
  "notification_type": "transactional",
  "campaign_name": "Order Notifications"
}
```

### When to Use Each Format

* **Nested Structure (`unflatten=false`)**: Recommended for better readability and when your system supports nested objects
* **Flat Structure (`unflatten=true`)**: Use when your system doesn't support nested objects or requires flat data structure

***

## 🎨 Components & Multimedia

**IMPORTANT**: Components you can send dynamically are **ONLY those returned by the template components endpoint**. The structure varies depending on whether the template has variables or media.

### Component Naming Rules

* **Header media**: `header_image`, `header_video`, `header_document` (NO suffix number)
* **Body variables**: `body_text_0`, `body_text_1`, `body_text_2`, etc. (with index number for each `{"{1}"}`, `{"{2}"}`, `{"{3}"}` placeholder)
* **Footer and Buttons**: Are STATIC in the template definition and CANNOT be sent dynamically

### How to Know Which Components to Send

1. First, call the template components endpoint:

   ```
   GET /notify/template/components?access_key={key}&template={template_id}
   ```

2. The API returns only the components you need to provide:

   ```json theme={null}
   {
     "status": "OK",
     "components": ["header_image", "body_text_0", "body_text_1"]
   }
   ```

3. Send ONLY those components in your notification request

### Component Types by Position

#### Header Components (Media Only)

**IMPORTANT**: Only ONE header component per template. Header text is STATIC in the template.

| Type       | Component Name    | Description         | Example Value                     | Specifications                 |
| ---------- | ----------------- | ------------------- | --------------------------------- | ------------------------------ |
| `image`    | `header_image`    | Header image URL    | `"https://example.com/image.jpg"` | JPG, PNG, GIF - Max 5MB        |
| `video`    | `header_video`    | Header video URL    | `"https://example.com/video.mp4"` | MP4, AVI, MOV - Max 16MB, 30s  |
| `document` | `header_document` | Header document URL | `"https://example.com/doc.pdf"`   | PDF, DOC, XLS, PPT - Max 100MB |

**Note**: `header_text` is NOT a dynamic component. Header text is defined in the template and cannot be changed.

#### Body Components (Variables Only)

Body text with placeholders requires variables in order: `{"{1}"}`, `{"{2}"}`, `{"{3}"}`, etc.

| Component Name | Description             | Maps to Template Placeholder |
| -------------- | ----------------------- | ---------------------------- |
| `body_text_0`  | First variable in body  | `{"{1}"}`                    |
| `body_text_1`  | Second variable in body | `{"{2}"}`                    |
| `body_text_2`  | Third variable in body  | `{"{3}"}`                    |
| `body_text_N`  | N-th variable in body   | `{"{N}"}`                    |

**Example Template**: "Hello `{"{1}"}`, your course `{"{2}"}` is ready"

* `body_text_0`: Value for `{"{1}"}` (e.g., "Maria")
* `body_text_1`: Value for `{"{2}"}` (e.g., "JavaScript")

#### Footer Components

⚠️ **Footer is STATIC** - defined in the template and cannot be modified per message.

#### Button Components

**IMPORTANT**: Most buttons are STATIC in the template. However, URL buttons with variables CAN be dynamic.

| Component Name  | Description                                       | When It Appears                                         |
| --------------- | ------------------------------------------------- | ------------------------------------------------------- |
| `buttons_url_0` | URL for first URL button with variable `{"{1}"}`  | When template has URL button with `{"{1}"}` placeholder |
| `buttons_url_1` | URL for second URL button with variable `{"{2}"}` | When template has multiple URL buttons with variables   |

**Example Template Button**: `"url": "https://example.com/{"{1}"}"`

* The template defines the URL pattern with placeholder
* You provide the value for `{"{1}"}` via `buttons_url_0`

**Note**: Quick reply buttons are always static and cannot be modified per message.

### Component Examples

#### Example 1: Template with Image Header (Nested Structure)

```json theme={null}
{
  "components_push": {
    "header_image": "https://cdn.example.com/promo.jpg"
  }
}
```

#### Example 2: Template with Body Variables (Nested Structure)

```json theme={null}
{
  "components_push": {
    "body_text_0": "María",
    "body_text_1": "JavaScript Advanced Course"
  }
}
```

#### Example 3: Template with Image and Variables (Flat Structure)

```json theme={null}
{
  "components_push.header_image": "https://cdn.example.com/promo.jpg",
  "components_push.body_text_0": "María",
  "components_push.body_text_1": "JavaScript Advanced Course"
}
```

***

## 🧩 Template Variables (Body Text)

**CRITICAL**: Variables in WhatsApp templates use **positional placeholders** like `{"{1}"}`, `{"{2}"}`, `{"{3}"}`, NOT named variables like `{"{name}"}`.

### How Template Variables Work

WhatsApp templates define variables as numbered placeholders in the template body text:

* Template text: "Hello `{"{1}"}`, your course `{"{2}"}` is ready"
* `{"{1}"}` maps to `body_text_0`
* `{"{2}"}` maps to `body_text_1`

### Variable Assignment

You provide the **values** for these numbered placeholders in the `components_push` object:

```json theme={null}
{
  "components_push": {
    "body_text_0": "María",
    "body_text_1": "JavaScript Advanced Course"
  }
}
```

**Result**: "Hello María, your course JavaScript Advanced Course is ready"

### Important Rules

1. **Positional order matters**: `body_text_0` = `{"{1}"}`, `body_text_1` = `{"{2}"}`, etc.
2. **Direct values**: Provide the actual value, not `{"{variable}"}` syntax
3. **All variables required**: Must provide values for all `{"{N}"}` placeholders in the template
4. **No mixing**: Cannot combine variables with static text in components\_push

### ✅ Valid Examples

**Template**: "Hello `{"{1}"}`, your order `{"{2}"}` is ready"

```json theme={null}
{
  "contact": {
    "name": "María",
    "order_id": "ORD-12345"
  },
  "components_push": {
    "body_text_0": "María",
    "body_text_1": "ORD-12345"
  }
}
```

**You can also use contact fields directly**:

```json theme={null}
{
  "contact": {
    "name": "María",
    "order_id": "ORD-12345"
  },
  "components_push": {
    "body_text_0": "{{name}}",
    "body_text_1": "{{order_id}}"
  }
}
```

### ❌ Invalid Examples

```json theme={null}
{
  "components_push": {
    "body_text_0": "Hello María", // ❌ Don't add template text, only the value
    "body_text_1": "{1}" // ❌ Don't use {1}, provide the actual value
  }
}
```

### Variable Resolution

The system resolves `{"{variable}"}` references in `components_push` by searching:

1. First in `contact` object
2. Then in root-level parameters

```json theme={null}
{
  "contact": {
    "name": "María",
    "email": "maria@example.com"
  },
  "order_id": "ORD-12345",
  "components_push": {
    "body_text_0": "{{name}}", // Resolved from contact.name → "María"
    "body_text_1": "{{order_id}}" // Resolved from root order_id → "ORD-12345"
  }
}
```

***

## ⏰ Scheduling & Conversation Flows

### Immediate Delivery (Default)

If `datetime_sending` is not specified, the message is sent immediately:

```json theme={null}
{
  "contact": { "number": "34666033135" },
  "language_template": "es_ES",
  "name_template": "welcome_user",
  "recipient_id": "34666033135",
  "notification_type": "marketing",
  "campaign_name": "Welcome Campaign"
}
```

### Scheduled Delivery

Use `datetime_sending` and `timezone` to schedule messages:

**Nested Structure:**

```json theme={null}
{
  "contact": { "number": "34666033135" },
  "language_template": "es_ES",
  "name_template": "welcome_user",
  "recipient_id": "34666033135",
  "notification_type": "marketing",
  "campaign_name": "Welcome Campaign",
  "datetime_sending": "2024-12-25T10:30:00",
  "timezone": "Europe/Madrid"
}
```

**Flat Structure:**

```json theme={null}
{
  "contact.number": "34666033135",
  "language_template": "es_ES",
  "name_template": "welcome_user",
  "recipient_id": "34666033135",
  "notification_type": "marketing",
  "campaign_name": "Welcome Campaign",
  "datetime_sending": "2024-12-25T10:30:00",
  "timezone": "Europe/Madrid"
}
```

### Conversation Flow Integration

Use `name_event` to trigger specific conversation flows:

```json theme={null}
{
  "contact": { "number": "34666033135" },
  "language_template": "es_ES",
  "name_template": "course_info",
  "recipient_id": "34666033135",
  "notification_type": "marketing",
  "campaign_name": "Course Enrollment",
  "name_event": "info-course-nursing"
}
```

***

## 📋 Complete Examples

### Example 1: Single Recipient with Body Variables

**Sending to ONE person using `contact`**

**Template**: "Hello `{"{1}"}`, thank you for your interest in `{"{2}"}`!"

**Request:**

```json theme={null}
{
  "contact": {
    "number": "34666033135",
    "customer_name": "Sarah"
  },
  "components_push": {
    "body_text_0": "{{customer_name}}",
    "body_text_1": "our Premium Membership"
  },
  "language_template": "en",
  "name_template": "interest_confirmation",
  "recipient_id": "34666033135",
  "notification_type": "marketing",
  "campaign_name": "Membership Campaign 2024"
}
```

**Response:**

```json theme={null}
{
  "success": true,
  "message": "Registration successful",
  "notification_id": "uuid-notification-123"
}
```

***

### Example 1B: Multiple Recipients (Bulk Sending)

**Sending to MULTIPLE people using `contacts`**

**Template**: "Hello `{"{1}"}`, thank you for your interest in `{"{2}"}`!"

**Request:**

```json theme={null}
{
  "contacts": [
    {
      "number": "34666033135",
      "customer_name": "Sarah"
    },
    {
      "number": "34777044246",
      "customer_name": "John"
    },
    {
      "number": "34888055357",
      "customer_name": "Michael"
    }
  ],
  "components_push": {
    "body_text_0": "{{customer_name}}",
    "body_text_1": "our Premium Membership"
  },
  "language_template": "en",
  "name_template": "interest_confirmation",
  "recipient_id": "bulk_campaign",
  "notification_type": "marketing",
  "campaign_name": "Membership Campaign 2024"
}
```

**Response:**

```json theme={null}
{
  "success": true,
  "message": "Processing completed",
  "total": 3,
  "processed": 3,
  "failed": 0,
  "errors": []
}
```

**If some contacts fail:**

```json theme={null}
{
  "success": true,
  "message": "Processing completed",
  "total": 3,
  "processed": 2,
  "failed": 1,
  "errors": [
    {
      "contact": { "number": "34888055357", "customer_name": "Michael" },
      "reason": "Invalid phone number format"
    }
  ]
}
```

***

### Example 2: Template with Image Header

**Template components**: `["header_image"]`

**URL:**

```
POST https://cloud.lovi.ai/functions/v1/notify?access_key=your-api-key
```

**Nested Structure:**

```json theme={null}
{
  "contact": {
    "number": "34666033135",
    "customer_name": "Robert",
    "email": "robert@example.com"
  },
  "components_push": {
    "header_image": "https://cdn.example.com/seasonal-promotion.jpg"
  },
  "language_template": "en",
  "name_template": "seasonal_offer",
  "recipient_id": "34666033135",
  "notification_type": "marketing",
  "campaign_name": "Holiday Sale 2024",
  "datetime_sending": "2024-12-24T09:00:00",
  "timezone": "Europe/Madrid"
}
```

**Note**: Body, footer, and buttons are static in the template and cannot be modified.

### Example 3: Template with PDF Document

**Template components**: `["header_document"]`

**URL:**

```
POST https://cloud.lovi.ai/functions/v1/notify?access_key=your-api-key&unflatten=true
```

**Flat Structure:**

```json theme={null}
{
  "contact.number": "34666033135",
  "contact.customer_name": "Jennifer",
  "contact.email": "jennifer@example.com",
  "components_push.header_document": "https://files.example.com/statement-2024.pdf",
  "language_template": "en",
  "name_template": "document_delivery",
  "recipient_id": "34666033135",
  "notification_type": "transactional",
  "campaign_name": "Monthly Statements"
}
```

### Example 4: Conversation Flow Trigger

**Nested Structure:**

```json theme={null}
{
  "contact": {
    "number": "34666033135",
    "first_name": "Laura",
    "last_name": "Martínez",
    "course_interest": "Web Development"
  },
  "language_template": "en_US",
  "name_template": "course_inquiry",
  "recipient_id": "34666033135",
  "notification_type": "marketing",
  "campaign_name": "Course Enrollment Q1",
  "name_event": "course-web-development-info",
  "datetime_sending": "2024-12-26T10:00:00",
  "timezone": "Europe/Madrid"
}
```

***

## 📊 Response Codes

### Successful Response (200 OK)

**Immediate sending:**

```json theme={null}
{
  "success": true,
  "message": "Notification queued successfully",
  "notification_id": "uuid-notification-123"
}
```

**Scheduled sending:**

```json theme={null}
{
  "success": true,
  "message": "Notification scheduled successfully",
  "notification_id": "uuid-notification-456",
  "scheduled_time": "2024-12-25T10:30:00Z"
}
```

### Error Responses

#### 400 Bad Request - Invalid Parameters

```json theme={null}
{
  "error": "validation_failed",
  "message": "Required field missing",
  "details": {
    "field": "contact.number",
    "reason": "This field is required"
  }
}
```

#### 401 Unauthorized - Invalid Access Key

```json theme={null}
{
  "error": "unauthorized",
  "message": "Invalid or expired access key"
}
```

#### 404 Not Found - Template Not Found

```json theme={null}
{
  "error": "template_not_found",
  "message": "Template 'welcome_user' not found or not approved"
}
```

#### 422 Unprocessable Entity - Business Logic Error

```json theme={null}
{
  "error": "template_not_approved",
  "message": "Template is not in approved status",
  "details": {
    "template_name": "pending_template",
    "current_status": "pending"
  }
}
```

#### 429 Too Many Requests - Rate Limit

```json theme={null}
{
  "error": "rate_limit_exceeded",
  "message": "Too many requests. Try again in 60 seconds",
  "retry_after": 60
}
```

***

## 🔧 Best Practices

### Data Structure

* **Prefer nested structure** (`unflatten=false`) for better readability
* **Use flat structure** (`unflatten=true`) only when your system requires it
* **Validate structure** before sending requests

### Media Guidelines

* **Use HTTPS URLs** for all media files
* **Optimize file sizes** for faster delivery
* **Use public URLs** without authentication requirements
* **Test media URLs** before sending to ensure accessibility

### Scheduling

* **Specify timezone** when using `datetime_sending`
* **Validate future dates** before scheduling
* **Consider business hours** for better engagement
* **Test scheduling** in development environment

### Placeholders

* **Use meaningful variable names** that match your data
* **Test variable substitution** before production
* **Keep one variable per field** to avoid errors
* **Provide fallback values** in your application logic

### Performance

* **Batch multiple notifications** when possible
* **Cache template information** to reduce API calls
* **Monitor rate limits** and implement backoff strategies
* **Use connection pooling** for better performance

***

## 🚨 Common Errors & Solutions

### Contact/Contacts Validation Errors

#### Error: Missing Contact Information

**Problem**: Request doesn't include `contact` or `contacts`

```json theme={null}
{
  "error": "validation_failed",
  "message": "Missing required field: 'contact' or 'contacts'"
}
```

**Solution**: You must include either `contact` (for one person) OR `contacts` (for multiple people)

***

#### Error: Using Both Contact and Contacts

**Problem**: Request includes both `contact` and `contacts` at the same time

```json theme={null}
{
  "error": "validation_failed",
  "message": "Cannot use both 'contact' and 'contacts' simultaneously"
}
```

**Solution**: Choose only one - use `contact` for single recipient or `contacts` for multiple recipients

***

#### Error: Contact is a List Instead of Object

**Problem**: Sent `contact` as a list `[...]` instead of an object `{...}`

```json theme={null}
{
  "error": "validation_failed",
  "message": "'contact' must be an object, not an array"
}
```

**Solution**: For single recipient, use `contact` as an object:

```json theme={null}
{
  "contact": {
    "number": "34666033135",
    "name": "John"
  }
}
```

***

#### Error: Contacts is Not a List

**Problem**: Sent `contacts` as an object `{...}` instead of a list `[...]`

```json theme={null}
{
  "error": "validation_failed",
  "message": "'contacts' must be an array, not an object"
}
```

**Solution**: For multiple recipients, use `contacts` as a list:

```json theme={null}
{
  "contacts": [
    { "number": "34666033135", "name": "John" },
    { "number": "34777044246", "name": "Sarah" }
  ]
}
```

***

#### Error: Empty Contacts List

**Problem**: Sent `contacts` as an empty list `[]`

```json theme={null}
{
  "error": "validation_failed",
  "message": "'contacts' array cannot be empty"
}
```

**Solution**: Include at least one contact in the list

***

#### Error: Too Many Contacts

**Problem**: Sent more than 100 contacts in the `contacts` list

```json theme={null}
{
  "error": "validation_failed",
  "message": "Maximum 100 contacts allowed per request. Received: 150"
}
```

**Solution**: Split your contacts into multiple requests of maximum 100 contacts each

***

#### Error: Unflatten with Contacts

**Problem**: Used `unflatten=true` with `contacts` (bulk sending)

```json theme={null}
{
  "error": "validation_failed",
  "message": "Parameter 'unflatten' is incompatible with 'contacts' array"
}
```

**Solution**: Bulk sending with `contacts` only works with nested structure. Remove `unflatten=true` or use `unflatten=false`

***

### Structure Mismatch

**Problem**: Mixing nested and flat structures
**Solution**: Choose one format consistently based on `unflatten` parameter

### Template Not Found

**Problem**: Using non-existent or non-approved template
**Solution**: Verify template name and approval status using template management endpoints

### Invalid Phone Format

**Problem**: Including '+' or spaces in phone number
**Solution**: Use clean international format without symbols (e.g., `34666033135`)

### Component Naming Errors

**Problem**: Using incorrect component names like `header_image_0` instead of `header_image`
**Solution**: Always check template components first using the `/notify/template/components` endpoint

### Variable Position Errors

**Problem**: Incorrect mapping between template placeholders and body\_text components
**Solution**: Remember `{"{1}"}` = `body_text_0`, `{"{2}"}` = `body_text_1`, etc.

### Modifying Static Components

**Problem**: Trying to send footer, buttons, or header text dynamically
**Solution**: These components are static in the template. Only send components returned by the template components endpoint

### Scheduling Errors

**Problem**: Past dates or invalid timezone
**Solution**: Use future dates in ISO 8601 format with valid IANA timezone codes

***

## 🔬 Template Examples

These examples demonstrate different types of template structures.

### Example 1: Simple Text Only Template

**Components returned by API**: `[]` (empty - no dynamic components)

```json theme={null}
{
  "contact": {
    "number": "34666033135"
  },
  "language_template": "en",
  "name_template": "welcome_message",
  "recipient_id": "34666033135",
  "notification_type": "marketing",
  "campaign_name": "Welcome Campaign"
}
```

**Note**: No `components_push` needed since template has no dynamic components.

***

### Example 2: Template with Body Variables

**Template Body**: "Hello `{"{1}"}`, your `{"{2}"}` is ready!"
**Components returned by API**: `["body_text_0", "body_text_1"]`

```json theme={null}
{
  "contact": {
    "number": "34666033135",
    "customer_name": "John",
    "product_name": "Premium Package"
  },
  "components_push": {
    "body_text_0": "{{customer_name}}",
    "body_text_1": "{{product_name}}"
  },
  "language_template": "en",
  "name_template": "order_ready",
  "recipient_id": "34666033135",
  "notification_type": "transactional",
  "campaign_name": "Order Notifications"
}
```

**Result**: "Hello John, your Premium Package is ready!"

***

### Example 3: Template with Image Header

**Components returned by API**: `["header_image"]`

```json theme={null}
{
  "contact": {
    "number": "34666033135"
  },
  "components_push": {
    "header_image": "https://example.com/promotional-banner.jpg"
  },
  "language_template": "en",
  "name_template": "promo_with_image",
  "recipient_id": "34666033135",
  "notification_type": "marketing",
  "campaign_name": "Holiday Sale"
}
```

**Note**: Body, footer, and buttons are static in the template.

***

### Example 4: Template with Video Header

**Components returned by API**: `["header_video"]`

```json theme={null}
{
  "contact": {
    "number": "34666033135"
  },
  "components_push": {
    "header_video": "https://example.com/product-demo.mp4"
  },
  "language_template": "en",
  "name_template": "video_announcement",
  "recipient_id": "34666033135",
  "notification_type": "marketing",
  "campaign_name": "Product Launch"
}
```

***

### Example 5: Template with PDF Document

**Components returned by API**: `["header_document"]`

```json theme={null}
{
  "contact": {
    "number": "34666033135",
    "customer_name": "Jane Smith"
  },
  "components_push": {
    "header_document": "https://example.com/invoice-12345.pdf"
  },
  "language_template": "en",
  "name_template": "invoice_delivery",
  "recipient_id": "34666033135",
  "notification_type": "transactional",
  "campaign_name": "Monthly Invoices"
}
```

***

### Example 6: Template with Header Text and Body Variable

**Header**: "Important Notice" (static text in template)
**Body**: "Hello `{"{1}"}`, welcome to our platform!"
**Components returned by API**: `["body_text_0"]`

```json theme={null}
{
  "contact": {
    "number": "34666033135",
    "first_name": "Michael"
  },
  "components_push": {
    "body_text_0": "{{first_name}}"
  },
  "language_template": "en",
  "name_template": "welcome_with_header",
  "recipient_id": "34666033135",
  "notification_type": "utility",
  "campaign_name": "User Onboarding"
}
```

**Result**:

* Header: "Important Notice"
* Body: "Hello Michael, welcome to our platform!"

***

### Example 7: Template with Dynamic URL Button

**Body**: Static text
**Buttons**:

* URL button with variable: `"url": "https://example.com/{"{1}"}"` (dynamic)
* Quick reply button: "Contact Support" (static)
  **Components returned by API**: `["buttons_url_0"]`

```json theme={null}
{
  "contact": {
    "number": "34666033135",
    "customer_id": "12345"
  },
  "components_push": {
    "buttons_url_0": "https://example.com/profile/{{customer_id}}"
  },
  "language_template": "en",
  "name_template": "account_notification",
  "recipient_id": "34666033135",
  "notification_type": "utility",
  "campaign_name": "Account Updates"
}
```

**Result**: The URL button will link to `https://example.com/profile/12345`

**Note**: The variable in `buttons_url_0` can reference contact fields using `{"{variable}"}` syntax, and the system will resolve it before sending.

***

## 📚 Related Documentation

* **[Authentication](./authentication)** - How to obtain access tokens and API keys
* **[Voice Notifications](./voice_notifications)** - Send automated voice calls
* **[Template Management](./template_management)** - Create and manage WhatsApp templates
* **[Scheduling](./scheduling)** - Advanced scheduling and timezone management
* **[Error Handling](./error_handling)** - Complete error codes and handling strategies
* **[Best Practices](./best_practices)** - Security and performance guidelines
