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

# Create or update message template

> Create a new WhatsApp message template, or update an existing one.

- Omit `hsm_id` to create a new template.
- Include `hsm_id` as a query parameter to update an existing template.

Templates must be approved by WhatsApp before they can be used. After creation,
templates enter a PENDING state until reviewed.

**Side effect**: Enqueues a template sync job on success to update Kapso's
local template cache.




## OpenAPI

````yaml /api/meta/whatsapp/openapi-whatsapp.yaml post /{business_account_id}/message_templates
openapi: 3.1.0
info:
  title: Kapso Meta Proxy API
  version: 1.0.0
  description: >
    Kapso's Meta Proxy API provides a unified interface to WhatsApp Business
    Platform with enhanced features and Kapso-specific extensions.


    This API acts as a proxy layer between your application and WhatsApp,
    adding:

    - Simplified authentication with project-level API keys

    - Enhanced message metadata and tracking

    - Conversation management capabilities

    - Voice call integration

    - Extended contact and template management


    ## Base URL


    All API requests are made to: `https://api.kapso.ai/meta/whatsapp/v24.0`


    ## Authentication


    The API supports authentication via **X-API-Key header** (recommended):


    ```

    X-API-Key: your_project_api_key

    ```


    Alternative: Bearer token authentication is also supported for backward
    compatibility:


    ```

    Authorization: Bearer your_access_token

    ```


    Note: X-API-Key is the recommended authentication method for the Meta Proxy
    API.
  contact:
    name: Kapso Support
    url: https://kapso.ai
    email: dev@kap.so
servers:
  - url: https://api.kapso.ai/meta/whatsapp/v24.0
    description: Production server
security:
  - ApiKeyAuth: []
  - BearerAuth: []
tags:
  - name: Messages
    description: Send and retrieve WhatsApp messages
  - name: Conversations
    description: Manage WhatsApp conversations
  - name: Contacts
    description: Manage WhatsApp contacts
  - name: Templates
    description: Manage message templates
  - name: Media
    description: Upload and retrieve media files
  - name: Calls
    description: Manage voice calls
  - name: Settings
    description: Account settings and configuration
  - name: Business Profile
    description: Business profile management
  - name: Phone Numbers
    description: Phone number management
  - name: Flows
    description: WhatsApp Flow management (Beta)
  - name: Block Users
    description: Block and unblock WhatsApp users
  - name: Usernames
    description: Reserve and manage WhatsApp business usernames
