API Configuration

Loading...

API Keys Management
What are API Keys? API keys allow your external software to send WhatsApp messages through our platform. All messages sent via API will automatically appear in your Contact Management and Chat history.

Loading API keys...

API Testing Tool

Test endpoints from the portal with a live request/response viewer

Open the testing console

Send authenticated requests against your WABA and inspect responses without leaving ChatYug.

Open Testing Tool
API Documentation

Getting Started

Follow these simple steps to integrate our API with your software:

Step 1: Generate an API Key

Click the "Generate New API Key" button above to create your API key. Save it securely - you won't be able to see it again!

API keys start with ck_ and a long random secret (shown once when you generate the key). Do not use made-up or example strings.
Step 2: Authentication

Include your API key in the Authorization header of all requests:

Authorization: Bearer YOUR_API_KEY
Step 3: Make Your First API Call

Send a template message using cURL:

cURL
curl -X POST https://chatyug.com/api/external/send-message \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
    "to": "917016793529",
    "type": "template",
    "templateName": "hello_world",
    "templateLanguage": "en"
  }'
Security Best Practice: Never commit your API keys to version control. Store them securely in environment variables.
Supported type values on POST /send-message: text, template, image, video, audio, document. See the Send Media tab for photos/files (use mediaId from upload-media). Download the full PDF for complete request/response samples.

Send Text Message

Note: Text messages can only be sent within 24 hours of the customer's last reply due to WhatsApp's rules. Use template messages for cold contacts.

Endpoint: POST https://chatyug.com/api/external/send-message

Request Body:

JSON
{
  "phoneNumberId": "719142414620783",
  "to": "917016793529",
  "type": "text",
  "text": "Hello! This is a test message."
}

Response (Success):

JSON
{
  "success": true,
  "message": "text message sent successfully",
  "data": {
    "messageId": "wamid.HBgMOTE5ODc2NTQzMjEw...",
    "status": "sent",
    "conversationId": 12345
  }
}

Response (Error):

JSON
{
  "success": false,
  "message": "Failed to send text message: (#131047) Message failed to send because more than 24 hours have passed since the customer last replied to this number."
}

Code Examples:

cURL
curl -X POST https://chatyug.com/api/external/send-message \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "719142414620783",
    "to": "917016793529",
    "type": "text",
    "text": "Hello! This is a test message."
  }'

📷 Send Session Media (Image / Video / Audio / Document)

Send photos and files inside the 24-hour customer service window. Outside that window use an approved media template instead.

Important: Do not use type: "text" with mediaUrl — that only sends text. Set type to image, video, audio, or document.

Endpoint: POST https://chatyug.com/api/external/send-message

Option A — Upload then send (recommended)

  1. POST /api/external/messages/upload-media (multipart) → get mediaId
  2. POST /api/external/send-message with type + mediaId
cURL — upload
curl -X POST https://chatyug.com/api/external/messages/upload-media \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "mediaFile=@photo.jpg" \
  -F "phoneNumberId=YOUR_PHONE_NUMBER_ID" \
  -F "mediaType=image"
cURL — send image
curl -X POST https://chatyug.com/api/external/send-message \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
    "to": "917016793529",
    "type": "image",
    "mediaId": "META_MEDIA_ID_FROM_UPLOAD",
    "caption": "Here is the product photo"
  }'

Option B — Public HTTPS link

{
  "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
  "to": "917016793529",
  "type": "image",
  "mediaUrl": "https://example.com/images/product.jpg",
  "caption": "Optional caption"
}

Video / document examples

{
  "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
  "to": "917016793529",
  "type": "document",
  "mediaId": "META_MEDIA_ID",
  "filename": "invoice.pdf",
  "caption": "Your invoice"
}

Inbound media (customer photos)

ChatYug downloads inbound media to /received_media/.... Use GET /api/external/messages/:messageId/media for a stable URL. Do not cache Meta lookaside.fbsbx.com links — they expire in minutes.

Send Template Message

Recommended: Template messages can be sent anytime, even to cold contacts. They must be pre-approved by WhatsApp. Use the Templates API tab to list approved templates and variable placeholders for your integration.

Endpoint: POST https://chatyug.com/api/external/send-message

Simple Template (No Variables):

Request Body - JSON
{
  "phoneNumberId": "719142414620783",
  "to": "917016793529",
  "type": "template",
  "templateName": "hello_world",
  "templateLanguage": "en"
}

Response (Success):

JSON
{
  "success": true,
  "message": "template message sent successfully",
  "data": {
    "messageId": "wamid.HBgMOTE5ODc2NTQzMjEw...",
    "status": "sent",
    "conversationId": 12345
  }
}

Code Examples:

cURL
curl -X POST https://chatyug.com/api/external/send-message \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "719142414620783",
    "to": "917016793529",
    "type": "template",
    "templateName": "hello_world",
    "templateLanguage": "en"
  }'

Send Template Messages with Buttons

NEW! WhatsApp templates can now include interactive buttons. Use the `buttonParameters` array to send dynamic button values.

Supported Button Types:

1. URL Button - Direct users to a website

URL buttons allow users to visit a specific link. The template can have a static URL or a dynamic URL with a variable.

Example: Order Tracking Button

Template URL: https://example.com/track/{{1}}

Request Body - JSON
{
  "phoneNumberId": "719142414620783",
  "to": "917016793529",
  "type": "template",
  "templateName": "order_tracking",
  "templateLanguage": "en",
  "templateVariables": ["John Doe", "ORD-12345"],
  "buttonParameters": [
    {
      "type": "url",
      "index": 0,
      "value": "ORD-12345"
    }
  ]
}
Note: The value replaces the {{1}} variable in the button URL. The index is the button position (0-based).
2. Quick Reply Button - Simple response buttons

Quick reply buttons allow users to respond with predefined options. When clicked, the button sends a payload back to your webhook.

