Pagination: The API returns up to limit templates per call (default 10, max 100). If more templates exist, the response includes a cursor value. Pass it as after in the next call to fetch the next page. Repeat until cursor is null.
When to Use
- Template inventory sync: A nightly scheduled workflow calls this node with paginated iteration to build a local database snapshot of all templates with their current approval statuses.
- Duplicate name detection: Before creating a new template, a workflow lists all existing templates to check whether the intended name is already taken, avoiding a 132000 error from
template/create.
- Bulk status audit: A compliance workflow lists all templates and filters for
REJECTED status, then notifies the template owner for each rejected template with the template name and ID.
- Pending template monitoring: A monitoring workflow lists all templates and alerts the operations team if any have been in
PENDING status for more than 48 hours.
- Template selection UI data: A workflow that builds dynamic send configuration fetches the template list to populate a selection menu presented to a human-in-the-loop approval step.
Configuration
Connection
| Field | Required | Description |
accessToken | Required | Permanent System User access token from Meta Business Manager. Store in BizFirst Credentials Manager. |
phoneNumberId | Required | WhatsApp Business phone number ID. Used to identify the associated Business Account for the template list. |
apiVersion | Optional | Meta Graph API version, e.g. v18.0. Defaults to v18.0. |
Operation
| Field | Required | Description |
limit | Optional | Number of templates to return per page. Default is 10, maximum is 100. Higher values reduce the number of API calls needed to paginate through large template libraries. |
after | Optional | Pagination cursor from the previous call's cursor output. Omit on the first call. Pass on subsequent calls to fetch the next page. |
Sample Configuration
{
"resource": "template",
"operation": "getMany",
"accessToken": "{{ $credentials.whatsAppToken }}",
"phoneNumberId": "123456789012345",
"limit": 50
}
Validation Errors
| Error | Cause |
accessToken is required | The accessToken field is empty or missing. |
phoneNumberId is required | The phoneNumberId field is empty or missing. |
100 (Meta) | The business account associated with the phone number ID does not exist or the token lacks access. |
190 (Meta) | Access token expired or invalid. |
200 (Meta) | Insufficient permissions. Token requires whatsapp_business_management scope. |
timeout | The request timed out. Reduce the limit value and retry. |
Output
Success Port
Fires when the template list is successfully retrieved. The templates array contains summary objects for each template on the current page.
| Field | Type | Description |
templates | array | Array of template summary objects, each with id, name, language, status (approval status), and category. |
cursor | string | Pagination cursor for the next page. null when there are no more pages. |
status | string | "success" on success. |
errorCode | string | Empty on success. |
errorMessage | string | Empty on success. |
rawResponse | string | Full raw JSON response from Meta. |
Error Port
| Field | Type | Description |
status | string | "failed" or "error". |
errorCode | string | Meta error code or BizFirst internal code. |
errorMessage | string | Human-readable description of the failure. |
rawResponse | string | Raw API error JSON for diagnostics. |
Sample Output
{
"templates": [
{ "id": "987654321098765", "name": "order_shipped_notification", "language": "en_US", "status": "APPROVED", "category": "UTILITY" },
{ "id": "876543210987654", "name": "summer_sale_2024", "language": "en_US", "status": "PENDING", "category": "MARKETING" },
{ "id": "765432109876543", "name": "otp_login_v1", "language": "en_US", "status": "APPROVED", "category": "AUTHENTICATION" }
],
"cursor": "QVFIUmtLbVEzd2tEOHlJdE9RWVZX...",
"status": "success",
"errorCode": null,
"errorMessage": null,
"rawResponse": "{\"data\":[...],\"paging\":{\"cursors\":{\"after\":\"QVFIUmtLbVEzd2tEOH...\"}}}"
}
Expression Reference
| Value | Expression | Notes |
| Templates array | {{ $output.getManyTemplates.templates }} | Iterate with a Loop node. Each item has id, name, language, status, category. |
| Next page cursor | {{ $output.getManyTemplates.cursor }} | Pass as after on the next call. Null when pagination is complete. |
| Template count | {{ $output.getManyTemplates.templates.length }} | Number of templates returned on this page. |
| Status | {{ $output.getManyTemplates.status }} | "success" on success. |
Node Policies & GuardRails
| Policy Area | Recommendation |
| Full pagination | If you need a complete inventory, use a Loop node with a while-cursor condition to paginate through all pages. Do not assume a single call returns all templates. |
| Rate limiting | For large template libraries, space paginated calls with a Delay node (100–200ms) to avoid hitting Meta's per-minute rate limit. |
| Summary vs. detail | This node returns summary data only — it does not include componentsJson. For full component details, follow up with individual template/get calls on specific IDs. |
| Credential storage | Store the access token in BizFirst Credentials Manager. Never paste it into node configuration as plain text. |
| Error port handling | Always connect the error port. A permissions error (200) on this node means the token scope needs to be updated in Meta Business Manager. |
Examples
Paginated Full Inventory Sync
// First call (no cursor):
{
"resource": "template",
"operation": "getMany",
"accessToken": "{{ $credentials.whatsAppToken }}",
"phoneNumberId": "123456789012345",
"limit": 100
}
// Subsequent calls (with cursor from previous output):
{
"resource": "template",
"operation": "getMany",
"accessToken": "{{ $credentials.whatsAppToken }}",
"phoneNumberId": "123456789012345",
"limit": 100,
"after": "{{ $session.nextPageCursor }}"
}
A nightly inventory workflow loops until cursor is null. Each batch of template summaries is upserted into a local database table, giving the platform a near-real-time view of all templates and their approval statuses.
Filter REJECTED Templates for Alert
{
"resource": "template",
"operation": "getMany",
"accessToken": "{{ $credentials.whatsAppToken }}",
"phoneNumberId": "123456789012345",
"limit": 100
}
After fetching the list, a Function node filters templates for items where status == "REJECTED". If any are found, a Slack notification node sends the list to the #whatsapp-templates channel with the template IDs and names.
Duplicate Name Check Before Creation
{
"resource": "template",
"operation": "getMany",
"accessToken": "{{ $credentials.whatsAppToken }}",
"phoneNumberId": "123456789012345",
"limit": 100
}
Before creating a new template, a Function node scans the returned templates array for a name match against the intended new template name. If a match is found for the target language, the workflow skips creation and reuses the existing template ID. Otherwise it proceeds to template/create.