Skip to main content

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 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

ParameterRequiredDescription
access_keyYesYour unique API access key.
unflattenNoIf 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

KeyValueRequiredDescription
Content-Typeapplication/jsonYesIndicates 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

ParameterTypeDescriptionExample
contact.numberStringPhone number without ’+’ or spaces"34666033135"
language_templateStringLanguage code for the template"es_ES", "en_US"
name_templateStringName of the approved template"welcome_user"
recipient_idStringID or phone number of the recipient"34666033135"
notification_typeStringType for analytics"marketing", "transactional", "utility"
campaign_nameStringCampaign identifier name"Black Friday 2024"

Optional Parameters

ParameterTypeDescriptionWhen to UseExample
contact.nameStringContact’s name for personalizationFor personalized messages"Juan Pérez"
contact.emailStringContact’s emailFor additional contact data"[email protected]"
name_eventStringEvent to trigger conversation flowsWhen you want to start a specific conversation flow"intent-general-push"
datetime_sendingDateTimeScheduled delivery time (ISO 8601)When you want to schedule the message for later"2024-12-25T10:30:00"
timezoneStringTimezone for scheduled deliveryWhen using datetime_sending"Europe/Madrid"
components_push.*MixedTemplate components (text, media)When template requires dynamic contentSee components section