Example: Confirmation Buttons

Template buttons: "Yes" | "No" | "Maybe"

Request Body - JSON
{
  "phoneNumberId": "719142414620783",
  "to": "917016793529",
  "type": "template",
  "templateName": "appointment_confirmation",
  "templateLanguage": "en",
  "templateVariables": ["John Doe", "Oct 25, 2025", "2:00 PM"],
  "buttonParameters": [
    {
      "type": "quick_reply",
      "index": 0,
      "value": "CONFIRM_YES"
    },
    {
      "type": "quick_reply",
      "index": 1,
      "value": "CONFIRM_NO"
    }
  ]
}
Payload Handling: When a user clicks a quick reply button, WhatsApp sends the payload value (e.g., "CONFIRM_YES") to your webhook. Handle this in your webhook endpoint.
3. Phone Number Button - Call action

Phone number buttons allow users to call a specific number directly from WhatsApp. The phone number can be static or dynamic.

Example: Support Call Button

Template button: "Call Support" with dynamic number

Request Body - JSON
{
  "phoneNumberId": "719142414620783",
  "to": "917016793529",
  "type": "template",
  "templateName": "customer_support",
  "templateLanguage": "en",
  "templateVariables": ["John Doe"],
  "buttonParameters": [
    {
      "type": "phone_number",
      "index": 0,
      "value": "+919876543210"
    }
  ]
}
Note: The phone number must include the country code with a + prefix (e.g., +919876543210).
4. OTP/Copy Code Button - One-time password button

OTP buttons allow users to easily copy verification codes. This is ideal for authentication templates.

Example: Verification Code

Template: "Your verification code is {{1}}"

Request Body - JSON
{
  "phoneNumberId": "719142414620783",
  "to": "917016793529",
  "type": "template",
  "templateName": "otp_verification",
  "templateLanguage": "en",
  "templateVariables": ["123456"],
  "buttonParameters": [
    {
      "type": "otp",
      "index": 0,
      "value": "123456"
    }
  ]
}
Alternative: You can also use "type": "copy_code" - both work the same way.
5. Catalog Button - Show product catalog

Catalog buttons open your WhatsApp Business catalog. This is useful for e-commerce and product showcases.

Example: View Products Button
Request Body - JSON
{
  "phoneNumberId": "719142414620783",
  "to": "917016793529",
  "type": "template",
  "templateName": "product_showcase",
  "templateLanguage": "en",
  "templateVariables": ["John Doe"],
  "buttonParameters": [
    {
      "type": "catalog",
      "index": 0
    }
  ]
}
Requirement: Your WhatsApp Business Account must have a catalog set up in Meta Business Manager for this button to work.

Multiple Buttons Example:

Request Body - JSON
{
  "phoneNumberId": "719142414620783",
  "to": "917016793529",
  "type": "template",
  "templateName": "order_complete",
  "templateLanguage": "en",
  "templateVariables": ["John Doe", "ORD-12345", "₹1,299"],
  "buttonParameters": [
    {
      "type": "url",
      "index": 0,
      "value": "ORD-12345"
    },
    {
      "type": "phone_number",
      "index": 1,
      "value": "+919876543210"
    }
  ]
}
Button Limits:
  • Quick Reply: Maximum 3 buttons
  • Call-to-Action (URL/Phone): Maximum 2 buttons
  • OTP/Catalog: Maximum 1 button

Complete cURL Example with Buttons:

cURL
curl -X POST https://chatyug.com/api/external/send-message \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "719142414620783",
    "to": "917016793529",
    "type": "template",
    "templateName": "order_tracking",
    "templateLanguage": "en",
    "templateVariables": ["John Doe", "ORD-12345", "Rs. 1,299"],
    "buttonParameters": [
      {
        "type": "url",
        "index": 0,
        "value": "ORD-12345"
      },
      {
        "type": "quick_reply",
        "index": 1,
        "value": "TRACK_ORDER"
      }
    ]
  }'

📋 List Approved Templates & Variables

Fetch templates registered in ChatYug for your WABA. Use templateName, templateLanguage, and templateVariables in POST /api/external/send-message.

Base URL: https://chatyug.com/api/external  |  Auth: Authorization: Bearer YOUR_API_KEY
GET /templates — List templates

Query: status (APPROVED default, or PENDING, REJECTED, ALL), search, category, language

cURL
curl -X GET "https://chatyug.com/api/external/templates?status=APPROVED" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200 OK):

JSON
{
  "success": true,
  "total": 2,
  "templates": [
    {
      "templateId": 42,
      "templateName": "order_confirmation",
      "language": "en",
      "category": "UTILITY",
      "status": "APPROVED",
      "bodyText": "Hello {{1}}, your order {{2}} is confirmed.",
      "variableCount": 2,
      "variables": [
        { "index": 1, "component": "body", "placeholder": "{{1}}", "example": "Rahul" },
        { "index": 2, "component": "body", "placeholder": "{{2}}", "example": "ORD-12345" }
      ],
      "sampleSendRequest": {
        "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
        "to": "919876543210",
        "type": "template",
        "templateName": "order_confirmation",
        "templateLanguage": "en",
        "templateVariables": ["Rahul", "ORD-12345"]
      }
    }
  ]
}
GET /templates/:templateId — Template details
curl -X GET https://chatyug.com/api/external/templates/42 \
  -H "Authorization: Bearer YOUR_API_KEY"

Returns full body/header/footer text, variables, buttons, components, and sendMessageExample.

Create templates via API

Automation permission required for template creation endpoints. Your WABA must have automation enabled (portal → Automation). Templates are always submitted to Meta immediately — API returns PENDING. Poll GET /templates/:templateId/status until APPROVED or REJECTED.
POST /templates — Create & submit template

Accepts application/json or multipart/form-data (use mediaFile field for IMAGE/VIDEO/DOCUMENT headers). Alternatively pass assetHandle from Meta Resumable Upload.

