Review reset: Updating a template's components resets its approval status to PENDING. Any ongoing send campaigns using this template will continue to work until the next review cycle begins, but plan updates outside of active campaign windows to avoid disruption.
When to Use
- Content corrections: A template with a typo or outdated URL was approved. Rather than deleting and recreating it, a workflow calls this node to fix the BODY text while preserving the template ID stored across all integrations.
- Seasonal content refresh: A MARKETING template body is updated each season (summer discount %, changed product names) via this node, avoiding the need to create and track new template IDs for each seasonal variant.
- Button URL changes: A product landing page URL changes. A workflow updates the BUTTONS component of the affected template to point to the new URL without requiring a full template replacement.
- Automated template patching: A CI/CD deployment pipeline detects that a configuration value referenced in a template body has changed and automatically updates the template components to reflect the new value.
- Footer or disclaimer updates: A legal team requires a new compliance disclaimer to appear in the FOOTER of all MARKETING templates. A workflow loops through affected template IDs and updates each one.
Configuration
Connection
| Field | Required | Description |
accessToken | Required | Permanent System User access token with whatsapp_business_management permission. Store in BizFirst Credentials Manager. |
phoneNumberId | Required | WhatsApp Business phone number ID associated with the account owning the template. |
apiVersion | Optional | Meta Graph API version, e.g. v18.0. Defaults to v18.0. |
Operation
| Field | Required | Description |
templateId | Required | The ID of the template to update. The template must belong to the business account associated with the access token. |
components | Required | JSON array of the new component objects. This replaces the entire component structure of the template. The format is identical to the components field in template/create. |
Sample Configuration
{
"resource": "template",
"operation": "update",
"accessToken": "{{ $credentials.whatsAppToken }}",
"phoneNumberId": "123456789012345",
"templateId": "987654321098765",
"components": "[{\"type\":\"HEADER\",\"format\":\"TEXT\",\"text\":\"Your Order Has Shipped\"},{\"type\":\"BODY\",\"text\":\"Hi {{1}}, your order #{{2}} shipped on {{3}}. Estimated delivery: {{4}}. Track at: https://track.example.com/{{5}}\"},{\"type\":\"FOOTER\",\"text\":\"BizFirstAI Commerce — Updated June 2024\"}]"
}
Validation Errors
| Error | Cause |
accessToken is required | The accessToken field is empty or missing. |
phoneNumberId is required | The phoneNumberId field is empty or missing. |
templateId is required | The templateId field is empty or missing. |
components is required | The components field is empty or missing. |
invalid_json | The components value is not valid JSON. |
100 (Meta) | Template ID not found or does not belong to the calling account. |
132005 (Meta) | Updated body text exceeds the 1024-character limit. |
132012 (Meta) | Updated components contain disallowed content. |
Output
Success Port
Fires when Meta accepts the update. The template is now in PENDING status awaiting re-review. Use template/get to track approval progress.
| Field | Type | Description |
id | string | The template ID that was updated. |
templateStatus | string | null after update (status is implicitly PENDING). Use template/get to confirm current status. |
status | string | "updated" on success. |
errorCode | string | Empty on success. |
errorMessage | string | Empty on success. |
rawResponse | string | Full raw JSON response from Meta, typically {"success":true}. |
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
{
"id": "987654321098765",
"templateStatus": null,
"status": "updated",
"errorCode": null,
"errorMessage": null,
"rawResponse": "{\"success\":true}"
}
Expression Reference
| Value | Expression | Notes |
| Template ID | {{ $output.updateTemplate.id }} | Use to chain directly to template/get to poll for re-approval. |
| Operation status | {{ $output.updateTemplate.status }} | "updated" confirms the API call succeeded. Template review status must be checked separately. |
| Error code | {{ $output.updateTemplate.errorCode }} | Non-null on error port. Code 100 means the template ID does not exist. |
| Raw response | {{ $output.updateTemplate.rawResponse }} | Meta returns {"success":true} on successful updates. |
Node Policies & GuardRails
| Policy Area | Recommendation |
| Review reset awareness | Any update triggers a full Meta review. Schedule updates outside of active campaigns and monitor approval status via template/get before resuming sends. |
| Full component replacement | The components field replaces the entire component structure. Always include all components (HEADER, BODY, FOOTER, BUTTONS) even if only one is changing. |
| Backup before update | Call template/get before updating to retrieve and store the current component JSON. This provides a rollback reference if the update causes a rejection. |
| Credential storage | Store the access token in BizFirst Credentials Manager. |
| Error port handling | Always connect the error port. A failed update that goes undetected may result in a campaign sending with outdated content. |
| Compliance audit | Log all template updates — template ID, timestamp, previous component JSON, new component JSON, and the triggering workflow — for regulatory audit purposes. |
Examples
Fix a Typo in the Body Text
{
"resource": "template",
"operation": "update",
"accessToken": "{{ $credentials.whatsAppToken }}",
"phoneNumberId": "123456789012345",
"templateId": "987654321098765",
"components": "[{\"type\":\"BODY\",\"text\":\"Hi {{1}}, your appointment with {{2}} is confirmed for {{3}} at {{4}}. Reply CANCEL to cancel.\"}]"
}
A template was approved with a punctuation error. The workflow first retrieves the current components via template/get, stores them as a backup, applies the text correction, and updates. A template/get polling loop then monitors for re-approval before the next campaign batch.
Update Button URL After Domain Migration
{
"resource": "template",
"operation": "update",
"accessToken": "{{ $credentials.whatsAppToken }}",
"phoneNumberId": "123456789012345",
"templateId": "{{ $input.templateId }}",
"components": "[{\"type\":\"BODY\",\"text\":\"Your order #{{1}} is ready! Track it below.\"},{\"type\":\"BUTTONS\",\"buttons\":[{\"type\":\"URL\",\"text\":\"Track Order\",\"url\":\"https://new-domain.example.com/track/{{1}}\"}]}]"
}
A domain migration event triggers a workflow that iterates over all template IDs containing the old tracking URL, updates each one with the new domain, and logs the result. The workflow then starts an approval monitoring loop for each updated template.
Bulk Footer Compliance Update
// Loop node iterates over list of templateIds to update
{
"resource": "template",
"operation": "update",
"accessToken": "{{ $credentials.whatsAppToken }}",
"phoneNumberId": "123456789012345",
"templateId": "{{ $loop.currentItem.id }}",
"components": "{{ $loop.currentItem.updatedComponentsJson }}"
}
A legal compliance workflow prepares an updated component JSON for each affected template (with the new FOOTER disclaimer text), then loops through the list calling this node for each. Results are collected and a summary report is emailed to the legal team showing how many templates were updated successfully and how many failed.