POST
/
api
/
public
/
ticket
/
open
/
whatsapp
/
{phoneId}
Open a new ticket for whatsapp
curl --request POST \
  --url https://api.vambe.me/api/public/ticket/open/whatsapp/{phoneId} \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: <x-api-key>' \
  --data '{
  "to_phone_number": 2,
  "contact_metadata": {},
  "ticket_metadata": {},
  "integration_data": {},
  "message": {
    "templateId": "<string>",
    "content": "<string>",
    "ai_generated": true
  },
  "stage_id": "<string>"
}'

Overview

Create a new support ticket for a WhatsApp Business API contact. This endpoint initializes a conversation in a specific pipeline stage, optionally sends an initial message, and allows you to set custom metadata for both the contact and ticket. This endpoint is specifically for WhatsApp Business API connections (not WhatsApp Web/QR). Use this when you have an official WhatsApp Business API integration.

Use Cases

  • Form-triggered Tickets: Create a ticket when a user submits a contact form
  • E-commerce Integration: Open tickets for new orders or delivery issues
  • Onboarding Workflows: Start onboarding tickets for new customers
  • Support Escalation: Programmatically create tickets from other systems
  • Event-based Tickets: Create tickets based on user behavior or triggers
  • CRM Synchronization: Sync customer issues from external CRM to Vambe

Authentication

This endpoint requires authentication using an API key. Include your API key in the request header:
x-api-key: your_api_key_here

Path Parameters

ParameterTypeRequiredDescription
phoneIdnumber/stringYesYour WhatsApp Business API phone ID (numeric)
WhatsApp Business API: The phoneId must be a numeric ID from your WhatsApp Business API configuration. This is different from WhatsApp Web (QR) which uses string identifiers.

Request Body

FieldTypeRequiredDescription
to_phone_numberstringYesContact’s WhatsApp phone number (with country code)
stage_idstringYesUUID of the pipeline stage where the ticket should start
contact_namestringNoFull name of the contact
emailstringNoContact’s email address (must be valid email format)
contact_metadataobjectNoCustom key-value pairs for contact-level data
ticket_metadataobjectNoCustom key-value pairs for ticket-level data
integration_dataobjectNoIntegration-specific data (e.g., external system IDs)
messageobjectNoOptional initial message to send when creating the ticket

Message Object

When providing an initial message, use this structure:
FieldTypeRequiredDescription
contentstringNoText content of the message to send
templateIdstringNoID of a template to use (if using smart templates)
ai_generatedbooleanYesWhether the message is AI-generated (true) or manual

Response Structure

The endpoint returns a success response with the created contact information:
FieldTypeDescription
aiContactIdstring (UUID)Unique identifier of the created or existing contact
statusstringStatus of the operation (always β€œok”)

Example Request

curl --request POST \
  'https://api.vambe.ai/api/public/ticket/open/whatsapp/123456789' \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: your_api_key_here' \
  --data-raw '{
    "to_phone_number": "+56912345678",
    "stage_id": "550e8400-e29b-41d4-a716-446655440000",
    "contact_name": "Maria Rodriguez",
    "email": "maria.rodriguez@example.com",
    "contact_metadata": {
      "company": "Acme Corp",
      "plan": "Premium",
      "source": "website_form"
    },
    "ticket_metadata": {
      "issue_type": "billing",
      "priority": "high",
      "order_id": "ORD-12345"
    },
    "message": {
      "content": "Hola Maria! Hemos recibido tu consulta sobre facturaciΓ³n. ΒΏEn quΓ© podemos ayudarte?",
      "ai_generated": false
    }
  }'

Example Response

{
  "aiContactId": "df980fc8-b6db-4820-bf22-2969482d106d",
  "status": "ok"
}

Common Use Cases

1. Create Ticket from Contact Form