JSON
curl -X POST https://chatyug.com/api/external/templates \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "templateName": "order_update_api",
    "templateContent": "Hi {{1}}, your order {{2}} is confirmed.",
    "category": "UTILITY",
    "language": "en",
    "variables": [
      { "index": 1, "example": "Rahul" },
      { "index": 2, "example": "ORD-991" }
    ]
  }'
Response
{
  "success": true,
  "data": {
    "templateId": 128,
    "metaTemplateId": "123456789",
    "status": "PENDING",
    "statusEndpoint": "/api/external/templates/128/status"
  }
}
GET /templates/:templateId/status — Poll approval

Returns PENDING, APPROVED, or REJECTED plus rejectionReason when applicable.

curl -X GET https://chatyug.com/api/external/templates/128/status \
  -H "Authorization: Bearer YOUR_API_KEY"
POST /templates/:templateId/sync — Force Meta sync
curl -X POST https://chatyug.com/api/external/templates/128/sync \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phoneNumberId": "YOUR_PHONE_NUMBER_ID"}'
POST /templates/carousel — Create carousel template

Register a carousel template with card images and buttons. Requires phoneNumberId, templateName, bodyText, and cards[] with headerSrc (HTTPS image URL) per card.

curl -X POST https://chatyug.com/api/external/templates/carousel \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
    "templateName": "summer_sale_carousel",
    "languageCode": "en_US",
    "bodyText": "Swipe to explore our summer collection",
    "cards": [
      { "headerSrc": "https://chatyug.com/example/card1.jpg", "bodyText": "T-shirt", "buttons": [{ "type": "URL", "text": "Shop", "url": "https://example.com" }] }
    ]
  }'

Once APPROVED, send with POST /api/external/messages/carousel.

Your approved templates (live)

Select a template to copy the ready-to-use send-message JSON for your integration.

Loading templates…

📅 Scheduled Messages API

Schedule template-based WhatsApp sends from your CRM, ERP, or custom platform — no portal login required. ChatYug's background processor fires at the scheduled time; use the report endpoint for delivery status.

Prerequisites: API key + automation permission on the WABA. Template must be APPROVED in Meta before scheduling. Default timezone: Asia/Kolkata. Use ISO date (YYYY-MM-DD) and HH:mm time.
POST /scheduled-messages — Create schedule

scheduleType: ONE_TIME or RECURRING. For recurring, include recurrencePattern, recurrenceInterval, recurrenceDays, recurrenceEndDate.

JSON
curl -X POST https://chatyug.com/api/external/scheduled-messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
    "scheduleName": "Monday promo",
    "scheduleType": "ONE_TIME",
    "templateName": "order_update",
    "templateLanguage": "en",
    "scheduledDate": "2026-07-25",
    "scheduledTime": "10:30",
    "timezone": "Asia/Kolkata",
    "recipients": [
      { "phoneNumber": "919876543210", "variables": { "1": "Rahul", "2": "ORD-991" } }
    ]
  }'

variables map to template {{1}}, {{2}} placeholders.

GET /scheduled-messages — List schedules

Query: status, scheduleType, phoneNumberId, page, limit

curl -X GET "https://chatyug.com/api/external/scheduled-messages?status=PENDING&page=1&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET /scheduled-messages/:scheduleId — Schedule detail
curl -X GET https://chatyug.com/api/external/scheduled-messages/101 \
  -H "Authorization: Bearer YOUR_API_KEY"
GET /scheduled-messages/:scheduleId/report — Delivery report

Returns summary counts (sent, delivered, read, failed, pending) and per-recipient delivery details.

curl -X GET https://chatyug.com/api/external/scheduled-messages/101/report \
  -H "Authorization: Bearer YOUR_API_KEY"
DELETE /scheduled-messages/:scheduleId — Cancel

Cancels a pending schedule. Requires automation permission.

curl -X DELETE https://chatyug.com/api/external/scheduled-messages/101 \
  -H "Authorization: Bearer YOUR_API_KEY"
POST /scheduled-messages/upload-csv — Validate CSV recipients

Multipart upload with field csvFile. CSV must include a phone column (or Phone, phone_number). Returns validated rows for use in create payload.

curl -X POST https://chatyug.com/api/external/scheduled-messages/upload-csv \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "csvFile=@recipients.csv"
POST /scheduled-messages/:scheduleId/run-now — Run immediately

Queues a PENDING or FAILED schedule for immediate execution by the background processor.

curl -X POST https://chatyug.com/api/external/scheduled-messages/101/run-now \
  -H "Authorization: Bearer YOUR_API_KEY"

Error codes

CodeWhen
AUTOMATION_ACCESS_DENIEDWABA lacks automation permission
TEMPLATE_NOT_APPROVEDTemplate not approved in Meta
VALIDATION_ERRORMissing or invalid fields

Full guide: Scheduled Messages API documentation

Check Delivery Status

Endpoint: GET https://chatyug.com/api/external/delivery-status/:messageId

Example Request:

cURL
curl -X GET https://chatyug.com/api/external/delivery-status/wamid.HBgMOTE5... \
  -H "Authorization: Bearer YOUR_API_KEY"

Response:

JSON
{
  "success": true,
  "data": {
    "messageId": "wamid.HBgMOTE5ODc2NTQzMjEw...",
    "status": "read",
    "to": "917016793529",
    "customerName": "John Doe",
    "messageType": "template",
    "content": "Template: order_confirmation",
    "sentAt": "2025-10-19T12:00:00.000Z",
    "deliveredAt": "2025-10-19T12:00:05.000Z",
    "readAt": "2025-10-19T12:00:15.000Z",
    "error": null
  }
}

Status Values:

  • sent - Message sent to WhatsApp
  • delivered - Message delivered to recipient
  • read - Message read by recipient
  • failed - Message failed to send

