> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zavu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Create template

> Create a WhatsApp message template. Note: Templates must be approved by Meta before use.



## OpenAPI

````yaml /openapi.json post /v1/templates
openapi: 3.0.3
info:
  title: Zavu Unified Messaging Layer API
  version: 0.2.0
  description: >
    Unified multi-channel messaging API for Zavu.


    Supported channels:

    - **SMS**: Simple text messages

    - **WhatsApp**: Rich messaging with media, buttons, lists, CTA URL buttons,
    and templates

    - **Telegram**: Bot messaging with text, media, and interactive elements

    - **Email**: Transactional emails via Amazon SES


    Design goals:

    - Simple `send()` entrypoint for developers

    - Project-level authentication via Bearer token

    - Support for all WhatsApp message types (text, image, video, audio,
    document, sticker, location, contact, buttons, list, cta_url, reaction,
    template)

    - If a non-text message type is sent, WhatsApp channel is used automatically

    - 24-hour WhatsApp conversation window enforcement

    - Universal `to` field accepts phone numbers (E.164), email addresses, or
    numeric chat IDs (Telegram/Instagram)
servers:
  - url: https://api.zavu.dev
security:
  - bearerAuth: []
paths:
  /v1/templates:
    post:
      summary: Create template
      description: >-
        Create a WhatsApp message template. Note: Templates must be approved by
        Meta before use.
      operationId: createTemplate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TemplateCreateRequest'
            example:
              name: order_confirmation
              language: en
              body: >-
                Hi {{1}}, your order {{2}} has been confirmed and will ship
                within 24 hours.
              whatsappCategory: UTILITY
              variables:
                - customer_name
                - order_id
      responses:
        '201':
          description: Template created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Template'
        '400':
          description: Invalid template.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - bearerAuth: []
components:
  schemas:
    TemplateCreateRequest:
      type: object
      required:
        - name
        - language
        - body
      properties:
        name:
          type: string
        language:
          type: string
          default: en
        body:
          type: string
          description: Default template body. Used when no channel-specific body is set.
        smsBody:
          type: string
          description: Channel-specific body for SMS. Falls back to `body` if not set.
        telegramBody:
          type: string
          description: Channel-specific body for Telegram. Falls back to `body` if not set.
        instagramBody:
          type: string
          description: >-
            Channel-specific body for Instagram. Falls back to `body` if not
            set.
        whatsappCategory:
          $ref: '#/components/schemas/WhatsAppCategory'
        headerType:
          type: string
          description: Type of header for the template.
          enum:
            - text
            - image
            - video
            - document
        headerContent:
          type: string
          description: Header content (text string or media URL).
        footer:
          type: string
          description: Footer text for the template.
          maxLength: 60
        variables:
          type: array
          items:
            type: string
        buttons:
          type: array
          description: Template buttons (max 3).
          maxItems: 3
          items:
            type: object
            required:
              - type
              - text
            properties:
              type:
                type: string
                enum:
                  - quick_reply
                  - url
                  - phone
                  - otp
              text:
                type: string
                maxLength: 25
              url:
                type: string
                format: uri
                description: >-
                  Button destination. Use `{{1}}` exactly once for a dynamic URL
                  (e.g. `https://example.com/orders/{{1}}`); WhatsApp only
                  accepts the strict `{{1}}` form. Static URLs must not contain
                  any `{{...}}` placeholder.
              example:
                type: string
                description: >-
                  Sample value Meta uses to review templates with a dynamic URL
                  button. Substituted into `{{1}}` of the URL when the template
                  is submitted to Meta. Only meaningful when `url` contains
                  `{{1}}`; ignored for static URLs.
                example: ORD-12345
              phoneNumber:
                type: string
              otpType:
                type: string
                enum:
                  - COPY_CODE
                  - ONE_TAP
                description: >-
                  Required when type is 'otp'. COPY_CODE shows copy button,
                  ONE_TAP enables Android autofill.
              packageName:
                type: string
                description: Android package name. Required for ONE_TAP buttons.
              signatureHash:
                type: string
                description: Android app signature hash. Required for ONE_TAP buttons.
        addSecurityRecommendation:
          type: boolean
          description: >-
            Add 'Do not share this code' disclaimer. Only for AUTHENTICATION
            templates.
        codeExpirationMinutes:
          type: integer
          minimum: 1
          maximum: 90
          description: Code expiration time in minutes. Only for AUTHENTICATION templates.
    Template:
      type: object
      required:
        - id
        - name
        - language
        - body
        - category
      properties:
        id:
          type: string
        name:
          type: string
          description: >-
            Template name. For WhatsApp, must match the approved template name
            in Meta.
          example: order_confirmation
        language:
          type: string
          description: Language code.
          example: en
        body:
          type: string
          description: >-
            Default template body with variables: {{1}}, {{2}}, or named
            variables like {{contact.first_name}}. Used when no channel-specific
            body is set.
          example: Hi {{1}}, your order {{2}} has shipped.
        smsBody:
          type: string
          description: >-
            Channel-specific body for SMS messages. Falls back to `body` if not
            set.
        telegramBody:
          type: string
          description: >-
            Channel-specific body for Telegram messages. Falls back to `body` if
            not set.
        instagramBody:
          type: string
          description: >-
            Channel-specific body for Instagram messages. Falls back to `body`
            if not set.
        category:
          $ref: '#/components/schemas/WhatsAppCategory'
        status:
          type: string
          enum:
            - draft
            - pending
            - approved
            - rejected
          default: draft
        variables:
          type: array
          items:
            type: string
          description: List of variable names for documentation.
        headerType:
          type: string
          description: Type of header (text, image, video, document).
        headerContent:
          type: string
          description: Header content (text or media URL).
        footer:
          type: string
          description: Footer text for the template.
        buttons:
          type: array
          description: Template buttons.
          items:
            type: object
            properties:
              type:
                type: string
                enum:
                  - quick_reply
                  - url
                  - phone
                  - otp
              text:
                type: string
              url:
                type: string
              example:
                type: string
                description: >-
                  Sample value used to substitute `{{1}}` in the URL when
                  submitting the template to Meta for review. Only present for
                  dynamic URL buttons.
              phoneNumber:
                type: string
              otpType:
                type: string
                enum:
                  - COPY_CODE
                  - ONE_TAP
                description: OTP button type. Required when type is 'otp'.
              packageName:
                type: string
                description: Android package name. Required for ONE_TAP buttons.
              signatureHash:
                type: string
                description: Android app signature hash. Required for ONE_TAP buttons.
        addSecurityRecommendation:
          type: boolean
          description: >-
            Add 'Do not share this code' disclaimer. Only for AUTHENTICATION
            templates.
        codeExpirationMinutes:
          type: integer
          minimum: 1
          maximum: 90
          description: Code expiration time in minutes. Only for AUTHENTICATION templates.
        whatsapp:
          type: object
          description: WhatsApp-specific template information.
          properties:
            templateName:
              type: string
              description: WhatsApp template name.
            namespace:
              type: string
              description: WhatsApp Business Account namespace.
            status:
              type: string
              description: WhatsApp approval status.
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          example: invalid_request
        message:
          type: string
          example: Phone number is invalid
        details:
          type: object
          additionalProperties: true
    WhatsAppCategory:
      type: string
      description: WhatsApp template category.
      enum:
        - UTILITY
        - MARKETING
        - AUTHENTICATION
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````