# Introduction
Source: https://api.lancepilot.com/index
Meet the Worldβs First WhatsApp Cold Outreach Tool! Integrate WhatsApp messaging into your CRM, marketing tools, or custom applications for streamlined communication and improved conversions.
# Welcome to LancePilot V3 API Documentation
LancePilot revolutionizes your cold outreach strategy by leveraging the power of WhatsApp for highly targeted and engaging campaign execution. With our RESTful API, you can easily integrate WhatsApp messaging into your CRM, marketing tools, or custom applications to streamline communication and boost conversions.
LancePilot empowers businesses to automate, personalize, and manage their outreach campaigns at scale. Whether you're looking to send bulk messages, manage contacts, or orchestrate complex campaign sequences, our API provides robust endpoints and flexible integration options.
## What You Can Do with LancePilot API
* **Send automated cold outreach messages via WhatsApp**
* **Personalize messages dynamically using contact data**
* **Manage contact lists and campaign schedules**
* **Connect and manage channels and wallets**
* **Create and manage contact-group lists**
* **Import contact files**
* **Send template messages**
* **Create and manage users**
* **Create and manage user roles**
* **Create and manage sequences**
## Getting Started
To use the LancePilot API, youβll need:
* An active LancePilot account
* An API key (found in your dashboard under Settings > API)
Include your API key in the headers of each request:
**Base URL:**\
`http://lancepilot.com/api/v3`
Include your API key in the request headers as follows:
# Get Channel
Source: https://api.lancepilot.com/pages/endpoints/channel/get
GET /workspaces/{workspace}/channel
Retrieve the channel for the specified workspace.
# Get Conversations
Source: https://api.lancepilot.com/pages/endpoints/channel/wallet/conversation
GET /workspaces/{workspace}/channel/wallet/conversations
Retrieve the conversation list for the specified workspace's wallet.
# Download Invoice
Source: https://api.lancepilot.com/pages/endpoints/channel/wallet/invoice
GET /workspaces/{workspace}/channel/wallet/transactions/{transaction}/invoice
Download the invoice for a specific wallet transaction as a PDF file.
# Refresh Wallet
Source: https://api.lancepilot.com/pages/endpoints/channel/wallet/refresh
POST /workspaces/{workspace}/channel/wallet/refresh
Refresh the wallet channel for the specified workspace.
# Get Transactions
Source: https://api.lancepilot.com/pages/endpoints/channel/wallet/transactions
GET /workspaces/{workspace}/channel/wallet/transactions
Retrieve wallet transactions for the specified workspace.
# Get Transfer List
Source: https://api.lancepilot.com/pages/endpoints/channel/wallet/transfer
GET /workspaces/{workspace}/channel/wallet/transfer
Retrieve wallet transfer details for the specified workspace.
# Add Contact Field
Source: https://api.lancepilot.com/pages/endpoints/contact-field/add
POST /workspaces/{workspace}/contact-fields
Create a new contact field in the specified workspace.
# Delete Contact Field
Source: https://api.lancepilot.com/pages/endpoints/contact-field/delete
DELETE /workspaces/{workspace}/contact-fields/{contact-field}
Delete a contact field by ID.
# Get Contact Field
Source: https://api.lancepilot.com/pages/endpoints/contact-field/get
GET /workspaces/{workspace}/contact-fields/{contact-field}
Retrieve a specific contact field by ID.
# Get Contact Fields
Source: https://api.lancepilot.com/pages/endpoints/contact-field/list
GET /workspaces/{workspace}/contact-fields
Retrieve all contact fields for a workspace.
# Update Contact Field
Source: https://api.lancepilot.com/pages/endpoints/contact-field/update
PUT /workspaces/{workspace}/contact-fields/{contact-field}
Update an existing contact field in the specified workspace.
# Add Contact Group
Source: https://api.lancepilot.com/pages/endpoints/contact-group/add
POST /workspaces/{workspace}/contact-groups
Create a new contact group in the specified workspace.
# Delete Contact Group
Source: https://api.lancepilot.com/pages/endpoints/contact-group/delete
DELETE /workspaces/{workspace}/contact-groups/{contact-group}
Delete a contact group by ID.
# Get Contact Group
Source: https://api.lancepilot.com/pages/endpoints/contact-group/get
GET /workspaces/{workspace}/contact-groups/{contact-group}
Retrieve a specific contact group by ID.
# Get Contact Groups
Source: https://api.lancepilot.com/pages/endpoints/contact-group/list
GET /workspaces/{workspace}/contact-groups
Retrieve all contact groups for a workspace.
# Update Contact Group
Source: https://api.lancepilot.com/pages/endpoints/contact-group/update
PUT /workspaces/{workspace}/contact-groups/{contact-group}
Update an existing contact group in the specified workspace.
# Add Contact Import
Source: https://api.lancepilot.com/pages/endpoints/contact-import/add
POST /workspaces/{workspace}/contact-imports
Create a new contact import in the specified workspace.
# Delete Contact Import
Source: https://api.lancepilot.com/pages/endpoints/contact-import/delete
DELETE /workspaces/{workspace}/contact-imports/{contact-import}
Delete a contact import by ID in the specified workspace.
# Download Contact Import
Source: https://api.lancepilot.com/pages/endpoints/contact-import/download
GET /workspaces/{workspace}/contact-imports/{contact-import}/download
Download the file of a specific contact import as a CSV file.
# Get Contact Import
Source: https://api.lancepilot.com/pages/endpoints/contact-import/get
GET /workspaces/{workspace}/contact-imports/{contact-import}
Retrieve a specific contact import by ID in the specified workspace.
# Get Contact Imports
Source: https://api.lancepilot.com/pages/endpoints/contact-import/list
GET /workspaces/{workspace}/contact-imports
Retrieve all contact imports for the specified workspace.
# Update Contact Import
Source: https://api.lancepilot.com/pages/endpoints/contact-import/update
PATCH /workspaces/{workspace}/contact-imports/{contact-import}
Update an existing contact import in the specified workspace.
# Add Contacts
Source: https://api.lancepilot.com/pages/endpoints/contacts/add
POST /workspaces/{workspace}/contacts
Create a new contact in the workspace.
### JSON (Basic Contact)
```json theme={null}
{
"number": "+14155550123",
"name": "John Doe",
"email": "john@example.com",
"gender": "male"
}
```
### Multipart Form Data (Extended Contact)
If you want to upload an **avatar image**, assign **groups**, or set **status**, you must send the request as `multipart/form-data`. Example:
```
POST /contacts
Content-Type: multipart/form-data
number=+14155550123
name=John Doe
email=john@example.com
gender=male
status=1
avatar=@/path/to/image.png
contact_groups[]=12
contact_groups[]=15
```
***
### π Field Requirements
| Field | Type | Required | Notes |
| ---------------- | ----------------------- | -------- | -------------------------------------------------------------------- |
| `number` | string | Yes | WhatsApp phone number (must be unique in workspace). |
| `name` | string (max 50) | No | Contactβs display name. Defaults to `Unknown` if not provided. |
| `email` | string (email) | No | Contactβs email address. |
| `gender` | enum(male,female,other) | No | Gender of contact. |
| `status` | boolean | No | Defaults to `true`. Only available in form-data requests. |
| `avatar` | file (image, β€2MB) | No | Upload contact avatar (form-data only). |
| `contact_groups` | array of integers | No | Group IDs to assign contact into (form-data only, workspace scoped). |
***
# Delete Contact
Source: https://api.lancepilot.com/pages/endpoints/contacts/delete
DELETE /workspaces/{workspace}/contacts/{contact}
Delete a contact by ID.
# Export Contacts
Source: https://api.lancepilot.com/pages/endpoints/contacts/export
GET /workspaces/{workspace}/contacts/export
Download all contacts (optionally filtered by a contact group) as CSV or XLSX.
# Get Contact
Source: https://api.lancepilot.com/pages/endpoints/contacts/get
GET /workspaces/{workspace}/contacts/{contact}
Retrieve a specific contact by ID.
# Get Contact by Number
Source: https://api.lancepilot.com/pages/endpoints/contacts/get-number
GET /workspaces/{workspace}/contacts/number/{number}
Retrieve a specific contact by WhatsApp number in the workspace.
# Get Contacts
Source: https://api.lancepilot.com/pages/endpoints/contacts/list
GET /workspaces/{workspace}/contacts
Retrieve contacts associated with a specific workspace.
# Toggle Contact Label
Source: https://api.lancepilot.com/pages/endpoints/contacts/toggle-label
POST /workspaces/{workspace}/contacts/{contact}/toggle-label
Attach or detach a label from a contact. If the label is already attached, it will be detached, and vice versa.
### JSON Example
```json theme={null}
{
"label_id": 5
}
```
***
### π Field Requirements
| Field | Type | Required | Notes |
| ---------- | ------- | -------- | --------------------------------------------------- |
| `label_id` | integer | Yes | ID of the label to toggle (must exist in workspace) |
***
### π Behavior
This endpoint toggles a label on a contact:
* If the label is **not** currently assigned to the contact, it will be **added**
* If the label is **already** assigned to the contact, it will be **removed**
### β
Success Response
```json theme={null}
{
"status": 200,
"message": "Contact label toggled successfully",
"data": null
}
```
# Toggle Contact Tag
Source: https://api.lancepilot.com/pages/endpoints/contacts/toggle-tag
POST /workspaces/{workspace}/contacts/{contact}/toggle-tag
Attach or detach a tag from a contact. If the tag is already attached, it will be detached, and vice versa.
### JSON Example
```json theme={null}
{
"tag_id": 3
}
```
***
### π Field Requirements
| Field | Type | Required | Notes |
| -------- | ------- | -------- | ------------------------------------------------- |
| `tag_id` | integer | Yes | ID of the tag to toggle (must exist in workspace) |
***
### π Behavior
This endpoint toggles a tag on a contact:
* If the tag is **not** currently assigned to the contact, it will be **added**
* If the tag is **already** assigned to the contact, it will be **removed**
### β
Success Response
```json theme={null}
{
"status": 200,
"message": "Contact tag toggled successfully",
"data": null
}
```
# Update Contact
Source: https://api.lancepilot.com/pages/endpoints/contacts/update
POST /workspaces/{workspace}/contacts/{contact}
Update an existing contact in the workspace.
### JSON Example
```json theme={null}
{
"name": "John Smith",
"email": "johnsmith@example.com",
"gender": "male",
"status": true
}
```
### Multipart Form Data Example
```
PUT /contacts/123
Content-Type: multipart/form-data
name=John Smith
email=johnsmith@example.com
gender=male
status=1
avatar=@/path/to/avatar.png
contact_groups[]=10
contact_groups[]=12
```
***
### π Field Requirements for Update
| Field | Type | Required | Notes |
| ---------------- | ----------------------- | -------- | -------------------------------------------------------- |
| `name` | string (max 50) | Yes | Contactβs display name |
| `email` | string (email) | No | Contact email |
| `gender` | enum(male,female,other) | No | Gender of contact |
| `status` | boolean | No | Contact active status |
| `avatar` | file (image β€2MB) | No | Upload new avatar (form-data only) |
| `contact_groups` | array of integers | No | Assign contact groups (form-data only, workspace scoped) |
# Create Label
Source: https://api.lancepilot.com/pages/endpoints/labels/add
POST /workspaces/{workspace}/labels
Create a new label in the specified workspace.
### JSON Request Example
```json theme={null}
{
"name": "Important",
"color": "#FF5733"
}
```
***
### π Field Requirements
| Field | Type | Required | Notes |
| ------- | ---------------- | -------- | ------------------------------------------------------------ |
| `name` | string (max 255) | Yes | Label name (must be unique within the workspace). |
| `color` | string (max 7) | No | Hex color code (e.g., #FF5733). Defaults to null if omitted. |
***
### π‘ Notes
* Label names must be unique within each workspace
* The `color` field accepts standard hex color codes with the `#` prefix
* Labels can be used to organize and categorize contacts
# Delete Label
Source: https://api.lancepilot.com/pages/endpoints/labels/delete
DELETE /workspaces/{workspace}/labels/{label}
Delete a label by ID. This will also detach the label from all associated contacts.
### π‘ Notes
* Deleting a label will automatically detach it from all associated contacts
* This action cannot be undone
* The label ID will not be reused
# Get Label
Source: https://api.lancepilot.com/pages/endpoints/labels/get
GET /workspaces/{workspace}/labels/{label}
Retrieve a specific label by ID.
# Get Labels
Source: https://api.lancepilot.com/pages/endpoints/labels/list
GET /workspaces/{workspace}/labels
Retrieve all labels associated with the specified workspace.
# Update Label
Source: https://api.lancepilot.com/pages/endpoints/labels/update
PUT /workspaces/{workspace}/labels/{label}
Update an existing label in the specified workspace.
### JSON Request Example
```json theme={null}
{
"name": "Very Important",
"color": "#00AA00"
}
```
***
### π Field Requirements
| Field | Type | Required | Notes |
| ------- | ---------------- | -------- | ----------------------------------------------------- |
| `name` | string (max 255) | Yes | New label name (must be unique within the workspace). |
| `color` | string (max 7) | No | Hex color code (e.g., #00AA00). Optional. |
***
### π‘ Notes
* The label name must remain unique within the workspace
* You can update just the name, just the color, or both fields
* Updating a label does not affect contacts already tagged with this label
# Audio Message
Source: https://api.lancepilot.com/pages/endpoints/messages/with-id/audio
POST /workspaces/{workspace}/contacts/{contact}/messages/audio
Send a audio message to a specific contact within a workspace.
This endpoint allows you to send an audio message to a contact. You can provide the audio in two ways:
1. **Audio URL**: Pass the audio URL in the request body.
2. **Uploaded File**: Send the audio as a file using `multipart/form-data`.
### File Field Requirements
* **file**:
* **Required**
* **Allowed MIME types**: `aac`, `amr`, `mp3`, `m4a`, `ogg`
* **Maximum size**: 16 MB (`max:16384` KB)
### Request Options
* **Audio URL Example (JSON):**
```json theme={null}
{
"file": "https://example.com/audio.mp3"
}
```
* **Uploaded File Example (multipart/form-data):**
```
POST /workspaces/{workspace}/contacts/{contact}/messages/audio
Content-Type: multipart/form-data
file: [binary audio file]
```
Choose the method that best fits your use case.
# Can Send Free Message
Source: https://api.lancepilot.com/pages/endpoints/messages/with-id/can-send-free
GET /workspaces/{workspace}/contacts/{contact}/can-send-free-message
# Document Message
Source: https://api.lancepilot.com/pages/endpoints/messages/with-id/document
POST /workspaces/{workspace}/contacts/{contact}/messages/document
Send a document message to a specific contact within a workspace.
This endpoint allows you to send an document message to a contact. You can provide the document in two ways:
1. **Document URL**: Pass the document URL in the request body.
2. **Uploaded File**: Send the document as a file using `multipart/form-data`.
### File Field Requirements
* **file**:
* **Required**
* **Allowed MIME types**: `txt`, `docx`, `ppt`, `pptx`, `xls`, `xlsx`, `doc`, `pdf`
* **Maximum size**: 100 MB (`max:102400` KB)
### Request Options
* **Document URL Example (JSON):**
```json theme={null}
{
"file": "https://example.com/document.txt"
}
```
* **Uploaded File Example (multipart/form-data):**
```
POST /workspaces/{workspace}/contacts/{contact}/messages/document
Content-Type: multipart/form-data
file: [binary document file]
```
Choose the method that best fits your use case.
# Image Message
Source: https://api.lancepilot.com/pages/endpoints/messages/with-id/image
POST /workspaces/{workspace}/contacts/{contact}/messages/image
Send a text message to a specific contact within a workspace.
This endpoint allows you to send an image message to a contact. You can provide the image in two ways:
1. **Image URL**: Pass the image URL in the request body.
2. **Uploaded File**: Send the image as a file using `multipart/form-data`.
### File Field Requirements
* **file**:
* **Required**
* **Allowed MIME types**: `jpg`, `png`
* **Maximum size**: 5.12 MB (`max:5120` KB)
### Request Options
* **Image URL Example (JSON):**
```json theme={null}
{
"file": "https://example.com/image.jpg"
}
```
* **Uploaded File Example (multipart/form-data):**
```
POST /workspaces/{workspace}/contacts/{contact}/messages/image
Content-Type: multipart/form-data
file: [binary image file]
```
Choose the method that best fits your use case.
# Text Message
Source: https://api.lancepilot.com/pages/endpoints/messages/with-id/text
POST /workspaces/{workspace}/contacts/{contact}/messages/text
Send a text message to a specific contact within a workspace.
# Video Message
Source: https://api.lancepilot.com/pages/endpoints/messages/with-id/video
POST /workspaces/{workspace}/contacts/{contact}/messages/video
Send a video message to a specific contact within a workspace.
This endpoint allows you to send an video message to a contact. You can provide the video in two ways:
1. **Video URL**: Pass the video URL in the request body.
2. **Uploaded File**: Send the video as a file using `multipart/form-data`.
### File Field Requirements
* **file**:
* **Required**
* **Allowed MIME types**: `mp4`, `3gp`
* **Maximum size**: 16 MB (`max:16384` KB)
### Request Options
* **Video URL Example (JSON):**
```json theme={null}
{
"file": "https://example.com/video.mp4"
}
```
* **Uploaded File Example (multipart/form-data):**
```
POST /workspaces/{workspace}/contacts/{contact}/messages/video
Content-Type: multipart/form-data
file: [binary video file]
```
Choose the method that best fits your use case.
# Audio Message
Source: https://api.lancepilot.com/pages/endpoints/messages/with-number/audio
POST /workspaces/{workspace}/contacts/number/{number}/messages/audio
Send a audio message to a specific contact within a workspace.
This endpoint allows you to send an audio message to a contact. You can provide the audio in two ways:
1. **Audio URL**: Pass the audio URL in the request body.
2. **Uploaded File**: Send the audio as a file using `multipart/form-data`.
### File Field Requirements
* **file**:
* **Required**
* **Allowed MIME types**: `aac`, `amr`, `mp3`, `m4a`, `ogg`
* **Maximum size**: 16 MB (`max:16384` KB)
### Request Options
* **Audio URL Example (JSON):**
```json theme={null}
{
"file": "https://example.com/audio.mp3"
}
```
* **Uploaded File Example (multipart/form-data):**
```
POST /workspaces/{workspace}/contacts/number/{number}/messages/audio
Content-Type: multipart/form-data
file: [binary audio file]
```
Choose the method that best fits your use case.
# Can Send Free Message
Source: https://api.lancepilot.com/pages/endpoints/messages/with-number/can-send-free
GET /workspaces/{workspace}/contacts/number/{number}/can-send-free-message
# Document Message
Source: https://api.lancepilot.com/pages/endpoints/messages/with-number/document
POST /workspaces/{workspace}/contacts/number/{number}/messages/document
Send a document message to a specific contact within a workspace.
This endpoint allows you to send an document message to a contact. You can provide the document in two ways:
1. **Document URL**: Pass the document URL in the request body.
2. **Uploaded File**: Send the document as a file using `multipart/form-data`.
### File Field Requirements
* **file**:
* **Required**
* **Allowed MIME types**: `txt`, `docx`, `ppt`, `pptx`, `xls`, `xlsx`, `doc`, `pdf`
* **Maximum size**: 100 MB (`max:102400` KB)
### Request Options
* **Document URL Example (JSON):**
```json theme={null}
{
"file": "https://example.com/document.txt"
}
```
* **Uploaded File Example (multipart/form-data):**
```
POST /workspaces/{workspace}/contacts/number/{number}/messages/document
Content-Type: multipart/form-data
file: [binary document file]
```
Choose the method that best fits your use case.
# Image Message
Source: https://api.lancepilot.com/pages/endpoints/messages/with-number/image
POST /workspaces/{workspace}/contacts/number/{number}/messages/image
Send a text message to a specific contact within a workspace.
This endpoint allows you to send an image message to a contact. You can provide the image in two ways:
1. **Image URL**: Pass the image URL in the request body.
2. **Uploaded File**: Send the image as a file using `multipart/form-data`.
### File Field Requirements
* **file**:
* **Required**
* **Allowed MIME types**: `jpg`, `png`
* **Maximum size**: 5.12 MB (`max:5120` KB)
### Request Options
* **Image URL Example (JSON):**
```json theme={null}
{
"file": "https://example.com/image.jpg"
}
```
* **Uploaded File Example (multipart/form-data):**
```
POST /workspaces/{workspace}/contacts/number/{number}/messages/image
Content-Type: multipart/form-data
file: [binary image file]
```
Choose the method that best fits your use case.
# Text Message
Source: https://api.lancepilot.com/pages/endpoints/messages/with-number/text
POST /workspaces/{workspace}/contacts/number/{number}/messages/text
Send a text message to a specific contact within a workspace.
# Video Message
Source: https://api.lancepilot.com/pages/endpoints/messages/with-number/video
POST /workspaces/{workspace}/contacts/number/{number}/messages/video
Send a video message to a specific contact within a workspace.
This endpoint allows you to send an video message to a contact. You can provide the video in two ways:
1. **Video URL**: Pass the video URL in the request body.
2. **Uploaded File**: Send the video as a file using `multipart/form-data`.
### File Field Requirements
* **file**:
* **Required**
* **Allowed MIME types**: `mp4`, `3gp`
* **Maximum size**: 16 MB (`max:16384` KB)
### Request Options
* **Video URL Example (JSON):**
```json theme={null}
{
"file": "https://example.com/video.mp4"
}
```
* **Uploaded File Example (multipart/form-data):**
```
POST /workspaces/{workspace}/contacts/number/{number}/messages/video
Content-Type: multipart/form-data
file: [binary video file]
```
Choose the method that best fits your use case.
# Subscribe (Id)
Source: https://api.lancepilot.com/pages/endpoints/newsletters/subscribe
POST /workspaces/{workspace}/newsletters/{newsletter}/subscribe
This endpoint subscribes an existing contact to a newsletter using their **contact_id**.
It also allows updating name, email, and custom input fields. If automation is configured for the newsletter, an automation instance will be created.
# Subscribe (Number)
Source: https://api.lancepilot.com/pages/endpoints/newsletters/subscribe-number
POST /workspaces/{workspace}/newsletters/{newsletter}/subscribe-number
This endpoint subscribes a contact to a newsletter using their **WhatsApp number**. If the contact does not exist, a new one will be created with default values.
It also supports updating name, email, and custom input fields. If automation is configured for the newsletter, an automation instance will be created.
# Get Permissions
Source: https://api.lancepilot.com/pages/endpoints/role-and-permissions/get-permissions
GET /workspaces/{workspace}/permissions
Retrieve the permissions for the specified workspace.
# Get Roles
Source: https://api.lancepilot.com/pages/endpoints/role-and-permissions/get-roles
GET /workspaces/{workspace}/roles-all
Retrieve all roles available in the specified workspace.
# Add Role
Source: https://api.lancepilot.com/pages/endpoints/roles/add
POST /workspaces/{workspace}/roles
Create a new role in the specified workspace.
# Delete Role
Source: https://api.lancepilot.com/pages/endpoints/roles/delete
DELETE /workspaces/{workspace}/roles/{role}
Delete a role by ID in the specified workspace.
# Get role
Source: https://api.lancepilot.com/pages/endpoints/roles/get
GET /workspaces/{workspace}/roles/{role}
Retrieve a specific role by ID in the specified workspace.
# Get Roles
Source: https://api.lancepilot.com/pages/endpoints/roles/list
GET /workspaces/{workspace}/roles
Retrieve all roles for the specified workspace.
# Update Role
Source: https://api.lancepilot.com/pages/endpoints/roles/update
PUT /workspaces/{workspace}/roles/{role}
Update an existing role in the specified workspace.
# Create Tag
Source: https://api.lancepilot.com/pages/endpoints/tags/add
POST /workspaces/{workspace}/tags
Create a new tag in the specified workspace.
### JSON Request Example
```json theme={null}
{
"name": "VIP"
}
```
***
### π Field Requirements
| Field | Type | Required | Notes |
| ------ | ---------------- | -------- | ----------------------------------------------- |
| `name` | string (max 255) | Yes | Tag name (must be unique within the workspace). |
***
### π‘ Notes
* Tag names must be unique within each workspace
* Tags can be used to organize and categorize contacts
* Unlike labels, tags do not have a color property
# Delete Tag
Source: https://api.lancepilot.com/pages/endpoints/tags/delete
DELETE /workspaces/{workspace}/tags/{tag}
Delete a tag by ID. This will also detach the tag from all associated contacts.
### π‘ Notes
* Deleting a tag will automatically detach it from all associated contacts
* This action cannot be undone
* The tag ID will not be reused
# Get Tag
Source: https://api.lancepilot.com/pages/endpoints/tags/get
GET /workspaces/{workspace}/tags/{tag}
Retrieve a specific tag by ID.
# Get Tags
Source: https://api.lancepilot.com/pages/endpoints/tags/list
GET /workspaces/{workspace}/tags
Retrieve all tags associated with the specified workspace.
# Update Tag
Source: https://api.lancepilot.com/pages/endpoints/tags/update
PUT /workspaces/{workspace}/tags/{tag}
Update an existing tag in the specified workspace.
### JSON Request Example
```json theme={null}
{
"name": "Premium VIP"
}
```
***
### π Field Requirements
| Field | Type | Required | Notes |
| ------ | ---------------- | -------- | --------------------------------------------------- |
| `name` | string (max 255) | Yes | New tag name (must be unique within the workspace). |
***
### π‘ Notes
* The tag name must remain unique within the workspace
* Updating a tag does not affect contacts already tagged with this tag
# Send Template Message (Id)
Source: https://api.lancepilot.com/pages/endpoints/template-message/send-id
POST /workspaces/{workspace}/contacts/{contact}/template-messages
Send a WhatsApp template message to a contact using their contact ID. Templates can include text/media headers, body with variables, footers, and buttons.
### Description
This endpoint allows you to send WhatsApp template messages to a contact using their contact ID. Templates can include various components such as headers (text/media), body text with variables, footers, and buttons.
***
## Template Components
Templates may contain the following components:
* **Header**: Text (with variables) or Media (image, video, document)
* **Body**: Message text with dynamic variables (`{{1}}`, `{{2}}`, etc.)
* **Footer**: Static footer text
* **Buttons**: URL buttons (with variables), phone buttons, or quick reply buttons
***
## Request Payload Structure
### Basic Structure
```json theme={null}
{
"template_id": 123,
"template_data": {
"header": {
"variables": ["Header Variable"],
"file": "https://example.com/image.jpg"
},
"body": {
"variables": ["Variable 1", "Variable 2"]
},
"buttons": [
{
"type": "URL",
"variables": ["promo-code-123"]
}
]
}
}
```
***
## Examples by Template Type
### 1. Simple Body-Only Template
For templates with only body text and no variables:
```json theme={null}
{
"template_id": 123,
"template_data": {}
}
```
***
### 2. Body with Variables
Template body: `"Hello \{\{1\}\}, your order \{\{2\}\} is confirmed!"`
```json theme={null}
{
"template_id": 123,
"template_data": {
"body": {
"variables": ["John Doe", "#12345"]
}
}
}
```
**Validation Rules:**
* Maximum 20 variables in body
* Each variable max 1000 characters
* Total body length (with variables) max 1024 characters
* Authentication templates: variables max 11 characters, no links allowed
***
### 3. Text Header with Variables
Template header: `"Welcome \{\{1\}\}!"`
```json theme={null}
{
"template_id": 123,
"template_data": {
"header": {
"variables": ["Premium Member"]
},
"body": {
"variables": ["John", "Gold Tier"]
}
}
}
```
**Validation Rules:**
* Maximum 1 variable in text header
* Variable max 60 characters
* Total header length (with variables) max 60 characters
***
### 4. Image Header Template
#### Option A: Using Image URL (JSON)
```json theme={null}
{
"template_id": 123,
"template_data": {
"header": {
"file": "https://example.com/product-image.jpg"
},
"body": {
"variables": ["Product Name", "$99.99"]
}
}
}
```
#### Option B: Uploading Image File (multipart/form-data)
```bash theme={null}
POST /api/v3/workspaces/{workspace}/contacts/{contact}/template-messages
Content-Type: multipart/form-data
template_id: 123
template_data[header][file]: [binary image file]
template_data[body][variables][0]: Product Name
template_data[body][variables][1]: $99.99
```
**Validation Rules:**
* Allowed types: jpg, jpeg, png
* Maximum size: 5 MB (5120 KB)
***
### 5. Video Header Template
#### Using Video URL
```json theme={null}
{
"template_id": 123,
"template_data": {
"header": {
"file": "https://example.com/demo-video.mp4"
},
"body": {
"variables": ["John", "Premium Course"]
}
}
}
```
#### Uploading Video File
```bash theme={null}
POST /api/v3/workspaces/{workspace}/contacts/{contact}/template-messages
Content-Type: multipart/form-data
template_id: 123
template_data[header][file]: [binary video file]
template_data[body][variables][0]: John
template_data[body][variables][1]: Premium Course
```
**Validation Rules:**
* Allowed type: video/mp4
* Maximum size: 16 MB (16384 KB)
***
### 6. Document Header Template
#### Using Document URL
```json theme={null}
{
"template_id": 123,
"template_data": {
"header": {
"file": "https://example.com/invoice.pdf"
},
"body": {
"variables": ["Invoice #12345", "$500.00"]
}
}
}
```
#### Uploading Document File
```bash theme={null}
POST /api/v3/workspaces/{workspace}/contacts/{contact}/template-messages
Content-Type: multipart/form-data
template_id: 123
template_data[header][file]: [binary PDF file]
template_data[body][variables][0]: Invoice #12345
template_data[body][variables][1]: $500.00
```
**Validation Rules:**
* Allowed type: application/pdf
* Maximum size: 30 MB (30720 KB)
***
### 7. Authentication/OTP Template
For one-time password templates:
```json theme={null}
{
"template_id": 123,
"template_data": {
"body": {
"variables": ["123456"]
}
}
}
```
**Validation Rules:**
* Variables max 11 characters
* No links allowed in variables
***
### 8. URL Button with Variables
Template with dynamic URL button: `https://example.com/promo/\{\{1\}\}`
```json theme={null}
{
"template_id": 123,
"template_data": {
"body": {
"variables": ["John", "SAVE20"]
},
"buttons": [
{
"type": "URL",
"variables": ["SAVE20"]
}
]
}
}
```
**Validation Rules:**
* Each URL button variable max 2000 characters
* Number of variables must match template definition
***
### 9. Multiple URL Buttons with Variables
For templates with multiple URL buttons:
```json theme={null}
{
"template_id": 123,
"template_data": {
"body": {
"variables": ["Order #12345"]
},
"buttons": [
{
"type": "URL",
"variables": ["12345"]
},
{
"type": "URL",
"variables": ["track-code-xyz"]
}
]
}
}
```
***
### 10. Complex Template (All Components)
Image header + body variables + URL button with variable:
```json theme={null}
{
"template_id": 123,
"template_data": {
"header": {
"file": "https://example.com/banner.jpg"
},
"body": {
"variables": ["John Doe", "Premium Plan", "$99.99", "December 31, 2025"]
},
"buttons": [
{
"type": "URL",
"variables": ["user-123-token-abc"]
}
]
}
}
```
***
## Media File Requirements
### Image Header
* **Required**: When template has image header
* **Allowed types**: jpg, jpeg, png
* **Maximum size**: 5 MB (5120 KB)
### Video Header
* **Required**: When template has video header
* **Allowed type**: mp4
* **Maximum size**: 16 MB (16384 KB)
### Document Header
* **Required**: When template has document header
* **Allowed type**: PDF
* **Maximum size**: 30 MB (30720 KB)
***
## Complete Example with cURL
```bash theme={null}
# JSON request with image URL
curl -X POST "https://lancepilot.com/api/v3/workspaces/123/contacts/456/template-messages" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"template_id": 789,
"template_data": {
"header": {
"file": "https://example.com/product.jpg"
},
"body": {
"variables": ["John Doe", "Premium Package", "$149.99"]
},
"buttons": [
{
"type": "URL",
"variables": ["promo2025"]
}
]
}
}'
# Multipart form-data request with file upload
curl -X POST "https://lancepilot.com/api/v3/workspaces/123/contacts/456/template-messages" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-F "template_id=789" \
-F "template_data[header][file]=@/path/to/image.jpg" \
-F "template_data[body][variables][0]=John Doe" \
-F "template_data[body][variables][1]=Premium Package" \
-F "template_data[body][variables][2]=$149.99" \
-F "template_data[buttons][0][type]=URL" \
-F "template_data[buttons][0][variables][0]=promo2025"
```
***
## Error Responses
### Invalid Template ID
```json theme={null}
{
"message": "Template not found"
}
```
### Missing Required Variables
```json theme={null}
{
"message": "The body.variables field is required.",
"errors": {
"body.variables": ["The body.variables field is required."]
}
}
```
### Variable Count Mismatch
```json theme={null}
{
"message": "The body.variables must have at least 3 items.",
"errors": {
"body.variables": ["The body.variables must have at least 3 items."]
}
}
```
### Body Text Too Long
```json theme={null}
{
"message": "Message body with all variable values is too long, it can be max 1024 characters",
"errors": {
"body.text": ["Message body with all variable values is too long, it can be max 1024 characters"]
}
}
```
### Invalid Media File
```json theme={null}
{
"message": "The header.file must be a file of type: jpg, jpeg, png.",
"errors": {
"header.file": ["The header.file must be a file of type: jpg, jpeg, png."]
}
}
```
***
# Send Template Message (Number)
Source: https://api.lancepilot.com/pages/endpoints/template-message/send-number
POST /workspaces/{workspace}/contacts/number/{number}/template-messages
Send a WhatsApp template message to a contact using their phone number. If the contact doesn't exist, it will be automatically created. Templates can include text/media headers, body with variables, footers, and buttons.
### Description
This endpoint allows you to send WhatsApp template messages to a contact using their phone number. If the contact doesn't exist in your workspace, it will be automatically created. Templates can include various components such as headers (text/media), body text with variables, footers, and buttons.
***
## Template Components
Templates may contain the following components:
* **Header**: Text (with variables) or Media (image, video, document)
* **Body**: Message text with dynamic variables (`{{1}}`, `{{2}}`, etc.)
* **Footer**: Static footer text
* **Buttons**: URL buttons (with variables), phone buttons, or quick reply buttons
***
## Request Payload Structure
### Basic Structure
```json theme={null}
{
"template_id": 123,
"template_data": {
"header": {
"variables": ["Header Variable"],
"file": "https://example.com/image.jpg"
},
"body": {
"variables": ["Variable 1", "Variable 2"]
},
"buttons": [
{
"type": "URL",
"variables": ["promo-code-123"]
}
]
}
}
```
***
## Examples by Template Type
### 1. Simple Body-Only Template
For templates with only body text and no variables:
```json theme={null}
{
"template_id": 123,
"template_data": {}
}
```
***
### 2. Body with Variables
Template body: `"Hello \{\{1\}\}, your order \{\{2\}\} is confirmed!"`
```json theme={null}
{
"template_id": 123,
"template_data": {
"body": {
"variables": ["John Doe", "#12345"]
}
}
}
```
**Validation Rules:**
* Maximum 20 variables in body
* Each variable max 1000 characters
* Total body length (with variables) max 1024 characters
* Authentication templates: variables max 11 characters, no links allowed
***
### 3. Text Header with Variables
Template header: `"Welcome \{\{1\}\}!"`
```json theme={null}
{
"template_id": 123,
"template_data": {
"header": {
"variables": ["Premium Member"]
},
"body": {
"variables": ["John", "Gold Tier"]
}
}
}
```
**Validation Rules:**
* Maximum 1 variable in text header
* Variable max 60 characters
* Total header length (with variables) max 60 characters
***
### 4. Image Header Template
#### Option A: Using Image URL (JSON)
```json theme={null}
{
"template_id": 123,
"template_data": {
"header": {
"file": "https://example.com/product-image.jpg"
},
"body": {
"variables": ["Product Name", "$99.99"]
}
}
}
```
#### Option B: Uploading Image File (multipart/form-data)
```bash theme={null}
POST /api/v3/workspaces/{workspace}/contacts/number/{number}/template-messages
Content-Type: multipart/form-data
template_id: 123
template_data[header][file]: [binary image file]
template_data[body][variables][0]: Product Name
template_data[body][variables][1]: $99.99
```
**Validation Rules:**
* Allowed types: jpg, jpeg, png
* Maximum size: 5 MB (5120 KB)
***
### 5. Video Header Template
#### Using Video URL
```json theme={null}
{
"template_id": 123,
"template_data": {
"header": {
"file": "https://example.com/demo-video.mp4"
},
"body": {
"variables": ["John", "Premium Course"]
}
}
}
```
#### Uploading Video File
```bash theme={null}
POST /api/v3/workspaces/{workspace}/contacts/number/{number}/template-messages
Content-Type: multipart/form-data
template_id: 123
template_data[header][file]: [binary video file]
template_data[body][variables][0]: John
template_data[body][variables][1]: Premium Course
```
**Validation Rules:**
* Allowed type: video/mp4
* Maximum size: 16 MB (16384 KB)
***
### 6. Document Header Template
#### Using Document URL
```json theme={null}
{
"template_id": 123,
"template_data": {
"header": {
"file": "https://example.com/invoice.pdf"
},
"body": {
"variables": ["Invoice #12345", "$500.00"]
}
}
}
```
#### Uploading Document File
```bash theme={null}
POST /api/v3/workspaces/{workspace}/contacts/number/{number}/template-messages
Content-Type: multipart/form-data
template_id: 123
template_data[header][file]: [binary PDF file]
template_data[body][variables][0]: Invoice #12345
template_data[body][variables][1]: $500.00
```
**Validation Rules:**
* Allowed type: application/pdf
* Maximum size: 30 MB (30720 KB)
***
### 7. Authentication/OTP Template
For one-time password templates:
```json theme={null}
{
"template_id": 123,
"template_data": {
"body": {
"variables": ["123456"]
}
}
}
```
**Validation Rules:**
* Variables max 11 characters
* No links allowed in variables
***
### 8. URL Button with Variables
Template with dynamic URL button: `https://example.com/promo/\{\{1\}\}`
```json theme={null}
{
"template_id": 123,
"template_data": {
"body": {
"variables": ["John", "SAVE20"]
},
"buttons": [
{
"type": "URL",
"variables": ["SAVE20"]
}
]
}
}
```
**Validation Rules:**
* Each URL button variable max 2000 characters
* Number of variables must match template definition
***
### 9. Multiple URL Buttons with Variables
For templates with multiple URL buttons:
```json theme={null}
{
"template_id": 123,
"template_data": {
"body": {
"variables": ["Order #12345"]
},
"buttons": [
{
"type": "URL",
"variables": ["12345"]
},
{
"type": "URL",
"variables": ["track-code-xyz"]
}
]
}
}
```
***
### 10. Complex Template (All Components)
Image header + body variables + URL button with variable:
```json theme={null}
{
"template_id": 123,
"template_data": {
"header": {
"file": "https://example.com/banner.jpg"
},
"body": {
"variables": ["John Doe", "Premium Plan", "$99.99", "December 31, 2025"]
},
"buttons": [
{
"type": "URL",
"variables": ["user-123-token-abc"]
}
]
}
}
```
***
## Phone Number Format
The phone number in the URL should be in international format without the `+` symbol:
* β
Correct: `14155552671` (USA), `447911123456` (UK), `919876543210` (India)
* β Incorrect: `+14155552671`, `+44 7911 123456`, `(415) 555-2671`
***
## Media File Requirements
### Image Header
* **Required**: When template has image header
* **Allowed types**: jpg, jpeg, png
* **Maximum size**: 5 MB (5120 KB)
### Video Header
* **Required**: When template has video header
* **Allowed type**: mp4
* **Maximum size**: 16 MB (16384 KB)
### Document Header
* **Required**: When template has document header
* **Allowed type**: PDF
* **Maximum size**: 30 MB (30720 KB)
***
## Complete Example with cURL
```bash theme={null}
# JSON request with image URL to a new contact
curl -X POST "https://lancepilot.com/api/v3/workspaces/123/contacts/number/14155552671/template-messages" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"template_id": 789,
"template_data": {
"header": {
"file": "https://example.com/product.jpg"
},
"body": {
"variables": ["John Doe", "Premium Package", "$149.99"]
},
"buttons": [
{
"type": "URL",
"variables": ["promo2025"]
}
]
}
}'
# Multipart form-data request with file upload
curl -X POST "https://lancepilot.com/api/v3/workspaces/123/contacts/number/447911123456/template-messages" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-F "template_id=789" \
-F "template_data[header][file]=@/path/to/image.jpg" \
-F "template_data[body][variables][0]=John Doe" \
-F "template_data[body][variables][1]=Premium Package" \
-F "template_data[body][variables][2]=$149.99" \
-F "template_data[buttons][0][type]=URL" \
-F "template_data[buttons][0][variables][0]=promo2025"
```
***
## Auto-Contact Creation
When sending to a number that doesn't exist in your workspace:
1. The system validates the phone number format
2. Automatically creates a new contact with:
* Name: "Unknown" (can be updated later)
* WhatsApp number: The provided number
* Country: Auto-detected from phone number
* Timezone: Set based on country
3. Sends the template message to the newly created contact
***
## Error Responses
### Invalid Phone Number
```json theme={null}
{
"message": "Invalid Number"
}
```
### Invalid Template ID
```json theme={null}
{
"message": "Template not found"
}
```
### Missing Required Variables
```json theme={null}
{
"message": "The body.variables field is required.",
"errors": {
"body.variables": ["The body.variables field is required."]
}
}
```
### Variable Count Mismatch
```json theme={null}
{
"message": "The body.variables must have at least 3 items.",
"errors": {
"body.variables": ["The body.variables must have at least 3 items."]
}
}
```
### Body Text Too Long
```json theme={null}
{
"message": "Message body with all variable values is too long, it can be max 1024 characters",
"errors": {
"body.text": ["Message body with all variable values is too long, it can be max 1024 characters"]
}
}
```
### Invalid Media File
```json theme={null}
{
"message": "The header.file must be a file of type: jpg, jpeg, png.",
"errors": {
"header.file": ["The header.file must be a file of type: jpg, jpeg, png."]
}
}
```
***
# Add Template
Source: https://api.lancepilot.com/pages/endpoints/templates/add
POST /workspaces/{workspace}/templates
## Overview
Create a new WhatsApp message template. Templates must be approved by Meta before they can be used to send messages.
Templates typically take 5-30 minutes for approval. Use the [Sync endpoint](/pages/endpoints/templates/sync) to check approval status.
***
## Request Body Schema
| Field | Type | Required | Description |
| --------------------------- | ----------- | ----------- | -------------------------------------------------------------------------- |
| `name` | string | Yes | Unique template name (only lowercase + underscores). |
| `language` | string | Yes | Language code (e.g., `en`, `es`, `fr`). |
| `category` | string | Yes | One of: `MARKETING`, `UTILITY`, `AUTHENTICATION`. |
| `header` | object/null | No | Template header. Can be `null`, `text`, or `media` (image/video/document). |
| `body` | object | Yes | Main message body. Supports variables (`{{1}}`, `{{2}}`). |
| `body.text` | string | Yes | Message text (max 1024 chars). |
| `body.variables` | array | Conditional | Required if variables exist in text. |
| `footer` | string | No | Footer text (max 60 chars, no emojis). |
| `buttons` | array | No | Interactive buttons (URL, Phone, Quick Reply). Max 3. |
| `unsubscribeButton` | boolean | No | Show **Unsubscribe** button (MARKETING only). |
| `blockButton` | boolean | No | Show **Block** button (MARKETING only). |
| `addSecurityRecommendation` | boolean | Auth only | Include security warning (AUTHENTICATION only). |
| `codeExpirationMinutes` | integer | Auth only | OTP validity period in minutes (1-1440, AUTHENTICATION only). |
| `copyCodeButton` | boolean | Auth only | Add one-tap copy button (AUTHENTICATION only). |
***
## Complete Examples
### Example 1: Marketing Template with Image Header
```json theme={null}
{
"name": "summer_sale_promo",
"language": "en",
"category": "MARKETING",
"header": {
"type": "media",
"media": {
"type": "image",
"file": ""
}
},
"body": {
"text": "Hi {{1}}! π\n\nOur Summer Sale is here! Get {{2}}% off on all items. Use code: {{3}}\n\nHurry, offer ends soon!",
"variables": ["John", "30", "SUMMER30"]
},
"footer": "Terms and conditions apply",
"buttons": [
{
"type": "URL",
"text": "Shop Now",
"url": "https://example.com/sale"
}
],
"unsubscribeButton": true
}
```
### Example 2: Authentication (OTP) Template
```json theme={null}
{
"name": "login_otp_verification",
"language": "en",
"category": "AUTHENTICATION",
"addSecurityRecommendation": true,
"codeExpirationMinutes": 10,
"copyCodeButton": true
}
```
Authentication templates are **auto-generated by Meta** with standard security messaging. You only need to specify the three parameters above.
### Example 3: Utility Template with Multiple Buttons
```json theme={null}
{
"name": "order_confirmation",
"language": "en",
"category": "UTILITY",
"header": {
"type": "text",
"text": {
"content": "Order #{{1}}",
"variables": ["12345"]
}
},
"body": {
"text": "Hi {{1}},\n\nYour order has been confirmed!\n\nOrder ID: {{2}}\nTotal: {{3}}\nDelivery: {{4}}",
"variables": ["Sarah", "ORD-12345", "$99.99", "Dec 15, 2025"]
},
"footer": "Thank you for shopping with us",
"buttons": [
{
"type": "URL",
"text": "Track Order",
"url": "https://example.com/track"
},
{
"type": "PHONE_NUMBER",
"text": "Contact Support",
"phone_number": "+1234567890"
},
{
"type": "QUICK_REPLY",
"text": "Cancel Order"
}
]
}
```
### Example 4: Simple Text Template
```json theme={null}
{
"name": "appointment_reminder",
"language": "en",
"category": "UTILITY",
"body": {
"text": "Reminder: Your appointment with {{1}} is scheduled for {{2}} at {{3}}. Please arrive 10 minutes early.",
"variables": ["Dr. Smith", "December 15, 2025", "2:00 PM"]
},
"footer": "Reply CANCEL to reschedule"
}
```
### Example 5: URL Button with Variable
```json theme={null}
{
"name": "personalized_offer",
"language": "en",
"category": "MARKETING",
"body": {
"text": "Exclusive offer for {{1}}! Your discount code {{2}} is ready. Click below to redeem.",
"variables": ["VIP Members", "VIP20"]
},
"buttons": [
{
"type": "URL",
"text": "Redeem Now",
"url": "https://example.com/offer?code={{1}}",
"variables": ["VIP20"]
}
]
}
```
### Example 6: Video Header Template
```json theme={null}
{
"name": "product_tutorial",
"language": "en",
"category": "MARKETING",
"header": {
"type": "media",
"media": {
"type": "video",
"file": ""
}
},
"body": {
"text": "Watch this quick tutorial on {{1}}! Learn how to get the most out of your purchase in just {{2}} minutes.",
"variables": ["our new feature", "5"]
},
"footer": "Need help? Contact support"
}
```
### Example 7: Document Header Template
```json theme={null}
{
"name": "invoice_delivery",
"language": "en",
"category": "UTILITY",
"header": {
"type": "media",
"media": {
"type": "document",
"file": ""
}
},
"body": {
"text": "Dear {{1}},\n\nPlease find your invoice #{{2}} attached. Amount due: {{3}}\n\nPayment due: {{4}}",
"variables": ["John Doe", "INV-001", "$150.00", "Dec 31, 2025"]
},
"footer": "Thank you for your business"
}
```
***
## Validation Rules
* Must be unique in workspace
* Only lowercase letters and underscores
* Examples: β
`welcome_message`, `order_confirmation_v2`
* Invalid: β `WelcomeMessage`, `order-confirmation`, `template 1`
Must be valid ISO language code:
* English: `en`
* Spanish: `es`
* French: `fr`
* German: `de`
* Portuguese: `pt`
* Arabic: `ar`
* And more...
**Text Header:**
* Max 60 characters
* Max 1 variable: `{{1}}`
* Cannot start/end with variable
* Example: β
`Welcome {{1}}`
* Invalid: β `{{1}} Welcome`
**Media Header:**
* Image: JPG/PNG, max 5MB (5120KB)
* Video: MP4, max 10MB (10240KB)
* Document: PDF, max 30MB (30720KB)
* Required field
* Max 1024 characters
* Cannot start or end with variable
* Max 2 consecutive newlines (`\n\n` allowed, `\n\n\n` not allowed)
* Variables must match: if text has `{{1}}` and `{{2}}`, variables array must have exactly 2 items
* Variables are numbered sequentially: `{{1}}`, `{{2}}`, `{{3}}`, etc.
* Optional field
* Max 60 characters
* No newlines allowed
* No emojis allowed
* Plain text only
* Max 3 buttons total (unsubscribe/block don't count toward limit)
* **URL Button**:
* Requires `text` and `url`
* Can have 1 variable at end: `https://example.com/page?id={{1}}`
* Variable must be in `variables` array
* **PHONE\_NUMBER Button**:
* Requires `text` and `phone_number`
* Phone must include country code: `+1234567890`
* **QUICK\_REPLY Button**:
* Requires `text` only
* Max 3 quick replies per template
* **Button Order**: URL β Phone β Quick Reply
* Only 3 fields required: `addSecurityRecommendation`, `codeExpirationMinutes`, `copyCodeButton`
* No custom header, body, footer, or buttons
* Meta auto-generates the template content
* `codeExpirationMinutes` range: 1-1440 (1 min to 24 hours)
***
## Response
### Success (201 Created)
```json theme={null}
{
"success": true,
"message": "Template created successfully and submitted to Meta for review.",
"data": {
"id": 1234,
"workspace_id": "9ca711b1-14ca-4bd5-9457-751db9c052ac",
"name": "welcome_template",
"language": "en",
"category": "MARKETING",
"status": "PENDING",
"provider_id": null,
"components": {
"header": { ... },
"body": { ... },
"footer": "...",
"buttons": [ ... ]
},
"created_at": "2025-12-03T10:00:00Z",
"updated_at": "2025-12-03T10:00:00Z"
}
}
```
### Validation Error (422)
```json theme={null}
{
"success": false,
"message": "Validation failed",
"errors": {
"name": ["The name field must only contain lowercase letters and underscores."],
"body.variables": ["The number of variables must match the placeholders in the text."],
"header.media.file": ["The file size must not exceed 5120 kilobytes."]
}
}
```
***
## Template Status Flow
After creation, templates go through this lifecycle:
```
PENDING β (Meta Review 5-30 mins) β APPROVED or REJECTED
```
Use [Sync Templates](/pages/endpoints/templates/sync) to update the status.
***
## Common Validation Errors
| Error Message | Cause | Solution |
| -------------------------------------------- | ------------------------------------------ | ------------------------------------------------------- |
| "not\_start\_or\_end\_with\_var" | Text starts/ends with variable | Remove variable from start/end |
| "only\_one\_variable" | Header has more than 1 variable | Use max 1 variable in header |
| "Variable count mismatch" | Variables array doesn't match placeholders | Count `{{1}}`, `{{2}}` in text and provide exact number |
| "File too large" | Media exceeds size limit | Compress file (Image: 5MB, Video: 10MB, PDF: 30MB) |
| "Invalid phone number" | Missing country code | Add country code: `+1234567890` |
| "Template name exists" | Name already used | Choose unique name |
| "no\_more\_than\_two\_consecutive\_newlines" | Too many blank lines | Use max `\n\n` (2 newlines) |
***
## Best Practices
Always test with actual variable values before submission
Start with basic templates, add complexity gradually
Avoid promotional language in UTILITY templates
Use clear names like `order_confirmation` not `template_1`
Compress images/videos before upload
Map out all dynamic values before creating template
***
## Category Guidelines
**Purpose**: Promotional messages, offers, announcements
**Characteristics**:
* Can include unsubscribe/block buttons
* Subject to stricter Meta review
* Rate limits may apply
**Examples**:
* Sales and promotions
* New product launches
* Event invitations
* Newsletter updates
**Purpose**: Transactional and account-related messages
**Characteristics**:
* Faster approval
* Higher sending limits
* No promotional content
**Examples**:
* Order confirmations
* Shipping updates
* Appointment reminders
* Account notifications
**Purpose**: One-time passwords and verification codes
**Characteristics**:
* Auto-generated by Meta
* Highest priority delivery
* Built-in security features
**Examples**:
* Login OTPs
* Password reset codes
* Two-factor authentication
***
## Example cURL Request
```bash theme={null}
curl -X POST \
https://lancepilot.com/api/v3/workspaces/{workspace}/templates \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "welcome_template",
"language": "en",
"category": "UTILITY",
"body": {
"text": "Welcome {{1}}! Your account is now active.",
"variables": ["John"]
}
}'
```
***
**Need More Examples?**
Check out [TEMPLATE\_PAYLOADS.md](https://github.com/lancepilot/docs) for 15+ comprehensive template examples covering all use cases.
**Meta Review Time**: Templates typically take 5-30 minutes for approval. Use the [Sync endpoint](/pages/endpoints/templates/sync) to check status updates.
***
## Next Steps
After creating a template:
1. **Wait for Review**: Meta reviews templates within 5-30 minutes
2. **Sync Status**: Use [POST /templates/sync](/pages/endpoints/templates/sync)
3. **Check Approval**: Use [GET /templates](/pages/endpoints/templates/list) to verify status
4. **Send Messages**: Once approved, use [Send Template Message](/pages/endpoints/template-message/send-id)
# Delete Template
Source: https://api.lancepilot.com/pages/endpoints/templates/delete
DELETE /workspaces/{workspace}/templates/{template}
Delete a template by ID in the specified workspace.
## Overview
Delete a WhatsApp message template from both your workspace and Meta's system.
This action is **irreversible**. The template will be deleted from Meta and cannot be recovered.
***
## Path Parameters
| Parameter | Type | Required | Description |
| ----------- | ------- | -------- | --------------------- |
| `workspace` | UUID | Yes | Workspace ID |
| `template` | integer | Yes | Template ID to delete |
***
## Response
### Success (200 OK)
```json theme={null}
{
"success": true,
"message": "Template deleted successfully"
}
```
### Not Found (404)
```json theme={null}
{
"success": false,
"message": "Template not found"
}
```
***
## What Happens on Deletion?
A background job `DeleteTemplateInApiProvider` is queued
The template is deleted from Meta's WhatsApp Business API
The template is removed from your workspace database
***
## Example Usage
### cURL
```bash theme={null}
curl -X DELETE \
https://lancepilot.com/api/v3/workspaces/{workspace}/templates/1234 \
-H 'Authorization: Bearer YOUR_API_TOKEN'
```
### JavaScript
```javascript theme={null}
async function deleteTemplate(workspaceId, templateId) {
const response = await fetch(
`https://lancepilot.com/api/v3/workspaces/${workspaceId}/templates/${templateId}`,
{
method: 'DELETE',
headers: {
'Authorization': `Bearer ${YOUR_API_TOKEN}`
}
}
);
const data = await response.json();
if (data.success) {
console.log('Template deleted successfully');
} else {
console.error('Deletion failed:', data.message);
}
}
```
### Python
```python theme={null}
import requests
def delete_template(workspace_id, template_id, api_token):
url = f"https://lancepilot.com/api/v3/workspaces/{workspace_id}/templates/{template_id}"
headers = {"Authorization": f"Bearer {api_token}"}
response = requests.delete(url, headers=headers)
return response.json()
# Usage
result = delete_template("workspace-uuid", 1234, "your_token")
print(result['message'])
```
***
## Before Deleting
Verify if the template is currently being used in active campaigns
Save template configuration if you might need it later
Could you update instead of delete? Use [Update Template](/pages/endpoints/templates/update)
Test deletion on non-production templates first
***
## Important Notes
**Async Processing**
Deletion from Meta happens in the background. The local database entry is removed immediately, but Meta deletion may take a few seconds.
**Active Campaigns**
If the template is used in active campaigns or automations, deleting it will cause those to fail. Check dependencies before deletion.
**Soft Delete Alternative**
Consider implementing a soft delete pattern where templates are marked as archived instead of permanently deleted.
***
## Related Endpoints
* [Get Template](/pages/endpoints/templates/get) - View template details before deletion
* [Get Templates](/pages/endpoints/templates/list) - List all templates to find the one to delete
* [Update Template](/pages/endpoints/templates/update) - Alternative to deletion
***
## Error Scenarios
| Error Code | Cause | Solution |
| ---------- | ------------------------ | ------------------------------ |
| 404 | Template not found | Verify template ID exists |
| 401 | Unauthorized | Check API token validity |
| 403 | Insufficient permissions | Verify workspace access rights |
| 500 | Server error | Contact support or retry later |
***
## Bulk Deletion Example
```javascript theme={null}
async function bulkDeleteTemplates(workspaceId, templateIds) {
const results = [];
for (const templateId of templateIds) {
try {
const result = await deleteTemplate(workspaceId, templateId);
results.push({ templateId, success: true, ...result });
} catch (error) {
results.push({ templateId, success: false, error: error.message });
}
// Add delay to avoid rate limiting
await new Promise(resolve => setTimeout(resolve, 1000));
}
return results;
}
// Usage
const deletedTemplates = await bulkDeleteTemplates('workspace-uuid', [1, 2, 3, 4]);
console.log(`Deleted ${deletedTemplates.filter(r => r.success).length} templates`);
```
# Get Template
Source: https://api.lancepilot.com/pages/endpoints/templates/get
GET /workspaces/{workspace}/templates/{template}
Retrieve a specific template by ID in the specified workspace.
## Overview
Retrieve a specific WhatsApp message template by ID.
***
## Path Parameters
| Parameter | Type | Required | Description |
| ----------- | ------- | -------- | ------------ |
| `workspace` | UUID | Yes | Workspace ID |
| `template` | integer | Yes | Template ID |
***
## Response
### Success (200 OK)
```json theme={null}
{
"success": true,
"data": {
"id": 1234,
"workspace_id": "9ca711b1-14ca-4bd5-9457-751db9c052ac",
"name": "order_confirmation",
"language": "en",
"category": "UTILITY",
"status": "APPROVED",
"provider_id": "8949194595096852",
"components": {
"header": {
"type": "text",
"text": {
"content": "Order #{{1}}",
"variables": ["12345"]
}
},
"body": {
"text": "Hi {{1}},\n\nYour order has been confirmed! Estimated delivery: {{2}}",
"variables": ["John", "Dec 15, 2025"]
},
"footer": "Thank you for shopping with us",
"buttons": [
{
"type": "URL",
"text": "Track Order",
"url": "https://example.com/track"
},
{
"type": "PHONE_NUMBER",
"text": "Contact Support",
"phone_number": "+1234567890"
}
]
},
"created_at": "2025-11-01T10:00:00Z",
"updated_at": "2025-11-15T14:30:00Z"
}
}
```
### Not Found (404)
```json theme={null}
{
"success": false,
"message": "Template not found"
}
```
***
## Component Structure
The `components` object contains all template elements:
### Header (Optional)
**Text Header:**
```json theme={null}
"header": {
"type": "text",
"text": {
"content": "Header text with {{1}}",
"variables": ["value"]
}
}
```
**Media Header:**
```json theme={null}
"header": {
"type": "media",
"media": {
"type": "image", // or "video", "document"
"handle": "file_handle_from_meta"
}
}
```
### Body (Required)
```json theme={null}
"body": {
"text": "Message with {{1}} and {{2}}",
"variables": ["value1", "value2"]
}
```
### Footer (Optional)
```json theme={null}
"footer": "Footer text (max 60 chars)"
```
### Buttons (Optional)
```json theme={null}
"buttons": [
{
"type": "URL",
"text": "Button Text",
"url": "https://example.com"
},
{
"type": "PHONE_NUMBER",
"text": "Call Us",
"phone_number": "+1234567890"
},
{
"type": "QUICK_REPLY",
"text": "Quick Reply"
}
]
```
***
## Usage Example
```bash theme={null}
curl -X GET \
https://lancepilot.com/api/v3/workspaces/{workspace}/templates/1234 \
-H 'Authorization: Bearer YOUR_API_TOKEN'
```
***
Use this endpoint to inspect template structure before sending messages with [Send Template Message](/pages/endpoints/template-message/send-id).
# Get Templates
Source: https://api.lancepilot.com/pages/endpoints/templates/list
GET /workspaces/{workspace}/templates
Retrieve all templates for the specified workspace.
## Overview
Retrieve all WhatsApp message templates for a workspace with pagination support.
***
## Query Parameters
| Parameter | Type | Required | Default | Description |
| ---------- | ------- | -------- | ------- | ---------------------------- |
| `per_page` | integer | No | 10 | Number of templates per page |
| `page` | integer | No | 1 | Page number |
***
## Response
### Success (200 OK)
```json theme={null}
{
"success": true,
"data": [
{
"id": 1234,
"workspace_id": "9ca711b1-14ca-4bd5-9457-751db9c052ac",
"name": "welcome_template",
"language": "en",
"category": "MARKETING",
"status": "APPROVED",
"provider_id": "8949194595096852",
"components": {
"header": {
"type": "text",
"text": {
"content": "Welcome {{1}}",
"variables": ["Customer"]
}
},
"body": {
"text": "Thank you for joining us!",
"variables": []
},
"footer": "Reply STOP to unsubscribe",
"buttons": [
{
"type": "URL",
"text": "Visit Website",
"url": "https://example.com"
}
]
},
"created_at": "2025-11-01T10:00:00Z",
"updated_at": "2025-11-15T14:30:00Z"
}
],
"meta": {
"current_page": 1,
"from": 1,
"last_page": 5,
"per_page": 10,
"to": 10,
"total": 47
}
}
```
***
## Template Status Values
| Status | Description |
| ---------- | --------------------------------------------- |
| `PENDING` | Submitted to Meta, awaiting review |
| `APPROVED` | Approved by Meta, ready to use |
| `REJECTED` | Rejected by Meta, cannot be used |
| `UPDATING` | Existing template being updated, under review |
***
## Filter Examples
### Get first page with 25 templates
```bash theme={null}
GET /api/v3/workspaces/{workspace}/templates?per_page=25&page=1
```
### Get all approved templates
Use the response data and filter by `status: "APPROVED"` on the client side, or use [Sync](/pages/endpoints/templates/sync) to update statuses.
***
Use the [Sync endpoint](/pages/endpoints/templates/sync) regularly to update template statuses from Meta.
# Sync Templates
Source: https://api.lancepilot.com/pages/endpoints/templates/sync
POST /workspaces/{workspace}/templates/sync
Synchronize templates in the specified workspace.
## Overview
Synchronize template statuses from Meta (WhatsApp Business API provider). Updates all pending templates with their current approval status.
This endpoint only syncs templates with `PENDING` status. It fetches the latest status from Meta and updates your local database.
***
## How It Works
1. Checks if workspace has any templates with `status: PENDING`
2. Fetches all templates from Meta's API
3. Matches templates by `provider_id`
4. Updates local template statuses (`APPROVED`, `REJECTED`, etc.)
***
## Response
### Success (200 OK)
```json theme={null}
{
"success": true,
"message": "Templates synced successfully"
}
```
### No Pending Templates (404)
```json theme={null}
{
"success": false,
"message": "No pending templates found"
}
```
### Sync Failed (500)
```json theme={null}
{
"success": false,
"message": "Failed to sync the templates"
}
```
***
## When to Use
Sync after creating templates to check if they've been approved
Check status after updating existing templates
Run periodic syncs (e.g., every 30 minutes) for pending templates
Ensure templates are approved before attempting to send
***
## Status Transitions
```mermaid theme={null}
graph LR
A[PENDING] -->|Sync| B[APPROVED]
A -->|Sync| C[REJECTED]
D[UPDATING] -->|Sync| B
D -->|Sync| C
```
***
## Example Usage
### cURL
```bash theme={null}
curl -X POST \
https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync \
-H 'Authorization: Bearer YOUR_API_TOKEN'
```
### JavaScript
```javascript theme={null}
async function syncTemplates(workspaceId) {
const response = await fetch(
`https://lancepilot.com/api/v3/workspaces/${workspaceId}/templates/sync`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${YOUR_API_TOKEN}`
}
}
);
const data = await response.json();
console.log(data.message);
}
```
### Python
```python theme={null}
import requests
def sync_templates(workspace_id, api_token):
url = f"https://lancepilot.com/api/v3/workspaces/{workspace_id}/templates/sync"
headers = {"Authorization": f"Bearer {api_token}"}
response = requests.post(url, headers=headers)
return response.json()
```
***
## Workflow Example
Create a new template via [POST /templates](/pages/endpoints/templates/add)
Response: `status: "PENDING"`
Meta typically reviews templates within 5-30 minutes
Call sync endpoint to update status
```bash theme={null}
POST /workspaces/{workspace}/templates/sync
```
Use [GET /templates](/pages/endpoints/templates/list) to verify new status
Possible results: `APPROVED` or `REJECTED`
***
## Best Practices
Set up a background job to sync every 30 minutes:
```javascript theme={null}
setInterval(() => {
syncTemplates(workspaceId);
}, 30 * 60 * 1000); // 30 minutes
```
```javascript theme={null}
async function syncWithRetry(workspaceId, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const result = await syncTemplates(workspaceId);
if (result.success) return result;
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise(r => setTimeout(r, 5000)); // Wait 5s
}
}
}
```
Check for pending templates before syncing:
```javascript theme={null}
const templates = await getTemplates(workspaceId);
const hasPending = templates.some(t => t.status === 'PENDING');
if (hasPending) {
await syncTemplates(workspaceId);
}
```
***
## Common Issues
**No Pending Templates**
If you receive a 404 error, it means there are no templates with `PENDING` status to sync. This is not an error condition.
**Sync Failed (500)**
This usually indicates:
* Channel connection issues
* Meta API temporarily unavailable
* Invalid channel credentials
Solution: Wait a few minutes and try again, or check channel connection status.
***
**Pro Tip**: Combine sync with webhooks (if available) to get real-time template status updates instead of polling.
# Update Template
Source: https://api.lancepilot.com/pages/endpoints/templates/update
POST /workspaces/{workspace}/templates/{template}
Update an existing template. Supports the same payload structure as template creation.
## Overview
Update an existing WhatsApp message template. The template will be resubmitted to Meta for review.
* Language **cannot be changed** after template creation
* Category may be restricted for approved templates
* Media file only required when changing media type
* Template status changes to `UPDATING` during review
***
## Request Body Schema
Same as [Create Template](/pages/endpoints/templates/add), with these differences:
| Field | Update Restrictions |
| ------------------- | ----------------------------------------------- |
| `language` | **Cannot be changed** (must match original) |
| `category` | May be locked if template is approved |
| `header.media.file` | Required only when changing `header.media.type` |
***
## Example Payloads
### Update Text Content Only
```json theme={null}
{
"name": "welcome_template",
"language": "en",
"category": "MARKETING",
"body": {
"text": "Welcome {{1}}! Your account is now active. Enjoy {{2}}% off your first order!",
"variables": ["Customer", "20"]
},
"footer": "Valid for 30 days"
}
```
### Update Header Media Type
When changing media type (e.g., from image to video), the file is **required**:
```json theme={null}
{
"name": "product_promo",
"language": "en",
"category": "MARKETING",
"header": {
"type": "media",
"media": {
"type": "video",
"file": ""
}
},
"body": {
"text": "Check out our latest product showcase!",
"variables": []
}
}
```
### Keep Same Media Type
When keeping the same media type, file is **optional**:
```json theme={null}
{
"name": "product_promo",
"language": "en",
"category": "MARKETING",
"header": {
"type": "media",
"media": {
"type": "image"
// file not required if keeping same type
}
},
"body": {
"text": "Updated message text here!",
"variables": []
}
}
```
### Add Buttons to Existing Template
```json theme={null}
{
"name": "order_confirmation",
"language": "en",
"category": "UTILITY",
"body": {
"text": "Your order #{{1}} is confirmed!",
"variables": ["ORD-12345"]
},
"buttons": [
{
"type": "URL",
"text": "Track Order",
"url": "https://example.com/track"
},
{
"type": "PHONE_NUMBER",
"text": "Contact Support",
"phone_number": "+1234567890"
}
]
}
```
***
## Response
### Success (200 OK)
```json theme={null}
{
"success": true,
"message": "Template updated successfully and submitted to Meta for review."
}
```
### Validation Error (422)
```json theme={null}
{
"success": false,
"message": "Validation failed",
"errors": {
"language": ["Language cannot be changed after template creation."],
"header.media.file": ["The file field is required when changing media type."]
}
}
```
***
## Template Status Flow
After updating:
1. **PENDING** β Template without `provider_id` (treated as new creation)
2. **UPDATING** β Existing template resubmitted for review
3. **APPROVED** β After Meta approval
4. **REJECTED** β If Meta rejects the changes
Use the [Sync endpoint](/pages/endpoints/templates/sync) to refresh template statuses.
***
## Common Update Scenarios
Update `body.text` and adjust `body.variables` array to match new placeholders:
```json theme={null}
{
"name": "existing_template",
"language": "en",
"category": "MARKETING",
"body": {
"text": "New message with {{1}} and {{2}}",
"variables": ["value1", "value2"]
}
}
```
Set `header` to `null` or omit it:
```json theme={null}
{
"name": "existing_template",
"language": "en",
"category": "UTILITY",
"header": null,
"body": {
"text": "Simple message without header",
"variables": []
}
}
```
Update the entire `buttons` array:
```json theme={null}
{
"name": "existing_template",
"language": "en",
"category": "MARKETING",
"body": {
"text": "Click below for updated link",
"variables": []
},
"buttons": [
{
"type": "URL",
"text": "New Link",
"url": "https://newdomain.com/page"
}
]
}
```
Simply include or omit the `footer` field:
```json theme={null}
{
"name": "existing_template",
"language": "en",
"category": "UTILITY",
"body": {
"text": "Message content here",
"variables": []
},
"footer": "New footer text"
}
```
***
## Important Notes
**Breaking Changes**
* Changing `language` will fail validation
* Approved templates may have category restrictions
* Template name follows same rules as creation (lowercase + underscores only)
**Best Practices**
* Test updates on duplicate templates first
* Keep variable placeholders consistent
* Use [Sync endpoint](/pages/endpoints/templates/sync) to monitor approval status
* Backup original template configuration before major updates
***
For complete payload examples, see [TEMPLATE\_PAYLOADS.md](https://github.com/lancepilot/docs/blob/main/TEMPLATE_PAYLOADS.md).
# Add User
Source: https://api.lancepilot.com/pages/endpoints/users/add
POST /workspaces/{workspace}/users
Create a new user in the specified workspace.
# Delete User
Source: https://api.lancepilot.com/pages/endpoints/users/delete
DELETE /workspaces/{workspace}/users/{user}
Delete a user by ID in the specified workspace.
# Get User
Source: https://api.lancepilot.com/pages/endpoints/users/get
GET /workspaces/{workspace}/users/{user}
Retrieve a specific user by ID in the specified workspace.
# Get Users
Source: https://api.lancepilot.com/pages/endpoints/users/list
GET /workspaces/{workspace}/users
Retrieve all users associated with the specified workspace.
# Update User
Source: https://api.lancepilot.com/pages/endpoints/users/update
POST /workspaces/{workspace}/users/{user}
Update an existing user in the specified workspace.
# Create Workspace
Source: https://api.lancepilot.com/pages/endpoints/workspaces/create
POST /workspaces
Create a new workspace for the authenticated user.
# Delete Workspace
Source: https://api.lancepilot.com/pages/endpoints/workspaces/delete
DELETE /workspaces/{workspace}
Delete a workspace by ID.
# Get Workspace
Source: https://api.lancepilot.com/pages/endpoints/workspaces/get
GET /workspaces/{workspace}
Retrieve details of a specific workspace by its ID.
# Get Workspaces
Source: https://api.lancepilot.com/pages/endpoints/workspaces/list
GET /workspaces
Retrieve a list of all workspaces associated with the authenticated user.
# Get Partner Permissions
Source: https://api.lancepilot.com/pages/endpoints/workspaces/permissions
GET /workspaces/partner/permissions
Retrieve the authenticated userβs default permissions for partner workspaces.
# Update Workspace
Source: https://api.lancepilot.com/pages/endpoints/workspaces/update
PATCH /workspaces/{workspace}
Update the specified workspace.
# Update Partner Permissions
Source: https://api.lancepilot.com/pages/endpoints/workspaces/update-permissions
PATCH /workspaces/partner/permissions
Update the default permissions applied to new partner workspaces created by the user.