Complete Coding Guide

Comprehensive code examples for integrating our WhatsApp API in different programming languages. All requests use Authorization: Bearer YOUR_API_KEY (not X-API-Key). Text, template, and session media (image/video/audio/document) all use POST /api/external/send-message with a type field. For photos, set type: "image" with mediaId — not type: "text" + mediaUrl.

📦 Product Catalog API

Manage your product catalog programmatically — list catalogs, pull products, push new products, update stock/pricing, and send catalog messages to customers.

Base URL: https://chatyug.com/api/external  |  Auth: Authorization: Bearer YOUR_API_KEY
Category browse (SHOP keyword) — integrator-owned flow

ChatYug does not auto-reply to SHOP. Your app receives inbound webhooks, calls the APIs below, and sends WhatsApp messages. Assign category on each product in the portal or via POST /catalogs/:id/products.

  1. Customer sends text (e.g. SHOP) → your webhook eventType: message
  2. GET /catalogs/{metaCatalogId}/categories
  3. POST /messages/interactive with interactiveType: "list" and sections from interactiveListSections
  4. Customer taps a category → webhook list_reply.id = category slug (e.g. cat_dairy)
  5. GET /catalogs/{id}/product-list-payload?category={slug}
  6. POST /messages/product-list with returned sections or productRetailerIds

Limits: max 10 category rows per list; max 30 products per product_list message. Use truncated: true in payload response to paginate.

POST /catalogs — Create a catalog

Creates a product catalog in Meta and saves it in ChatYug. WABA is inferred from your API key.

FieldRequiredDescription
catalogNameDisplay name for the catalog
verticalcommerce or local_service (and other supported verticals)
cURL
curl -X POST https://chatyug.com/api/external/catalogs \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"catalogName": "My Shop Catalog", "vertical": "commerce"}'
GET /catalogs — List all catalogs

Returns all active WhatsApp product catalogs linked to your WABA.

Request:

cURL
curl -X GET https://chatyug.com/api/external/catalogs \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200 OK):

JSON
{
  "success": true,
  "total": 2,
  "catalogs": [
    {
      "Catalog_Id": 1,
      "Meta_Catalog_Id": "980328057290841",
      "Catalog_Name": "My Shop Catalog",
      "Description": "Main product catalog",
      "Product_Count": 45,
      "Is_Active": true,
      "Created_At": "2025-01-15T10:30:00.000Z",
      "Last_Synced_At": "2025-04-01T08:00:00.000Z"
    }
  ]
}
GET /catalogs/:catalogId/products — Pull products from catalog

Fetch all products from a catalog. catalogId can be the Meta Catalog ID or internal Catalog_Id.

Query Parameters:

ParameterTypeDescription
pageintegerPage number (default: 1)
limitintegerProducts per page (default: 50, max: 200)
searchstringSearch by name, description, or retailer ID
categorystringFilter by category name or slug from GET /catalogs/:id/categories
availabilitystringin stock or out of stock
cURL
curl -X GET "https://chatyug.com/api/external/catalogs/980328057290841/products?page=1&limit=20&availability=in+stock" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200 OK):

JSON
{
  "success": true,
  "products": [
    {
      "Product_Id": 101,
      "Meta_Product_Id": "5678901234567",
      "Product_Name": "Premium Cotton T-Shirt",
      "Description": "100% cotton, available in all sizes",
      "Retailer_ID": "TSHIRT-WHITE-M",
      "Currency": "INR",
      "Price": "599.00",
      "Image_URL": "https://example.com/tshirt.jpg",
      "Product_URL": "https://example.com/products/tshirt",
      "Availability": "in stock",
      "Category": "Apparel",
      "Brand": "MyBrand",
      "Inventory": 150
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 45,
    "pages": 3
  }
}
GET /catalogs/:catalogId/categories — List product categories

Returns distinct categories for commerce browse. Includes interactiveListSections ready for POST /messages/interactive (category picker). Products without a category appear as Uncategorized.

Query Parameters:

ParameterTypeDescription
inStockOnlybooleanDefault true — only count in-stock products
cURL
curl -X GET "https://chatyug.com/api/external/catalogs/980328057290841/categories" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200 OK):

JSON
{
  "success": true,
  "catalogId": "980328057290841",
  "categories": [
    { "name": "Kitchen Appliances", "slug": "cat_kitchen_appliances", "productCount": 5 },
    { "name": "Dairy", "slug": "cat_dairy", "productCount": 3 }
  ],
  "interactiveListSections": [
    {
      "title": "Categories",
      "rows": [
        { "id": "cat_kitchen_appliances", "title": "Kitchen Appliances", "description": "5 products" },
        { "id": "cat_dairy", "title": "Dairy", "description": "3 products" }
      ]
    }
  ]
}

Use slug as list_reply row id and pass it back to ?category= on product-list-payload. Row title max 24 chars (Meta limit).

GET /catalogs/:catalogId/product-list-payload — Build product_list sections

Returns sections and productRetailerIds for POST /messages/product-list. No hardcoded product lists — built dynamically from catalog DB.

Query Parameters:

ParameterTypeDescription
categorystringCategory slug from GET /categories (e.g. cat_dairy)
groupByCategorybooleanIf true and no category, one section per category (max 30 products total)
cURL
curl -X GET "https://chatyug.com/api/external/catalogs/980328057290841/product-list-payload?category=cat_dairy" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200 OK):

JSON
{
  "success": true,
  "catalogId": "980328057290841",
  "sections": [
    {
      "title": "Dairy",
      "product_items": [
        { "product_retailer_id": "MILK-1L" },
        { "product_retailer_id": "YOGURT-500G" }
      ]
    }
  ],
  "productRetailerIds": ["MILK-1L", "YOGURT-500G"],
  "totalProducts": 2,
  "truncated": false
}

truncated: true means more than 30 in-stock products matched — send additional product-list messages with the remaining IDs.

