---
title: "Update template"
method: PATCH
path: "/v1/whatsapp/templates/{templateName}"
tags: ["WhatsApp"]
---

# Update template

`PATCH /v1/whatsapp/templates/{templateName}`

Update one variant's components. Name, language and category cannot change after creation.

Meta stores one template per **name + language**, so a name identifies a family of variants,
each with its own Meta id. Pass `language` to address one variant. Without it, a name with a
single variant resolves to that variant; a name with several returns `409 ambiguous_template`
with `details.languages`. A bare language (`es`) matches a single regional variant (`es_ES`);
if the family has several regional variants for it, that is also a 409. A full code (`es_ES`)
must match exactly. Variants in `PENDING_DELETION` are not part of the family.

Meta only allows editing templates in `APPROVED`, `REJECTED` or `PAUSED` state; an approved
template can be edited once per 24 hours and up to 10 times per 30 days. A successful update
sends the variant back to Meta for review, so the `status` returned here is normally `PENDING`.
The final outcome arrives on the `whatsapp.template.status_updated` webhook (which carries the
variant's `templateId` and `language`). A variant already in `PENDING` cannot be edited again
until Meta finishes reviewing it.

## Path parameters

- `templateName` string, required

## Request body

- object
  - `accountId` string, required — WhatsApp social account ID
  - `language` string — Language code of the variant to edit (e.g. en_US, es, pt_BR). Required when the family has several languages. Body only: a language query parameter on PATCH is a 400.
  - `components` WhatsAppTemplateComponent[], required — Updated template components
    - union
      - WhatsAppHeaderComponent
        - `type` 'header', required
        - `format` 'text' | 'image' | 'video' | 'gif' | 'document' | 'location', required
        - `text` string — Header text (may include {{1}} variable). Used when format is TEXT.
        - `example` object
          - `header_text` string[] — Sample values for header text variables
          - `header_text_named_params` WhatsAppNamedParamExample[] — Sample values for NAMED header variables (templates using {{customer_name}}-style tokens with parameter_format: NAMED).
            - `param_name` string, required — Variable name as it appears in the text, without braces (e.g. customer_name for {{customer_name}}).
            - `example` string, required — Sample value for this variable.
          - `header_handle` string[] — When the header format is a media type (image, video, gif, document), provide a public URL here. Zernio will download and upload it to WhatsApp on your behalf, replacing it with the internal file handle before creating the template.
      - WhatsAppBodyComponent
        - `type` 'body', required
        - `text` string, required — Body text with optional {{n}} variables
        - `add_security_recommendation` boolean — Add security recommendation text (authentication templates only)
        - `example` object
          - `body_text` array[] — Sample values for body variables (array of arrays)
            - string[]
          - `body_text_named_params` WhatsAppNamedParamExample[] — Sample values for NAMED body variables (templates using {{customer_name}}-style tokens with parameter_format: NAMED).
            - `param_name` string, required — Variable name as it appears in the text, without braces (e.g. customer_name for {{customer_name}}).
            - `example` string, required — Sample value for this variable.
      - WhatsAppFooterComponent
        - `type` 'footer', required
        - `text` string — Static footer text
        - `code_expiration_minutes` integer — OTP code expiry in minutes (authentication templates only)
      - WhatsAppButtonsComponent
        - `type` 'buttons', required
        - `buttons` WhatsAppTemplateButton[], required
          - `type` 'quick_reply' | 'url' | 'phone_number' | 'otp' | 'copy_code' | 'flow' | 'mpm' | 'catalog', required
          - `text` string — Visible button label. Required for all types except copy_code (whose label is fixed by WhatsApp) and otp (omit it and WhatsApp supplies its own label, localized to the template language; an English label on a non-English template is rejected).
          - `url` string, uri — Required when type is URL
          - `example` unknown
          - `phone_number` string — Required when type is phone_number
          - `otp_type` 'copy_code' | 'one_tap' | 'zero_tap' — Required when type is otp
          - `autofill_text` string
          - `package_name` string
          - `signature_hash` string
          - `flow_id` string
          - `flow_name` string
          - `flow_json` string
          - `flow_action` string
          - `navigate_screen` string
      - WhatsAppCarouselComponent
        - `type` 'carousel', required
        - `cards` object[], required — 2-10 cards. Meta requires all cards to share the same component structure; a mismatch surfaces as a rejected_reason. MARKETING category only.
          - `components` WhatsAppCarouselCardComponent[], required — Per-card components. Each card carries its own media header + optional body + up to 2 buttons. Footer and nested carousel are not allowed inside cards.
            - union
              - …
      - WhatsAppLimitedTimeOfferComponent
        - `type` 'limited_time_offer', required
        - `limited_time_offer` object, required
          - `text` string, required — Short offer label (<=16 chars). MARKETING only.
          - `has_expiration` boolean — Toggles the countdown timer. The actual coupon code + expiry are bound at SEND time, not here.

## Response `200`

Template updated successfully

- object
  - `success` boolean
  - `template` object
    - `id` string — Meta id of the edited variant.
    - `name` string
    - `language` string — The variant that was edited.
    - `status` string — Approval state read back from Meta after the update, normally PENDING. If the state cannot be read back, the last known status is returned instead.

## Other responses

- `400` — Invalid request
- `401` — Unauthorized
- `404` — Account not found, or no template with that name (and language, when given) (code template_not_found).
- `409` — The template name exists in several languages and no language was given (code ambiguous_template). details.languages lists them.
- `502` — Meta rejected the update or was unreachable. Meta 4xx statuses are forwarded as-is.

## Changes

- **2026-08-29** `e6f7a453bfb1` — 1 breaking, 4 info
  - removed the media type `application/json` for the response with the status `404`
  - added the new optional request property `language`
  - added the media type `application/json` for the response with the status `400`
  - added the non-success response with the status `409`
  - …1 more

[Change history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/whatsapp/templates/:templateName/patch.md)

---

[API](https://skmtc.dev/zernio/apis/zernio-api.md) · [All operations](https://skmtc.dev/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/zernio/zernio-api/revisions/bdd771244d76/schema)