🔄 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:
{
  "contact": {
    "number": "34666033135",
    "name": "Juan Pérez",
    "email": "[email protected]"
  },
  "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:
{
  "contact.number": "34666033135",
  "contact.name": "Juan Pérez",
  "contact.email": "[email protected]",
  "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

Components follow the structure: {position}_{type}_{number}

Available Positions

  • header: Message header (supports text, image, video, document)
  • body: Main message content (text only)
  • footer: Message footer (text only)
  • button: Interactive buttons (URL links, quick replies)

Component Types by Position

Header Components

TypeDescriptionExampleSpecifications
textHeader text"header_text_0": "Welcome!"Max 60 characters
imageHeader image"header_image_0": "https://example.com/image.jpg"JPG, PNG, GIF - Max 5MB
videoHeader video"header_video_0": "https://example.com/video.mp4"MP4, AVI, MOV - Max 16MB, 30s
documentHeader document"header_document_0": "https://example.com/doc.pdf"PDF, DOC, XLS, PPT - Max 100MB

Body Components

TypeDescriptionExample
textMessage text"body_text_0": "Hello {{name}}"
textAdditional text"body_text_1": "Your course is ready"
TypeDescriptionExample
textFooter text"footer_text_0": "Support Team"

Button Components

TypeDescriptionExample
urlURL button"button_url_0": "https://my-store.com"
payloadQuick reply"button_payload_0": "CONTACT_SUPPORT"

Component Examples

Nested Structure:

{
  "components_push": {
    "header_image_0": "https://cdn.example.com/promo.jpg",
    "body_text_0": "Hello {{name}}!",
    "body_text_1": "Check out our Christmas special offer",
    "footer_text_0": "Valid until December 31st",
    "button_url_0": "https://store.example.com/christmas"
  }
}

Flat Structure:

{
  "components_push.header_image_0": "https://cdn.example.com/promo.jpg",
  "components_push.body_text_0": "Hello {{name}}!",
  "components_push.body_text_1": "Check out our Christmas special offer",
  "components_push.footer_text_0": "Valid until December 31st",
  "components_push.button_url_0": "https://store.example.com/christmas"
}

🧩 Dynamic Placeholders

Use placeholders like {{variable}} to dynamically inject values when the message is sent.

Important Rules

  1. One variable per field: Cannot mix multiple variables in the same field
  2. Variable OR static text: Cannot combine variables with static text in the same field
  3. Exact matching: Variable name must match the parameter name in the payload
  4. Search order: System searches first in contact object, then in root parameters

✅ Valid Examples

{
  "contact": {
    "name": "María",
    "course": "Nursing Assistant"
  },
  "components_push": {
    "body_text_0": "{{name}}",           // ✅ Only variable
    "body_text_1": "Static text only",   // ✅ Only static text
    "body_text_2": "{{course}}"          // ✅ Only variable
  }
}

❌ Invalid Examples

{
  "components_push": {
    "body_text_0": "Hello {{name}}, welcome!",  // ❌ Variable + static text
    "body_text_1": "{{name}} - {{course}}"      // ❌ Multiple variables
  }
}

Special System Variables

Some variables are automatically extracted:
  • {{name}}: From contact.name
  • {{number}}: From contact.number
  • {{email}}: From contact.email

⏰ Scheduling & Conversation Flows

Immediate Delivery (Default)

If datetime_sending is not specified, the message is sent immediately:
{
  "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:
{
  "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:
{
  "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:
{
  "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: Basic Marketing Message

Nested Structure (unflatten=false):
{
  "contact": {
    "number": "34666033135",
    "name": "Ana García"
  },
  "components_push": {
    "body_text_0": "Hello {{name}}!",
    "body_text_1": "Don't miss our Black Friday deals"
  },
  "language_template": "en_US",
  "name_template": "marketing_promo",
  "recipient_id": "34666033135",
  "notification_type": "marketing",
  "campaign_name": "Black Friday 2024"
}
Flat Structure (unflatten=true):
{
  "contact.number": "34666033135",
  "contact.name": "Ana García",
  "components_push.body_text_0": "Hello {{name}}!",
  "components_push.body_text_1": "Don't miss our Black Friday deals",
  "language_template": "en_US",
  "name_template": "marketing_promo",
  "recipient_id": "34666033135",
  "notification_type": "marketing",
  "campaign_name": "Black Friday 2024"
}

Example 2: Scheduled Message with Media

URL:
POST https://cloud.lovi.ai/functions/v1/notify?access_key=your-api-key
Nested Structure:
{
  "contact": {
    "number": "34666033135",
    "name": "Carlos Ruiz",
    "email": "[email protected]"
  },
  "components_push": {
    "header_image_0": "https://cdn.example.com/christmas-offer.jpg",
    "body_text_0": "Dear {{name}}",
    "body_text_1": "Your Christmas offer is ready! Valid until December 31st.",
    "footer_text_0": "Customer Service Team",
    "button_url_0": "https://store.example.com/offers"
  },
  "language_template": "en_US",
  "name_template": "seasonal_offer",
  "recipient_id": "34666033135",
  "notification_type": "marketing",
  "campaign_name": "Christmas 2024",
  "datetime_sending": "2024-12-24T09:00:00",
  "timezone": "Europe/Madrid"
}

Example 3: Transactional with Document

URL:
POST https://cloud.lovi.ai/functions/v1/notify?access_key=your-api-key&unflatten=true
Flat Structure:
{
  "contact.number": "34666033135",
  "contact.name": "María González",
  "contact.email": "[email protected]",
  "components_push.header_document_0": "https://files.example.com/invoice-001.pdf",
  "components_push.body_text_0": "Dear {{name}}",
  "components_push.body_text_1": "Your monthly invoice is attached.",
  "components_push.footer_text_0": "Billing Department",
  "language_template": "en_US",
  "name_template": "invoice_delivery",
  "recipient_id": "34666033135",
  "notification_type": "transactional",
  "campaign_name": "Monthly Billing"
}

Example 4: Conversation Flow Trigger

Nested Structure:
{
  "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:
{
  "success": true,
  "message": "Notification queued successfully",
  "notification_id": "uuid-notification-123"
}
Scheduled sending:
{
  "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

{
  "error": "validation_failed",
  "message": "Required field missing",
  "details": {
    "field": "contact.number",
    "reason": "This field is required"
  }
}

401 Unauthorized - Invalid Access Key

{
  "error": "unauthorized",
  "message": "Invalid or expired access key"
}

404 Not Found - Template Not Found

{
  "error": "template_not_found",
  "message": "Template 'welcome_user' not found or not approved"
}

422 Unprocessable Entity - Business Logic Error

{
  "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

{
  "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

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)

Placeholder Errors

Problem: Variable not found or incorrect syntax Solution: Ensure variable names match exactly and follow placeholder rules

Scheduling Errors

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