Sync Templates
curl --request POST \
--url https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync \
--header 'Authorization: Bearer <token>'import requests
url = "https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {}
}{
"message": "Unauthenticated."
}Templates
Sync Templates
Synchronize templates in the specified workspace.
POST
/
workspaces
/
{workspace}
/
templates
/
sync
Sync Templates
curl --request POST \
--url https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync \
--header 'Authorization: Bearer <token>'import requests
url = "https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {}
}{
"message": "Unauthenticated."
}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
- Checks if workspace has any templates with
status: PENDING - Fetches all templates from Meta’s API
- Matches templates by
provider_id - Updates local template statuses (
APPROVED,REJECTED, etc.)
Response
Success (200 OK)
{
"success": true,
"message": "Templates synced successfully"
}
No Pending Templates (404)
{
"success": false,
"message": "No pending templates found"
}
Sync Failed (500)
{
"success": false,
"message": "Failed to sync the templates"
}
When to Use
After Template Creation
Sync after creating templates to check if they’ve been approved
After Template Update
Check status after updating existing templates
Periodic Checks
Run periodic syncs (e.g., every 30 minutes) for pending templates
Before Sending Messages
Ensure templates are approved before attempting to send
Status Transitions
Example Usage
cURL
curl -X POST \
https://lancepilot.com/api/v3/workspaces/{workspace}/templates/sync \
-H 'Authorization: Bearer YOUR_API_TOKEN'
JavaScript
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
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
1
Create Template
Create a new template via POST /templatesResponse:
status: "PENDING"2
Wait for Review
Meta typically reviews templates within 5-30 minutes
3
Sync Status
Call sync endpoint to update status
POST /workspaces/{workspace}/templates/sync
4
Check Result
Use GET /templates to verify new statusPossible results:
APPROVED or REJECTEDBest Practices
Automatic Sync Schedule
Automatic Sync Schedule
Set up a background job to sync every 30 minutes:
setInterval(() => {
syncTemplates(workspaceId);
}, 30 * 60 * 1000); // 30 minutes
Handle Failures Gracefully
Handle Failures Gracefully
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
}
}
}
Only Sync When Needed
Only Sync When Needed
Check for pending templates before syncing:
const templates = await getTemplates(workspaceId);
const hasPending = templates.some(t => t.status === 'PENDING');
if (hasPending) {
await syncTemplates(workspaceId);
}
Common Issues
No Pending TemplatesIf 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
Pro Tip: Combine sync with webhooks (if available) to get real-time template status updates instead of polling.