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

# Open a new ticket for web whatsapp

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

| Parameter | Type   | Required | Description                                                |
| --------- | ------ | -------- | ---------------------------------------------------------- |
| `phoneId` | string | Yes      | Your WhatsApp Web phone identifier (connected via QR code) |

## Request Body

| Field              | Type   | Required | Description                                               |
| ------------------ | ------ | -------- | --------------------------------------------------------- |
| `to_phone_number`  | string | Yes      | Contact's WhatsApp phone number (with country code)       |
| `stage_id`         | string | Yes      | UUID of the pipeline stage where the ticket should start  |
| `contact_name`     | string | No       | Full name of the contact                                  |
| `email`            | string | No       | Contact's email address (must be valid email format)      |
| `contact_metadata` | object | No       | Custom key-value pairs for contact-level data             |
| `ticket_metadata`  | object | No       | Custom key-value pairs for ticket-level data              |
| `integration_data` | object | No       | Integration-specific data (e.g., external system IDs)     |
| `message`          | object | No       | Optional initial message to send when creating the ticket |

### Message Object

When providing an initial message, use this structure:

| Field          | Type    | Required | Description                                          |
| -------------- | ------- | -------- | ---------------------------------------------------- |
| `content`      | string  | No       | Text content of the message to send                  |
| `templateId`   | string  | No       | ID of a template to use (if using smart templates)   |
| `ai_generated` | boolean | Yes      | Whether the message is AI-generated (true) or manual |

## Response Structure

The endpoint returns a success response with the created contact information:

| Field         | Type          | Description                                          |
| ------------- | ------------- | ---------------------------------------------------- |
| `aiContactId` | string (UUID) | Unique identifier of the created or existing contact |
| `status`      | string        | Status of the operation (always "ok")                |

## Example Request

```bash theme={null}
curl --request POST \
  'https://api.vambe.me/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

```json theme={null}
{
  "aiContactId": "df980fc8-b6db-4820-bf22-2969482d106d",
  "status": "ok"
}
```

## Common Use Cases

### 1. Create Ticket from Contact Form

```javascript theme={null}
const createTicketFromForm = async (formData) => {
  const response = await fetch(
    'https://api.vambe.me/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

```javascript theme={null}
const createOrderTicket = async (order) => {
  const response = await fetch(
    'https://api.vambe.me/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

```javascript theme={null}
const escalateToSupport = async (customerId, issue) => {
  const response = await fetch(
    'https://api.vambe.me/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

```javascript theme={null}
// Let the AI assistant handle the first message based on pipeline configuration
const createSilentTicket = async (phone, stageId) => {
  const response = await fetch(
    'https://api.vambe.me/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

```javascript theme={null}
const createTicketWithTemplate = async (contact, templateId) => {
  const response = await fetch(
    'https://api.vambe.me/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 Code | Description                                    |
| ----------- | ---------------------------------------------- |
| 400         | Bad Request - Invalid phone number or stage ID |
| 401         | Unauthorized - Invalid or missing API key      |
| 404         | Not Found - Phone ID or stage ID doesn't exist |
| 500         | Internal 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](/reference/publicpipeline/get-pipelines) 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

## Related Endpoints

* [GET /api/public/pipeline](/reference/publicpipeline/get-pipelines) - Get available pipeline stages
* [GET /api/public/contact/{aiContactId}/info](/reference/contact/get-info-of-an-ai-contact) - Get ticket and contact info
* [POST /api/public/contact/{aiContactId}/update-metadata](#) - Update contact metadata later
* [POST /api/public/ticket/close/contact/{contactId}](#) - Close an active ticket


## OpenAPI

````yaml post /api/public/ticket/open/web-whatsapp/{phoneId}
openapi: 3.0.0
info:
  title: Vambe AI API
  description: Vambe AI documentation
  version: '1.0'
  contact: {}
servers:
  - url: https://api.vambe.me
    description: Production Server
security: []
tags:
  - name: Vambe AI
    description: ''
paths:
  /api/public/ticket/open/web-whatsapp/{phoneId}:
    post:
      tags:
        - Ticket
      summary: Open a new ticket for web whatsapp
      operationId: CreateTicketPublicController_openTicket
      parameters:
        - name: phoneId
          required: true
          in: path
          schema:
            type: string
        - name: x-api-key
          in: header
          description: API key needed to authorize the request
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OpenTicketDto'
      responses:
        '200':
          description: Ticket created successfully
components:
  schemas:
    OpenTicketDto:
      type: object
      properties:
        contact_name:
          type: string
        to_phone_number:
          anyOf:
            - type: number
              minimum: 1
            - type: string
        contact_metadata:
          default: {}
          type: object
          additionalProperties: true
        ticket_metadata:
          default: {}
          type: object
          additionalProperties: true
        integration_data:
          type: object
          additionalProperties: true
        email:
          type: string
          format: email
          pattern: >-
            ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$
        message:
          type: object
          properties:
            templateId:
              type: string
            content:
              type: string
            ai_generated:
              type: boolean
        stage_id:
          type: string
      required:
        - to_phone_number
        - contact_metadata
        - ticket_metadata
        - integration_data
        - message
        - stage_id

````