Category browse — integrator pseudocode

ChatYug forwards inbound messages to your webhook. Your app owns keyword detection and the category → product list journey.

JavaScript
async function onWebhook(event) {
  if (event.eventType !== 'message') return;
  const msg = event.data?.message;
  const from = event.data?.from;
  const catalogId = 'YOUR_META_CATALOG_ID';
  const phoneNumberId = event.phoneNumberId;

  if (msg?.type === 'text' && /^(shop|catalogue)$/i.test(msg.text?.body?.trim())) {
    const { interactiveListSections } = await api('GET', `/catalogs/${catalogId}/categories`);
    await api('POST', '/messages/interactive', {
      phoneNumberId, to: from, interactiveType: 'list',
      bodyText: 'Choose a category', listButtonText: 'View Categories',
      sections: interactiveListSections
    });
    return;
  }

  if (msg?.interactive?.type === 'list_reply') {
    const slug = msg.interactive.list_reply.id;
    const { sections } = await api('GET', `/catalogs/${catalogId}/product-list-payload?category=${slug}`);
    await api('POST', '/messages/product-list', {
      phoneNumberId, to: from, catalogId, sections,
      bodyText: `Browse ${msg.interactive.list_reply.title}`
    });
  }
}

Full reference: docs/INTEGRATOR_WHATSAPP_COMMERCE_REFERENCE.md §4.3

POST /catalogs/:catalogId/products — Push (create) a product

Add a new product to a catalog. The product is synced to Meta's catalog and saved in ChatYug.

Request Body:

FieldRequiredDescription
productNameProduct name (max 200 chars)
pricePrice in major units (e.g. 599 for ₹599; stored internally as smallest currency unit)
currencyCurrency code (default: INR)
retailerIdYour unique product SKU. Auto-generated if omitted.
descriptionProduct description
imageUrlHTTPS image URL (min 500×500px recommended)
productUrlProduct landing page URL
availabilityin stock (default) or out of stock
categoryBrowse category label (e.g. Dairy, Kitchen Appliances) — used for category picker flow
brandBrand name
inventoryStock count (integer)
For local_service vertical catalogs: availabilityAddressStreet, availabilityAddressCity, availabilityAddressState, availabilityAddressPostalCode, availabilityAddressCountry, availabilityLatitude, availabilityLongitude may be required.
cURL
curl -X POST https://chatyug.com/api/external/catalogs/980328057290841/products \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "productName": "Premium Cotton T-Shirt",
    "description": "100% cotton, comfortable fit",
    "price": 599,
    "currency": "INR",
    "retailerId": "TSHIRT-WHITE-M",
    "imageUrl": "https://example.com/tshirt.jpg",
    "productUrl": "https://example.com/products/tshirt",
    "availability": "in stock",
    "category": "Apparel & Accessories",
    "brand": "MyBrand",
    "inventory": 150
  }'

Response (201 Created):

JSON
{
  "success": true,
  "message": "Product created successfully",
  "data": {
    "productId": 101,
    "metaProductId": "5678901234567",
    "retailerId": "TSHIRT-WHITE-M",
    "productName": "Premium Cotton T-Shirt",
    "price": 599,
    "currency": "INR"
  }
}
PUT /catalogs/:catalogId/products/:retailerId — Update a product

Update product details (price, stock, name, etc.). Only include the fields you want to change.

cURL
curl -X PUT https://chatyug.com/api/external/catalogs/980328057290841/products/TSHIRT-WHITE-M \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "price": 499,
    "availability": "in stock",
    "inventory": 200
  }'

Response (200 OK):

JSON
{
  "success": true,
  "message": "Product updated successfully",
  "data": { "productId": 101, "retailerId": "TSHIRT-WHITE-M" }
}
POST /messages/product-list — Send catalog product list to customer

Send an interactive product list message. Customer can browse and add items to cart directly in WhatsApp. Pass either productRetailerIds[] (single section) or sections[] (multi-section / per-category).

cURL
curl -X POST https://chatyug.com/api/external/messages/product-list \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
    "to": "919876543210",
    "catalogId": "980328057290841",
    "sections": [
      {
        "title": "Dairy",
        "product_items": [
          { "product_retailer_id": "MILK-1L" },
          { "product_retailer_id": "YOGURT-500G" }
        ]
      }
    ],
    "headerText": "🛍️ Our Latest Collection",
    "bodyText": "Check out our top picks just for you!",
    "footerText": "Tap a product to add to cart"
  }'

Response (200 OK):

JSON
{
  "success": true,
  "message": "Product list message sent",
  "data": { "messageId": "wamid.HBgMOTE5ODc2NTQzMjEw..." }
}
POST /messages/single-product — Send single product to customer

Send a single product card. Ideal for upsells or highlighting a specific product.

cURL
curl -X POST https://chatyug.com/api/external/messages/single-product \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
    "to": "919876543210",
    "catalogId": "980328057290841",
    "productRetailerId": "TSHIRT-WHITE-M",
    "bodyText": "We thought you might love this! 😍"
  }'

Response (200 OK):

JSON
{
  "success": true,
  "message": "Single product message sent",
  "data": { "messageId": "wamid.HBgMOTE5ODc2NTQzMjEw..." }
}

🛒 Commerce Orders API

Manage WhatsApp Commerce orders — retrieve order details, update status through the full pipeline, add notes, and send customer notifications programmatically.

Order Status Pipeline: pendingconfirmedshippeddelivered (or cancelled). Setting a status automatically sends a WhatsApp notification to the customer unless you pass "notifyCustomer": false.
GET /orders — List all orders

Returns paginated orders for your WABA. Filter by status and date range.

Query Parameters:

ParameterTypeDescription
statusstringFilter by: pending, confirmed, shipped, delivered, cancelled
pageintegerPage number (default: 1)
pageSizeintegerResults per page (default: 20)
dateFromstringFilter from date (YYYY-MM-DD)
dateTostringFilter to date (YYYY-MM-DD)
dateFromUtcstringOptional ISO datetime (UTC) start bound
dateToUtcstringOptional ISO datetime (UTC) end bound
cURL
curl -X GET "https://chatyug.com/api/external/orders?status=pending&page=1&pageSize=20" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200 OK):

JSON
{
  "success": true,
  "total": 42,
  "page": 1,
  "pageSize": 20,
  "orders": [
    {
      "id": 101,
      "customer_phone": "919876543210",
      "customer_name": "Rahul Sharma",
      "status": "pending",
      "total_amount": "4999.00",
      "currency": "INR",
      "items_count": 2,
      "payment_method": null,
      "customer_note": "Please pack carefully",
      "created_at": "2025-04-07T10:30:00.000Z",
      "items": [
        { "product_retailer_id": "TSHIRT-WHITE-M", "quantity": 1, "item_price": "599", "currency": "INR" }
      ]
    }
  ]
}
GET /orders/:orderId — Get order details

Get complete details of a single order including all items, shipping address, and status history.

cURL
curl -X GET https://chatyug.com/api/external/orders/101 \
  -H "Authorization: Bearer YOUR_API_KEY"

Response (200 OK):

JSON
{
  "success": true,
  "order": {
    "id": 101,
    "customer_phone": "919876543210",
    "customer_name": "Rahul Sharma",
    "waba_id": "815098678039367",
    "meta_catalog_id": "980328057290841",
    "status": "confirmed",
    "total_amount": "4999.00",
    "currency": "INR",
    "items_count": 2,
    "payment_method": "cod",
    "customer_note": "Please pack carefully",
    "status_notes": "Order verified and packed",
    "notified_at": "2025-04-07T11:00:00.000Z",
    "flow_token": "order_1744012345_abc12",
    "created_at": "2025-04-07T10:30:00.000Z",
    "updated_at": "2025-04-07T11:00:00.000Z",
    "items": [
      { "product_retailer_id": "TSHIRT-WHITE-M", "quantity": 1, "item_price": "599", "currency": "INR" },
      { "product_retailer_id": "SHOES-001", "quantity": 1, "item_price": "4400", "currency": "INR" }
    ],
    "shipping_address": {
      "customer_name": "Rahul Sharma",
      "delivery_address": "12, MG Road",
      "city": "Bangalore",
      "pincode": "560001",
      "payment_method": "cod"
    }
  }
}
PUT /orders/:orderId/status — Update order status

Move an order through the pipeline. Automatically sends a WhatsApp status update to the customer (disable with "notifyCustomer": false).

Request Body:

FieldRequiredDescription
statusOne of: pending, confirmed, shipped, delivered, cancelled
noteInternal note / tracking info (included in customer notification)
notifyCustomertrue (default) to auto-send WhatsApp update, false to skip
cURL
# Confirm an order — customer gets "✅ Order Confirmed" WhatsApp message
curl -X PUT https://chatyug.com/api/external/orders/101/status \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "confirmed",
    "note": "Your order has been verified and is being packed.",
    "notifyCustomer": true
  }'

# Ship — attach tracking
curl -X PUT https://chatyug.com/api/external/orders/101/status \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "shipped",
    "note": "Tracking ID: DTDC123456789. Expected delivery: 3-5 days.",
    "notifyCustomer": true
  }'

Response (200 OK):

JSON
{
  "success": true,
  "message": "Order status updated to shipped",
  "notifySent": true
}
POST /orders/:orderId/note — Add a note to an order

Add an internal note to an order without changing its status. Useful for recording tracking numbers, packing details, etc.

cURL
curl -X POST https://chatyug.com/api/external/orders/101/note \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "note": "Customer requested gift wrapping. AWB: DTDC123456789"
  }'

Response (200 OK):

JSON
{ "success": true, "message": "Note added to order" }
POST /orders/:orderId/notify — Send order update to customer

Send a custom WhatsApp message to the customer about their order. Omit message to use the default status-based message.

cURL
# With custom message
curl -X POST https://chatyug.com/api/external/orders/101/notify \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "🚚 Your order #101 has been dispatched!\n\nTracking: DTDC123456789\nEstimated delivery: Apr 10–12\n\nTrack here: https://track.dtdc.com/123456789"
  }'

# Default status-based message (omit message field)
curl -X POST https://chatyug.com/api/external/orders/101/notify \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Response (200 OK):

JSON
{
  "success": true,
  "message": "Notification sent to customer",
  "messageId": "wamid.HBgMOTE5ODc2NTQzMjEw..."
}
Common Error Responses
HTTP CodeMeaningExample
401UnauthorizedMissing or invalid API key
400Bad RequestMissing required field / invalid status value
404Not FoundOrder or catalog does not exist / not accessible
500Server ErrorInternal error — check message field
JSON
{ "success": false, "message": "status must be one of: pending, confirmed, shipped, delivered, cancelled" }

🔔 Outbound Webhooks

ChatYug pushes real-time events to your HTTPS endpoint when customers message you, when delivery status changes, and when cart orders arrive. Configure in Webhook Settings.

Headers: X-Chatyug-Event-Id, X-Chatyug-Signature (HMAC-SHA256 when secret is set). Use eventId for idempotency.

Event types

eventTypeWhen fired
messageCustomer sends text, media, button/list reply, or WhatsApp Flow submission (nfm_reply)
statusMessage sent / delivered / read / failed
orderCustomer submits a WhatsApp cart order
testSent from Webhook Settings → Send Test Event

Sample: inbound message (button reply)