paths:
  /{business_account_id}/message_templates:
    parameters:
      - name: business_account_id
        in: path
        required: true
        description: WhatsApp Business Account ID
        schema:
          type: string
        example: '123456789012345'
    post:
      tags:
        - Templates
      summary: Create or update message template
      description: >
        Create a new WhatsApp message template, or update an existing one.


        - Omit `hsm_id` to create a new template.

        - Include `hsm_id` as a query parameter to update an existing template.


        Templates must be approved by WhatsApp before they can be used. After
        creation,

        templates enter a PENDING state until reviewed.


        **Side effect**: Enqueues a template sync job on success to update
        Kapso's

        local template cache.
      operationId: createOrUpdateTemplate
      parameters:
        - name: hsm_id
          in: query
          required: false
          description: |
            Template ID to update.

            - Omit for template creation.
            - Required when updating an existing template.
          schema:
            type: string
          example: '1627019861106475'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: >
                Request body for template creation or update.


                - For create requests, `name`, `language`, `category`, and
                `components`
                  are required.
                - For update requests, include `hsm_id` in the query string and
                provide
                  the fields you want to change.
              properties:
                name:
                  type: string
                  description: Template name (lowercase, underscore-separated)
                  example: order_confirmation
                language:
                  type: string
                  description: Language code (e.g., en, en_US)
                  example: en_US
                category:
                  type: string
                  enum:
                    - AUTHENTICATION
                    - MARKETING
                    - UTILITY
                  description: Template category
                  example: UTILITY
                parameter_format:
                  type: string
                  enum:
                    - NAMED
                    - POSITIONAL
                  description: >
                    Format for template parameters (defaults to POSITIONAL if
                    omitted).


                    **NAMED**: Parameters use unique names wrapped in double
                    curly brackets (e.g., {{first_name}}, {{order_number}}).
                    Values can appear in any order in send payloads.


                    **POSITIONAL**: Parameters use ordered array indices
                    starting from 1 (e.g., {{1}}, {{2}}). Values must appear in
                    order in send payloads.
                  example: NAMED
                components:
                  type: array
                  description: >
                    Template components. Supported types:


                    **HEADER** - Optional component at top. Formats: TEXT (1
                    param), IMAGE, VIDEO, DOCUMENT, LOCATION


                    **BODY** - Required text component. Supports multiple
                    parameters (positional or named)


                    **FOOTER** - Optional text-only component. No parameters
                    supported


                    **BUTTONS** - Optional interactive components. Types:
                    QUICK_REPLY (10 max), PHONE_NUMBER (1 max), URL (2 max),
                    COPY_CODE (1 max), OTP, CATALOG, MPM, FLOW
                  items:
                    type: object
            examples:
              body_named_params:
                summary: Simple body with named parameters (simplest)
                value:
                  name: order_confirmation_simple
                  language: en_US
                  category: UTILITY
                  parameter_format: NAMED
                  components:
                    - type: BODY
                      text: >-
                        Thank you, {{customer_name}}! Your order number is
                        {{order_number}}.
                      example:
                        body_text_named_params:
                          - param_name: customer_name
                            example: Pablo
                          - param_name: order_number
                            example: 860198-230332
              body_positional_params:
                summary: Body with positional parameters
                value:
                  name: delivery_notification
                  language: en_US
                  category: UTILITY
                  parameter_format: POSITIONAL
                  components:
                    - type: BODY
                      text: 'Good news {{1}}! Your order #{{2}} has been delivered.'
                      example:
                        body_text:
                          - - Mark
                            - '566701'
              text_header_body_footer_buttons:
                summary: Text header + body + footer + quick reply buttons
                value:
                  name: seasonal_promotion
                  language: en_US
                  category: MARKETING
                  components:
                    - type: HEADER
                      format: TEXT
                      text: Our {{1}} is on!
                      example:
                        header_text:
                          - Summer Sale
                    - type: BODY
                      text: >-
                        Shop now through {{1}} and use code {{2}} to get {{3}}
                        off of all merchandise.
                      example:
                        body_text:
                          - - the end of August
                            - 25OFF
                            - 25%
                    - type: FOOTER
                      text: >-
                        Use the buttons below to manage your marketing
                        subscriptions
                    - type: BUTTONS
                      buttons:
                        - type: QUICK_REPLY
                          text: Unsubscribe from Promos
                        - type: QUICK_REPLY
                          text: Unsubscribe from All
              document_header:
                summary: Document header with action buttons
                value:
                  name: order_confirmation_receipt
                  language: en_US
                  category: UTILITY
                  components:
                    - type: HEADER
                      format: DOCUMENT
                      example:
                        header_handle:
                          - 4::YXBwbGljYXRpb24vcGRm:ARZVv4zuogJMxmAdS3_6T4o...
                    - type: BODY
                      text: >-
                        Thank you for your order, {{1}}! Your order number is
                        {{2}}. Tap the PDF linked above to view your receipt. If
                        you have any questions, please use the buttons below to
                        contact support.
                      example:
                        body_text:
                          - - Pablo
                            - 860198-230332
                    - type: BUTTONS
                      buttons:
                        - type: PHONE_NUMBER
                          text: Call
                          phone_number: '15550051310'
                        - type: URL
                          text: Contact Support
                          url: https://www.luckyshrub.com/support
              location_header:
                summary: Location header for delivery/pickup
                value:
                  name: order_delivery_update
                  language: en_US
                  category: UTILITY
                  components:
                    - type: HEADER
                      format: LOCATION
                    - type: BODY
                      text: >-
                        Good news {{1}}! Your order #{{2}} is on its way to the
                        location above. Thank you for your order!
                      example:
                        body_text:
                          - - Mark
                            - '566701'
                    - type: FOOTER
                      text: >-
                        To stop receiving delivery updates, tap the button
                        below.
                    - type: BUTTONS
                      buttons:
                        - type: QUICK_REPLY
                          text: Stop Delivery Updates
              image_header:
                summary: Image header with media
                value:
                  name: limited_time_offer
                  language: en_US
                  category: MARKETING
                  components:
                    - type: HEADER
                      format: IMAGE
                      example:
                        header_handle:
                          - 4::aW1hZ2UvanBlZw==:ARa1ZDhwbLZM3EENeeg
                    - type: BODY
                      text: >-
                        Hi {{1}}! For a limited time only you can get our {{2}}
                        for as low as {{3}}.
                      example:
                        body_text:
                          - - Mark
                            - Tuscan Getaway package
                            - '800'
                    - type: FOOTER
                      text: Offer valid until May 31, 2023
                    - type: BUTTONS
                      buttons:
                        - type: PHONE_NUMBER
                          text: Call
                          phone_number: '15550051310'
                        - type: URL
                          text: Shop Now
                          url: https://www.examplesite.com/shop
              url_button_with_param:
                summary: URL button with dynamic parameter
                value:
                  name: promo_with_dynamic_link
                  language: en_US
                  category: MARKETING
                  components:
                    - type: BODY
                      text: >-
                        Special offer just for you! Tap below to view your
                        personalized deals.
                    - type: BUTTONS
                      buttons:
                        - type: URL
                          text: View Offers
                          url: https://www.examplesite.com/shop?promo={{1}}
                          example:
                            - summer2023
              authentication_otp_copy_code:
                summary: Authentication - COPY_CODE (manual entry)
                value:
                  name: auth_otp_copy_code
                  language: en_US
                  category: AUTHENTICATION
                  components:
                    - type: BODY
                      add_security_recommendation: true
                    - type: FOOTER
                      code_expiration_minutes: 10
                    - type: BUTTONS
                      buttons:
                        - type: OTP
                          otp_type: COPY_CODE
              authentication_otp_one_tap:
                summary: Authentication - ONE_TAP (Android autofill)
                value:
                  name: auth_otp_one_tap
                  language: en_US
                  category: AUTHENTICATION
                  components:
                    - type: BODY
                      add_security_recommendation: true
                    - type: FOOTER
                      code_expiration_minutes: 10
                    - type: BUTTONS
                      buttons:
                        - type: OTP
                          otp_type: ONE_TAP
                          supported_apps:
                            - package_name: com.example.myapp
                              signature_hash: K8a%2FAINcGX7
              authentication_otp_zero_tap:
                summary: Authentication - ZERO_TAP (no button, auto-read)
                value:
                  name: auth_otp_zero_tap
                  language: en_US
                  category: AUTHENTICATION
                  components:
                    - type: BODY
                      add_security_recommendation: false
                    - type: FOOTER
                      code_expiration_minutes: 5
                    - type: BUTTONS
                      buttons:
                        - type: OTP
                          otp_type: ZERO_TAP
              catalog_button:
                summary: Catalog button for product browsing
                value:
                  name: catalog_promotion
                  language: en_US
                  category: MARKETING
                  components:
                    - type: BODY
                      text: >-
                        Now shop for your favourite products right here on
                        WhatsApp! Get Rs {{1}} off on all orders above {{2}}Rs!
                      example:
                        body_text:
                          - - '100'
                            - '400'
                    - type: FOOTER
                      text: Best grocery deals on WhatsApp!
                    - type: BUTTONS
                      buttons:
                        - type: CATALOG
                          text: View catalog
              mpm_button:
                summary: Multi-product message button
                value:
                  name: abandoned_cart_mpm
                  language: en_US
                  category: MARKETING
                  components:
                    - type: HEADER
                      format: TEXT
                      text: Forget something {{1}}?
                      example:
                        header_text:
                          - Pablo
                    - type: BODY
                      text: >-
                        Looks like you left some items in your cart! Use code
                        {{1}} and you can get 10% off of all of them!
                      example:
                        body_text:
                          - - 10OFF
                    - type: BUTTONS
                      buttons:
                        - type: MPM
                          text: View items
              video_header:
                summary: Video header with media
                value:
                  name: product_demo_video
                  language: en_US
                  category: MARKETING
                  components:
                    - type: HEADER
                      format: VIDEO
                      example:
                        header_handle:
                          - 4::dmlkZW8vbXA0:ARa8f2Xh9K3pLmNqR1sT...
                    - type: BODY
                      text: >-
                        Check out our new product in action! Watch the video
                        above to see how it works.
                    - type: FOOTER
                      text: Available now
              text_header_named_params:
                summary: Text header with named parameters
                value:
                  name: event_reminder
                  language: en_US
                  category: UTILITY
                  components:
                    - type: HEADER
                      format: TEXT
                      text: 'Reminder: {{event_name}} starts {{start_time}}'
                      example:
                        header_text_named_params:
                          - param_name: event_name
                            example: Summer Webinar
                          - param_name: start_time
                            example: tomorrow at 3 PM
                    - type: BODY
                      text: >-
                        Don't forget to join us for {{event_name}}. We'll be
                        covering exciting updates!
                      example:
                        body_text_named_params:
                          - param_name: event_name
                            example: Summer Webinar
              copy_code_button:
                summary: Copy code button for promo codes
                value:
                  name: promo_code_offer
                  language: en_US
                  category: MARKETING
                  components:
                    - type: BODY
                      text: >-
                        Special discount just for you! Use code below to get 20%
                        off your next purchase.
                    - type: BUTTONS
                      buttons:
                        - type: COPY_CODE
                          example: SAVE20
              flow_button_basic:
                summary: Flow button for interactive experiences
                value:
                  name: feedback_survey_flow
                  language: en_US
                  category: UTILITY
                  components:
                    - type: BODY
                      text: >-
                        We'd love to hear your feedback! Tap below to share your
                        thoughts in a quick survey.
                    - type: BUTTONS
                      buttons:
                        - type: FLOW
                          text: Take Survey
                          flow_id: '123456789012345'
                          flow_action: navigate
                          navigate_screen: WELCOME_SCREEN
              template_update:
                summary: Update an existing template by hsm_id
                value:
                  category: MARKETING
                  components:
                    - type: HEADER
                      format: TEXT
                      text: Updated Header
                    - type: BODY
                      text: Updated body text
      responses:
        '200':
          description: Template created or updated successfully
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    properties:
                      id:
                        type: string
                        description: Template ID
                        example: '1627019861106475'
                      status:
                        type: string
                        enum:
                          - PENDING
                          - APPROVED
                          - REJECTED
                        description: Template status
                        example: PENDING
                      category:
                        type: string
                        description: Template category
                        example: UTILITY
                  - type: object
                    properties:
                      success:
                        type: boolean
                        example: true
              examples:
                created:
                  summary: Template created
                  value:
                    id: '1627019861106475'
                    status: PENDING
                    category: UTILITY
                updated:
                  summary: Template updated
                  value:
                    success: true
        '400':
          description: >-
            Bad request (invalid template format or missing/invalid hsm_id for
            updates)
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Error'
                  - type: object
                    required:
                      - error
                    properties:
                      error:
                        type: string
                        example: hsm_id is required
              examples:
                invalid_template:
                  summary: Invalid template format
                  value:
                    error:
                      message: Invalid template format
                      type: OAuthException
                      code: 400
                missing_hsm_id:
                  summary: Missing hsm_id on update
                  value:
                    error: hsm_id is required
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Template not found (update only)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - message
            - type
            - code
          properties:
            message:
              type: string
              description: Human-readable error message
              example: Invalid phone number format
            type:
              type: string
              description: Error category
              example: OAuthException
            code:
              type: integer
              description: Error code
              example: 400
            error_subcode:
              type: integer
              description: More specific error code
              example: 1001
            fbtrace_id:
              type: string
              description: Facebook trace ID for debugging
              example: AXk7s_8dR4eVHp9Kq2MmNlO
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: >
        Project API key for authentication. This is the recommended
        authentication method.


        Get your API key from the Kapso dashboard under Integrations > API keys.
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        Bearer token authentication (alternative method).

        Note: X-API-Key authentication is recommended for the Meta Proxy API.

````