const createTicketFromForm = async (formData) => {
  const response = await fetch(
    'https://api.vambe.ai/api/public/ticket/open/whatsapp/123456789',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': 'your_api_key_here',
      },
      body: JSON.stringify({
        to_phone_number: formData.phone,
        stage_id: 'your_initial_stage_id',
        contact_name: formData.name,
        email: formData.email,
        contact_metadata: {
          form_source: 'contact_page',
          submission_date: new Date().toISOString(),
        },
        ticket_metadata: {
          subject: formData.subject,
          message: formData.message,
        },
        message: {
          content: `Hola ${formData.name}! Hemos recibido tu mensaje y te responderemos pronto.`,
          ai_generated: false,
        },
      }),
    },
  );

  const result = await response.json();
  console.log('Ticket created for contact:', result.aiContactId);
  return result;
};

2. E-commerce Order Ticket

const createOrderTicket = async (order) => {
  const response = await fetch(
    'https://api.vambe.ai/api/public/ticket/open/whatsapp/123456789',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': 'your_api_key_here',
      },
      body: JSON.stringify({
        to_phone_number: order.customerPhone,
        stage_id: 'your_orders_stage_id',
        contact_name: order.customerName,
        email: order.customerEmail,
        contact_metadata: {
          customer_since: order.accountCreatedDate,
          lifetime_value: order.lifetimeValue.toString(),
        },
        ticket_metadata: {
          order_id: order.id,
          order_total: order.total.toString(),
          items: order.items.length.toString(),
          payment_method: order.paymentMethod,
        },
        integration_data: {
          shopify_order_id: order.shopifyId,
          tracking_number: order.trackingNumber,
        },
        message: {
          content: `Β‘Hola ${order.customerName}! Tu pedido #${order.id} ha sido confirmado y serΓ‘ enviado pronto. Total: $${order.total}`,
          ai_generated: false,
        },
      }),
    },
  );

  return await response.json();
};

3. Create Ticket Without Initial Message

// Let the AI assistant handle the first message based on pipeline configuration
const createSilentTicket = async (phone, stageId) => {
  const response = await fetch(
    'https://api.vambe.ai/api/public/ticket/open/whatsapp/123456789',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': 'your_api_key_here',
      },
      body: JSON.stringify({
        to_phone_number: phone,
        stage_id: stageId,
        // No message object - AI will handle first contact
      }),
    },
  );

  return await response.json();
};

4. Using Smart Templates

const createTicketWithTemplate = async (contact, templateId) => {
  const response = await fetch(
    'https://api.vambe.ai/api/public/ticket/open/whatsapp/123456789',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': 'your_api_key_here',
      },
      body: JSON.stringify({
        to_phone_number: contact.phone,
        stage_id: 'your_stage_id',
        contact_name: contact.name,
        message: {
          templateId: templateId,
          content: contact.name, // Template variable
          ai_generated: false,
        },
      }),
    },
  );

  return await response.json();
};

Phone ID Requirements

The phoneId in the path must be a numeric ID from your WhatsApp Business API configuration. This is NOT the phone number itself.
Examples:
  • βœ… Correct: 123456789 (numeric phone ID from WhatsApp Business API)
  • ❌ Incorrect: "+56912345678" (this is the customer’s phone number, not your phone ID)
  • ❌ Incorrect: "my-phone-id" (string identifier - use web-whatsapp endpoint instead)
To get your phone ID:
  1. Check your WhatsApp Business API configuration
  2. Look in your Vambe dashboard under WhatsApp channels
  3. The phone ID is a numeric value assigned by WhatsApp

Phone Number Format

The to_phone_number field accepts phone numbers in various formats:
  • With country code: "+56912345678" (recommended)
  • String format: "56912345678"
  • Number format: 56912345678
The system automatically strips non-numeric characters and validates the number.

Metadata Best Practices

Contact Metadata

Store information about the person:
  • Company name
  • Industry
  • Customer tier/plan
  • Account creation date
  • Language preference
  • Time zone

Ticket Metadata

Store information about this specific ticket:
  • Issue type/category
  • Priority level
  • Related order/transaction IDs
  • Urgency
  • Source (web, mobile, API, etc.)
  • Custom fields specific to your workflow

Error Responses