JSON
{
  "eventType": "message",
  "userId": 34,
  "wabaId": "1957290828491918",
  "phoneNumberId": "1079034885291122",
  "eventId": "wamid.HBgM....",
  "occurredAt": "2026-06-23T10:10:00.000Z",
  "data": {
    "metadata": { "phone_number_id": "1079034885291122" },
    "contacts": [{ "profile": { "name": "Rahul" }, "wa_id": "919876543210" }],
    "message": {
      "id": "wamid....",
      "type": "interactive",
      "interactive": {
        "type": "button_reply",
        "button_reply": { "id": "DIST_01", "title": "Distributor A" }
      }
    }
  }
}

Sample: delivery status

JSON
{
  "eventType": "status",
  "eventId": "wamid.HBgM....",
  "data": {
    "status": { "id": "wamid....", "status": "delivered", "timestamp": "1719156600", "recipient_id": "919876543210" }
  }
}

Sample: cart order

JSON
{
  "eventType": "order",
  "data": {
    "order": {
      "catalog_id": "980328057290841",
      "product_items": [{ "product_retailer_id": "TSHIRT-WHITE-M", "quantity": 2, "item_price": 599, "currency": "INR" }]
    }
  }
}

See Delivery & Retry Policy below for automatic retry behaviour and handler requirements.

Delivery & Retry Policy

48-hour automatic retry window: If your server is temporarily down, ChatYug keeps the event and retries delivery for up to 48 hours from when the event was received. Events are not lost immediately — they are queued and retried until your endpoint returns HTTP 2xx or the 48-hour window expires.

Retry backoff schedule

After each failed attempt (non-2xx HTTP response, 8-second timeout, or network/DNS error), ChatYug waits before the next attempt:

After failed attemptWait before next try
11 minute
22 minutes
310 minutes
460 minutes
5 and later360 minutes (6 hours)

This typically results in ~12–13 delivery attempts over the 48-hour window. After 48 hours without a successful delivery, the event is marked failed in ChatYug's delivery log. Contact ChatYug support if you need help recovering missed events.

Required handler pattern

  1. Verify X-Chatyug-Signature on the raw request body (if a secret is configured).
  2. Check eventId (or X-Chatyug-Event-Id header) against your processed-events store; skip if already handled.
  3. Return HTTP 200 (or any 2xx) immediately — within 8 seconds.
  4. Process the event asynchronously in your own queue or background worker.
Idempotency: The same eventId may be delivered more than once during retries (e.g. your server times out after processing but before returning 2xx). Always deduplicate on eventId.

Other delivery limits

SettingValue
HTTP timeout per attempt8 seconds
Rate limit300 events per minute per WABA
AcknowledgementReturn HTTP 2xx to stop retries for that event

Full troubleshooting guide: Webhook Retry & Troubleshooting

🔄 WhatsApp Commerce Flows API

Create checkout Flows (customer details form), publish them, and send Flow messages. Requires Commerce Settings with flow endpoint URL configured in the portal.

GET /commerce/flows
curl -X GET https://chatyug.com/api/external/commerce/flows -H "Authorization: Bearer YOUR_API_KEY"
POST /commerce/flows — Create flow
curl -X POST https://chatyug.com/api/external/commerce/flows \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Checkout Form", "category": "SHOPPING", "flowJson": { "version": "7.3", "screens": [] }}'
POST /commerce/flows/:flowId/publish
curl -X POST https://chatyug.com/api/external/commerce/flows/12/publish \
  -H "Authorization: Bearer YOUR_API_KEY"
POST /messages/flow — Send Flow message

Flow responses arrive on your webhook as message events with interactive.type: nfm_reply.

curl -X POST https://chatyug.com/api/external/messages/flow \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
    "to": "919876543210",
    "flowId": "META_FLOW_ID",
    "headerText": "Complete your order",
    "bodyText": "Fill in delivery details",
    "ctaText": "Proceed"
  }'

🤖 Chatbot Automation Flows API

Keyword-triggered automation flows. Requires automation permission on the WABA. Incoming keywords are delivered via the message webhook — your system matches keywords and drives the journey.

GET /chatbot/flows
curl -X GET "https://chatyug.com/api/external/chatbot/flows?published=true" \
  -H "Authorization: Bearer YOUR_API_KEY"
POST /chatbot/flows
curl -X POST https://chatyug.com/api/external/chatbot/flows \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "flowName": "Shop keyword",
    "triggerKeywords": "SHOP,CATALOGUE",
    "flowData": { "nodes": [], "edges": [] }
  }'
GET /chatbot/flows/:flowId
curl -X GET https://chatyug.com/api/external/chatbot/flows/42 -H "Authorization: Bearer YOUR_API_KEY"
PUT /chatbot/flows/:flowId
curl -X PUT https://chatyug.com/api/external/chatbot/flows/42 \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"flowName": "Updated name", "isActive": true}'

🔗 Integrator API — Inbound + Session Messaging

Endpoints for third-party platforms that receive inbound webhooks and need to read conversations, send interactive replies (buttons/lists), and fetch inbound media URLs.

24-hour session: Text and interactive messages require an open customer service window. List endpoints include session.sessionOpen based on the last inbound customer message.
GET /me — Account context
curl -X GET https://chatyug.com/api/external/me \
  -H "Authorization: Bearer YOUR_API_KEY"
POST /messages/interactive — Button or list reply

interactiveType: button (1–3 buttons) or list (sections with rows). Use within 24h of customer message. For category browse, pass sections from GET /catalogs/:id/categoriesinteractiveListSections.

curl -X POST https://chatyug.com/api/external/messages/interactive \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
    "to": "917016793529",
    "interactiveType": "list",
    "headerText": "Shop by Category",
    "bodyText": "Choose a category to browse products",
    "listButtonText": "View Categories",
    "sections": [
      {
        "title": "Categories",
        "rows": [
          { "id": "cat_dairy", "title": "Dairy", "description": "3 products" },
          { "id": "cat_kitchen_appliances", "title": "Kitchen Appliances", "description": "5 products" }
        ]
      }
    ]
  }'

