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

# Create template

`POST /v1/messaging/whatsapp/templates`

## Request

- Base URL: `https://apihub.co.il`
- URL: `https://apihub.co.il/v1/messaging/whatsapp/templates`
- Auth: HTTP bearer

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/


**Billing:** Request; paid actions are priced in credits (see GET /v1/messaging/prices) · **Rate limit:** 60/min

## Headers

- `Idempotency-Key` string
- `X-Tag` string

## Request body

- object
  - `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)
  - `accountId` string, required: WhatsApp account ID
  - `components` union[]: Template components (header, body, footer, buttons, carousel, limited_time_offer). Required for custom templates, omit when using library_template_name.
    - union
      - object
        - `text` string: Header text (may include {{1}} variable). Used when format is TEXT.
        - `type` 'header', required
        - `format` 'text' | 'image' | 'video' | 'gif' | 'document' | 'location', required
      - object
        - `text` string, required: Body text with optional {{n}} variables
        - `type` 'body', required
        - `add_security_recommendation` boolean: Add security recommendation text (authentication templates only)
      - object
        - `text` string: Static footer text
        - `type` 'footer', required
        - `code_expiration_minutes` integer: OTP code expiry in minutes (authentication templates only)
      - object
        - `type` 'buttons', required
        - `buttons` object[], required
          - `url` string, uri: Required when type is URL
          - `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).
          - `type` 'quick_reply' | 'url' | 'phone_number' | 'otp' | 'copy_code' | 'flow' | 'mpm' | 'catalog', required
          - `flow_id` string
          - `otp_type` 'copy_code' | 'one_tap' | 'zero_tap': Required when type is otp
          - `flow_json` string
          - `flow_name` string
          - `flow_action` string
          - `package_name` string
          - `phone_number` string: Required when type is phone_number
          - `autofill_text` string
          - `signature_hash` string
          - `navigate_screen` string
      - object
        - `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` union[], 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
              - …
      - object
        - `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.
  - `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.
  - `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.
  - `message_send_ttl_seconds` integer: Delivery validity window in seconds: a message not delivered within it is dropped. Range depends on category: AUTHENTICATION 30 to 900, UTILITY 30 to 43200 (12h), MARKETING 43200 to 2592000 (30 days); -1 (create only) keeps the 30-day default on AUTHENTICATION and UTILITY. Meta defaults to 600 for AUTHENTICATION and 30 days otherwise. If Meta later recategorises the template, it clears the TTL (read it back to check).
  - `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).
    - `url` object
      - `base_url` string
    - `type` 'quick_reply' | 'url' | 'phone_number'
    - `phone_number` string

## Response `200`

Completed

- object
  - `id` string: Execution id — stable across internal retries; use it with GET /v1/executions/{id}
  - `status` 'pending' | 'processing' | 'completed' | 'partial' | 'failed' | 'cancelled' | 'timeout'
  - `operation` string
  - `tag` string, nullable: Your X-Tag, if sent
  - `created_at` string, date-time
  - `completed_at` string, date-time, nullable
  - `output` object: Operation result (see each operation). While a Studio render is processing: `stage` (queued · transcribing · downloading · preparing · cleaning_voice · mixing_audio · rendering · finishing), `phase` (the engine's: download · prepare · voice · audio · encode · qa · upload, or null), `progress` (a percent, 0–100) and `progress_fraction` (0–1), `eta_seconds` (seconds left, never below 0) and `estimate_seconds`
    - `success` boolean
    - `template` object
      - `id` string
      - `name` string
      - `status` string: APPROVED for library templates, PENDING for custom
      - `category` string
      - `language` string
      - `message_send_ttl_seconds` integer: Echoed when supplied on the request.
  - `error` string, nullable
  - `usage` object
    - `credits_charged` number, nullable
    - `credits_reserved` number
    - `estimated_credits` number
    - `cost_source` 'provider_reported' | 'calculated' | 'estimated' | 'null', nullable
    - `provider_usage` object, nullable: Normalised consumption, e.g. { VIDEO_SECOND: 22.4 }
  - `balance` object
    - `available` number
    - `reserved` number

## Other responses

- `400`: Invalid input
- `402`: Insufficient credits / project budget
- `404`: Resource not found (or not yours)
- `429`: Rate limited
- `503`: Service temporarily paused

---

[API](https://skmtc.dev/apihub/apis/apihub-one-api-for-chat-image-video-ai.md) · [All operations](https://skmtc.dev/apihub/apis/apihub-one-api-for-chat-image-video-ai/llms.txt) · [OpenAPI document](https://skmtc.dev/apihub/apis/apihub-one-api-for-chat-image-video-ai/revisions/a8caa42835ce?raw)
