---
title: "Create template"
method: POST
path: "/v1/whatsapp/templates"
tags: ["WhatsApp"]
---

# Create template

`POST /v1/whatsapp/templates`

Create a new message template. Supports two modes:

Custom template: Provide components with your own content. Submitted to Meta for review (can take up to 24h).

Library template: Provide library_template_name instead of components to use a pre-built template
from Meta's template library. Library templates are pre-approved (no review wait). You can optionally
customize parameters and buttons via library_template_body_inputs and library_template_button_inputs.

Browse available library templates at: https://business.facebook.com/wa/manage/message-templates/

## Request body

- object
  - `accountId` string, required — WhatsApp social account ID
  - `name` string, required — Template name (lowercase, letters/numbers/underscores, must start with a letter)
  - `category` 'AUTHENTICATION' | 'MARKETING' | 'UTILITY', required — Template category
  - `language` string, required — Template language code (e.g., en_US)
  - `parameter_format` 'POSITIONAL' | 'NAMED' | 'positional' | 'named' — Variable style: POSITIONAL ({{1}}, the default) or NAMED ({{customer_name}}). Named templates provide examples via body_text_named_params / header_text_named_params. Inferred as NAMED when omitted but a named-params example is present.
  - `components` WhatsAppTemplateComponent[] — Template components (header, body, footer, buttons, carousel, limited_time_offer). Required for custom templates, omit when using library_template_name.
    - 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.
  - `library_template_name` string — Name of a pre-built template from Meta's template library (e.g., "appointment_reminder", "auto_pay_reminder_1", "address_update"). When provided, the template is pre-approved by Meta with no review wait. Omit components when using this field.
  - `library_template_body_inputs` object — Optional body customizations for library templates. Available options depend on the template (e.g., add_contact_number, add_learn_more_link, add_security_recommendation, add_track_package_link, code_expiration_minutes).
  - `library_template_button_inputs` object[] — Optional button customizations for library templates. Each item specifies button type and configuration (e.g., URL, phone number, quick reply).
    - `type` 'quick_reply' | 'url' | 'phone_number'
    - `url` object
      - `base_url` string
    - `phone_number` string

## Response `200`

Template created (pre-approved for library templates, pending review for custom)

- object
  - `success` boolean
  - `template` object
    - `id` string
    - `name` string
    - `status` string — APPROVED for library templates, PENDING for custom
    - `category` string
    - `language` string

## Other responses

- `400` — Validation error (invalid name format, missing fields, invalid category)
- `401` — Unauthorized
- `404` — WhatsApp account not found

---

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