Status CodeDescription
400Bad Request - Invalid phone number or stage ID
401Unauthorized - Invalid or missing API key
404Not Found - Phone ID doesn’t exist or is not numeric
500Internal Server Error - Something went wrong

Important Notes

  • Phone ID Must Be Numeric: The phoneId parameter must be a number, not a string identifier
  • WhatsApp Business API Only: This endpoint is for official WhatsApp Business API connections
  • For WhatsApp Web: Use POST /api/public/ticket/open/web-whatsapp/{phoneId} instead
  • Stage ID: Make sure the stage_id exists in your pipelines - use GET /api/public/pipeline to get valid stage IDs
  • Duplicate Contacts: If a contact with the same phone number already exists, the ticket will be created for that existing contact
  • Metadata Flexibility: Both contact_metadata and ticket_metadata accept any key-value pairs as objects
  • AI Processing: When you don’t provide a message, the AI assistant will automatically engage based on your pipeline configuration
  • Message vs Template: You can provide either plain content or use a templateId with variables

What Happens After Creation

  1. Phone ID Validation: System verifies the phone ID is numeric and exists
  2. Contact Creation/Update: The system finds or creates a contact with the provided phone number
  3. Metadata Processing: Contact and ticket metadata are processed and stored
  4. Stage Assignment: The ticket is placed in the specified pipeline stage
  5. Message Sending (if provided):
    • If message.content is provided without templateId: Sends a plain text message via WhatsApp Business API
    • If message.templateId is provided: Sends a WhatsApp approved template with variables
    • If no message: AI assistant takes over based on pipeline configuration
  6. Contact ID Return: You receive the aiContactId to track this contact for future operations

WhatsApp Business API vs WhatsApp Web

FeatureWhatsApp Business API (This)WhatsApp Web (QR)
Endpoint/api/public/ticket/open/whatsapp//api/public/ticket/open/web-whatsapp/
Phone ID FormatNumeric (e.g., 123456789)String (e.g., "phone_abc123")
Connection TypeOfficial API from MetaQR code connection
Message TypesTemplates and plain textPlain text only
ReliabilityHigher (official API)Depends on QR connection
ScalabilityBetter for high volumeLimited by QR session

Complete Workflow Example

// Complete workflow: Search contact, create ticket if needed
const createOrUpdateTicket = async (customerData) => {
  // 1. Search if contact already exists
  const searchResponse = await fetch(
    `https://api.vambe.ai/api/public/contacts/search?phone=${encodeURIComponent(customerData.phone)}`,
    {
      headers: {
        'x-api-key': 'your_api_key_here',
      },
    },
  );

  const existingContacts = await searchResponse.json();

  if (existingContacts.length > 0) {
    console.log('Contact exists, creating new ticket');
    // Contact exists - just create new ticket with updated metadata
  } else {
    console.log('New contact - creating first ticket');
  }

  // 2. Create ticket (works for both new and existing contacts)
  const ticketResponse = await fetch(
    'https://api.vambe.ai/api/public/ticket/open/whatsapp/123456789',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': 'your_api_key_here',
      },
      body: JSON.stringify({
        to_phone_number: customerData.phone,
        stage_id: 'your_stage_id',
        contact_name: customerData.name,
        email: customerData.email,
        contact_metadata: {
          company: customerData.company,
          updated_at: new Date().toISOString(),
        },
        ticket_metadata: {
          ticket_type: customerData.inquiryType,
          source: 'api',
        },
        message: {
          content: `Hola ${customerData.name}! Gracias por contactarnos.`,
          ai_generated: false,
        },
      }),
    },
  );

  const result = await ticketResponse.json();
  console.log('Ticket created:', result.aiContactId);

  return result;
};

Headers

x-api-key
string
required

API key needed to authorize the request

Path Parameters

phoneId
string
required

Body

application/json
to_phone_number
required
Required range: x >= 1
contact_metadata
object
required
ticket_metadata
object
required
integration_data
object
required
message
object
required
stage_id
string
required
contact_name
string
email
string<email>

Response

200

Ticket created successfully