List WhatsApp Templates API
Retrieve the WhatsApp message templates configured for your business. Use this endpoint to inspect template approval status, language, and components, and to find approved templates for campaign creation.
Endpoint
GET https://client-api.e-so.in/engage/v1/wa-templatesAuthentication is required. Results are scoped to the business associated with the access token. The endpoint supports pagination and selective field retrieval.
Authentication
Provide a business access token using either header:
| Header | Value |
|---|---|
Authorization | Bearer YOUR_TOKEN |
auth-key | YOUR_TOKEN |
If both headers are supplied, Authorization takes precedence. A missing, invalid, or expired token returns 401 Unauthorized.
Request parameters
This endpoint does not require a request body.
| Query parameter | Type | Required | Description |
|---|---|---|---|
page | Integer | No | Page number to retrieve. |
limit | Integer | No | Number of templates per page. |
fields | String | No | Comma-separated list of fields to return. The name field is always included. |
Pagination defaults, maximum page size, and behavior when fields is omitted are not specified in the supplied reference.
Available fields
id, business_id, name, category, status, template_type, language, wa_template_id, template_file, created_at, quality_score, rejected_reason, components, description
An unsupported field name returns 422.
Example request
curl "https://client-api.e-so.in/engage/v1/wa-templates?page=1&limit=20&fields=id,name,category,status,language,components" \
-H "Authorization: Bearer YOUR_TOKEN"Successful response
HTTP status: 200 OK
The following example corresponds to the fields selected above:
{
"status": 200,
"success": true,
"message": "success",
"payload": {
"data": [
{
"id": 123,
"name": "order_confirmation",
"category": "MARKETING",
"status": "APPROVED",
"language": "en",
"components": [
{
"type": "BODY",
"text": "Hello {{1}}"
}
]
}
],
"meta": {
"total": 18,
"per_page": 20,
"current_page": 1,
"last_page": 1,
"first_page": 1,
"first_page_url": "/?page=1",
"last_page_url": "/?page=1",
"next_page_url": null,
"previous_page_url": null
}
}
}Response structure
| Field | Type | Description |
|---|---|---|
status | Number | Response status code; 200 on success. |
success | Boolean | true on success. |
message | String | success on a successful request. |
payload | Object | Paginated result. |
payload.data | Array of objects | Templates for the current page. With selective fields, contains the requested fields plus name. |
payload.data[].status | String | Template approval status, such as APPROVED, PENDING, or REJECTED, when selected. |
payload.meta | Object | Pagination metadata. |
Pagination metadata
| Field | Description |
|---|---|
total | Total number of matching templates. |
per_page | Page size. |
current_page | Current page number. |
first_page, last_page | First and last page numbers. |
first_page_url, last_page_url | Links to the first and last pages. |
next_page_url, previous_page_url | Links to adjacent pages; null when unavailable. |
Retrieve additional pages using the page query parameter. Client-side filtering applies only to the page retrieved; paginate through all results if you need every approved template.
Errors
| HTTP status | Cause | Recommended action |
|---|---|---|
401 | Token is missing, invalid, or expired. | Check the authentication header and use a valid business token. |
422 | fields contains an unsupported field. | Use only the available fields listed above. |
429 | Request rate limit exceeded. | Back off before retrying. |
500 | Unexpected server error. | Retry with backoff; contact support if the issue persists. |
Rate limiting applies through defaultRateLimiter. Numerical limits, retry timing, and error response schemas are not specified in the supplied reference.
Code examples
JavaScript
async function listApprovedTemplates(token, page = 1) {
const params = new URLSearchParams({
page: String(page),
limit: "20",
fields: "id,name,status,language,components",
});
const response = await fetch(
`https://client-api.e-so.in/engage/v1/wa-templates?${params}`,
{ headers: { Authorization: `Bearer ${token}` } }
);
if (!response.ok) {
throw new Error(`Template request failed: HTTP ${response.status}`);
}
const body = await response.json();
return {
templates: body.payload.data.filter(
(template) => template.status === "APPROVED"
),
meta: body.payload.meta,
};
}Python
Requires the requests package.
import requests
def list_approved_templates(token, page=1):
response = requests.get(
"https://client-api.e-so.in/engage/v1/wa-templates",
params={
"page": page,
"limit": 20,
"fields": "id,name,status,language",
},
headers={"Authorization": f"Bearer {token}"},
timeout=30,
)
response.raise_for_status()
payload = response.json()["payload"]
return {
"templates": [
template for template in payload["data"]
if template["status"] == "APPROVED"
],
"meta": payload["meta"],
}Both examples return approved templates from one page and retain pagination metadata for subsequent requests.
Use a template in a campaign
- Request templates with at least
id,name,statusinfields. - Choose a template whose
statusisAPPROVED. - Retrieve its variables using
GET /engage/v1/wa-templates/{templateId}/variables. - Use those variables to build the campaign's
column_mappings. - Create the campaign using
POST /engage/v1/campaigns, passing the selected template'sidas the campaign'swa_template_id.
The campaign's wa_template_id uses the template record's id, as described in the supplied reference. Do not substitute the template record's separately named wa_template_id field.
Related endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /engage/v1/wa-templates/{templateId}/variables | Retrieve template variables for campaign column mappings. |
POST | /engage/v1/campaigns | Create a campaign using an approved template. |
Support
When contacting support, include the request URL and query parameters, the response status and message, and the UTC timestamp. Redact access tokens and other credentials.
Documentation prepared from the supplied API reference. Endpoint behavior has not been independently tested.