POST
/
api
/
public
/
ticket
/
open
/
web-whatsapp
/
{phoneId}
Open a new ticket for web whatsapp
curl --request POST \
  --url https://api.vambe.me/api/public/ticket/open/web-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 Web (QR) 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 is ideal for programmatically creating tickets when a customer takes a specific action on your platform (e.g., form submission, purchase, support request).

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
phoneIdstringYesYour WhatsApp Web phone identifier (connected via QR code)

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/web-whatsapp/your_phone_id' \
  --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/web-whatsapp/your_phone_id',
    {
      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/web-whatsapp/your_phone_id',
    {
      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. Support Escalation

const escalateToSupport = async (customerId, issue) => {
  const response = await fetch(
    'https://api.vambe.ai/api/public/ticket/open/web-whatsapp/your_phone_id',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': 'your_api_key_here',
      },
      body: JSON.stringify({
        to_phone_number: customerId.phone,
        stage_id: 'your_support_stage_id',
        contact_name: customerId.name,
        email: customerId.email,
        ticket_metadata: {
          escalation_reason: issue.reason,
          priority: 'urgent',
          original_system: issue.source,
          escalated_at: new Date().toISOString(),
        },
        message: {
          content: `Hola ${customerId.name}, hemos escalado tu caso a soporte técnico. Un agente te contactará pronto.`,
          ai_generated: false,
        },
      }),
    },
  );

  return await response.json();
};

4. 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/web-whatsapp/your_phone_id',
    {
      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();
};

5. Using Smart Templates

const createTicketWithTemplate = async (contact, templateId) => {
  const response = await fetch(
    'https://api.vambe.ai/api/public/ticket/open/web-whatsapp/your_phone_id',
    {
      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 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 or stage ID doesn’t exist
500Internal Server Error - Something went wrong

Important Notes

  • Phone ID Requirement: The phoneId in the path must be a WhatsApp Web connection that you’ve set up via QR code
  • Stage ID: Make sure the stage_id exists in your pipelines - use the GET /api/public/pipeline endpoint 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. Contact Creation/Update: The system finds or creates a contact with the provided phone number
  2. Metadata Processing: Contact and ticket metadata are processed and stored
  3. Stage Assignment: The ticket is placed in the specified pipeline stage
  4. Message Sending (if provided):
    • If message.content is provided without templateId: Sends a plain text message
    • If message.templateId is provided: Sends a smart template with variables
    • If no message: AI assistant takes over based on pipeline configuration
  5. Contact ID Return: You receive the aiContactId to track this contact for future operations

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