Customer reply arrives as webhook interactive.list_reply with id = category slug.

curl -X POST https://chatyug.com/api/external/messages/interactive \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumberId": "YOUR_PHONE_NUMBER_ID",
    "to": "917016793529",
    "interactiveType": "button",
    "bodyText": "Choose distributor",
    "buttons": [
      { "id": "DIST_A", "title": "Distributor A" },
      { "id": "DIST_B", "title": "Distributor B" }
    ]
  }'
GET /conversations — List conversations
curl -X GET "https://chatyug.com/api/external/conversations?phoneNumberId=YOUR_PHONE_NUMBER_ID&page=1&pageSize=50" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET /conversations/:id/messages — Message history
curl -X GET "https://chatyug.com/api/external/conversations/12345/messages?limit=100&offset=0" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET /messages/:messageId/media — Inbound media URL

Returns a stable ChatYug URL for inbound/outbound attachments. If only a Meta media ID is stored, ChatYug downloads and persists under /received_media/. Do not use expired Meta lookaside CDN links.

curl -X GET https://chatyug.com/api/external/messages/98765/media \
  -H "Authorization: Bearer YOUR_API_KEY"

MCP / AI Assistants

Use ChatYug MCP so an AI assistant can help you run WhatsApp Messaging and CRM from conversation — without opening every screen yourself. Generate a token in the MCP Tokens section above. Full guide: ChatYug MCP help.

What you can ask an assistant to do

  • Find or export contacts, update names and labels, manage contact groups
  • Send text, template, or media messages; check delivery status
  • Open recent conversations and review message history
  • Import contacts carefully (ChatYug asks you to confirm bulk changes first)

Credentials (same for every client)

  • URL: https://mcp.chatyug.com/mcp
  • Header: Authorization: Bearer mcp_… (include Bearer and a space)
  • Never put the token in the Name field, the URL, or OAuth Client ID / Secret

Where to enter the token by client

Client Where the token goes
Claude Add URL https://mcp.chatyug.com/mcp, leave OAuth Client ID/Secret empty, click Connect, then sign in with ChatYug and Allow. For attached images: allowlist mcp.chatyug.com under Capabilities → Code execution (or use the browser upload link Claude provides). Optional: Request headers / Claude Code with Bearer mcp_….
ChatGPT Custom connector with the same URL. Prefer OAuth / sign-in if offered; otherwise Bearer mcp_….
Gemini Web Connected Apps: URL https://mcp.chatyug.com/mcp → Copy redirect URI → create Client ID/Secret at https://mcp.chatyug.com/oauth/gemini-setup → paste into Advanced settings → ChatYug login. CLI: Bearer mcp_… header.
Other MCP clients Same URL; OAuth Connect when supported, otherwise Authorization Bearer header.
Step-by-step for each client: documentation. Claude’s Custom Connector may require a paid Claude subscription.

Plans and safety

Trial plans are read-only. Monthly and Annual plans can send messages and update CRM data as allowed. Never share your token in chat or email. Revoke it on this page if it is exposed.

ChatYug is a Meta-approved Business Solution Provider (BSP). Your MCP token only works for the WhatsApp Business Account linked to its parent API key.

Code Examples

Complete code examples in multiple programming languages:

PHP Example:

PHP
 '719142414620783',
    'to' => '919876543210',
    'type' => 'template',
    'templateName' => 'order_confirmation',
    'templateLanguage' => 'en',
    'templateVariables' => ['John Doe', 'ORD-12345', '₹1,299']
];

$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $apiKey,
    'Content-Type: application/json'
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$result = json_decode($response, true);

if ($httpCode === 200 && $result['success']) {
    echo "Message sent! ID: " . $result['data']['messageId'];
} else {
    echo "Error: " . $result['message'];
}
?>

Python Example:

Python
import requests

api_key = "YOUR_API_KEY"
url = "https://chatyug.com/api/external/send-message"

headers = {
    "Authorization": f"Bearer {api_key}",
    "Content-Type": "application/json"
}

payload = {
    "phoneNumberId": "719142414620783",
    "to": "917016793529",
    "type": "template",
    "templateName": "order_confirmation",
    "templateLanguage": "en",
    "templateVariables": ["John Doe", "ORD-12345", "₹1,299"]
}

response = requests.post(url, headers=headers, json=payload)

if response.status_code == 200:
    result = response.json()
    print(f"Message sent! ID: {result['data']['messageId']}")
else:
    print(f"Error: {response.text}")

Node.js Example:

JavaScript
const axios = require('axios');

const apiKey = 'YOUR_API_KEY';
const url = 'https://chatyug.com/api/external/send-message';

const payload = {
    phoneNumberId: '719142414620783',
    to: '919876543210',
    type: 'template',
    templateName: 'order_confirmation',
    templateLanguage: 'en',
    templateVariables: ['John Doe', 'ORD-12345', '₹1,299']
};

axios.post(url, payload, {
    headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
    }
})
.then(response => {
    console.log('Message sent!', response.data.data.messageId);
})
.catch(error => {
    console.error('Error:', error.response?.data?.message || error.message);
});

C# (.NET) Example:

C#
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

var apiKey = "YOUR_API_KEY";
var url = "https://chatyug.com/api/external/send-message";

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");

var payload = new
{
    phoneNumberId = "719142414620783",
    to = "919876543210",
    type = "template",
    templateName = "order_confirmation",
    templateLanguage = "en",
    templateVariables = new[] { "John Doe", "ORD-12345", "₹1,299" }
};

var json = JsonSerializer.Serialize(payload);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await httpClient.PostAsync(url, content);
var responseBody = await response.Content.ReadAsStringAsync();

if (response.IsSuccessStatusCode)
{
    Console.WriteLine("Message sent!");
    Console.WriteLine(responseBody);
}
else
{
    Console.WriteLine($"Error: {responseBody}");
}