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

# Create template

> Register a new structured WhatsApp message template locally and submit it to Meta for approval

Create a new custom WhatsApp message template. The template record is saved locally with initial status `PENDING` and asynchronously dispatched to Meta Graph API v19.0 under your connected WhatsApp Business Account (WABA).

***

### Authentication

This endpoint requires Bearer token authentication.

```http theme={null}
Authorization: Bearer <token>
```

| Header          | Type     | Required | Description                                     | Format           |
| :-------------- | :------- | :------- | :---------------------------------------------- | :--------------- |
| `Authorization` | `string` | **Yes**  | Scoped organization API key or Bearer JWT token | `Bearer <token>` |

***

### Input parameters

The following parameters are accepted in the JSON request body.

<ParamField header="Authorization" type="string" required>
  Bearer token for authentication. Format: `Bearer <token>`.
</ParamField>

<ParamField body="channel_id" type="string" required>
  UUID of the registered WhatsApp Business phone number channel in Sayvy AI.
</ParamField>

<ParamField body="name" type="string" required>
  Template identifier name on Meta (lowercase alphanumeric with underscores, maximum 255 characters). Example: `summer_promo_2026`.
</ParamField>

<ParamField body="language" type="string" required>
  Language code (e.g. `en_US`, `es_ES`, `pt_BR`).
</ParamField>

<ParamField body="category" type="string" required>
  Template category:

  * `MARKETING`: Promotional messages, lead offers, discounts.
  * `UTILITY`: Order confirmations, delivery updates, receipts.
  * `AUTHENTICATION`: OTP and two-factor authorization codes.
</ParamField>

<ParamField body="components" type="object[]" required>
  Structured array of template components (`HEADER`, `BODY`, `FOOTER`, `BUTTONS`):

  <Expandable title="Component Structure">
    <ParamField body="type" type="string" required>
      Component type: `HEADER`, `BODY`, `FOOTER`, or `BUTTONS`.
    </ParamField>

    <ParamField body="format" type="string">
      Header format: `TEXT`, `IMAGE`, `VIDEO`, or `DOCUMENT`.
    </ParamField>

    <ParamField body="text" type="string">
      Component text. Use double curly braces for positional variables (e.g. `Hello {{1}}, your order {{2}} is confirmed.`).
    </ParamField>

    <ParamField body="buttons" type="object[]">
      Array of interactive button definitions (type `QUICK_REPLY`, `URL`, or `PHONE_NUMBER`).
    </ParamField>
  </Expandable>
</ParamField>

***

### Response Fields

<ResponseField name="id" type="string">
  Generated UUID identifier of the template in Sayvy AI.
</ResponseField>

<ResponseField name="channel_id" type="string">
  UUID of the associated WhatsApp channel.
</ResponseField>

<ResponseField name="waba_id" type="string">
  WhatsApp Business Account (WABA) identifier on Meta.
</ResponseField>

<ResponseField name="meta_template_id" type="string">
  Meta's remote template ID (assigned upon Meta confirmation).
</ResponseField>

<ResponseField name="name" type="string">
  Template unique name.
</ResponseField>

<ResponseField name="language" type="string">
  BCP-47 language tag (e.g. `en_US`).
</ResponseField>

<ResponseField name="category" type="string">
  Template category (`MARKETING`, `UTILITY`, `AUTHENTICATION`).
</ResponseField>

<ResponseField name="status" type="string">
  Current review status: `PENDING`, `APPROVED`, or `REJECTED`.
</ResponseField>

<ResponseField name="components" type="object[]">
  Array of configured components.
</ResponseField>

<ResponseField name="quality_score" type="string">
  Meta quality score rating (`GREEN`, `YELLOW`, `RED`, or empty).
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO 8601 creation timestamp.
</ResponseField>

<ResponseField name="updated_at" type="string">
  ISO 8601 modification timestamp.
</ResponseField>

***

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.sayvy.ai/api/v1/templates" \
    -H "Authorization: Bearer <token>" \
    -H "Content-Type: application/json" \
    -d '{
      "channel_id": "8f3b0e2a-71d3-4a5f-9e6b-123456789abc",
      "name": "summer_promo_2026",
      "language": "en_US",
      "category": "MARKETING",
      "components": [
        {
          "type": "HEADER",
          "format": "TEXT",
          "text": "Exclusive Summer VIP Offer"
        },
        {
          "type": "BODY",
          "text": "Hi {{1}}, thank you for being a valued customer! Enjoy 20% off your next purchase with code {{2}}."
        },
        {
          "type": "FOOTER",
          "text": "Reply STOP to unsubscribe"
        },
        {
          "type": "BUTTONS",
          "buttons": [
            {
              "type": "URL",
              "text": "Shop Now",
              "url": "https://example.com/shop"
            },
            {
              "type": "QUICK_REPLY",
              "text": "Speak with Agent"
            }
          ]
        }
      ]
    }'
  ```

  ```python Python theme={null}
  import requests

  url = "https://api.sayvy.ai/api/v1/templates"

  payload = {
      "channel_id": "8f3b0e2a-71d3-4a5f-9e6b-123456789abc",
      "name": "summer_promo_2026",
      "language": "en_US",
      "category": "MARKETING",
      "components": [
          {
              "type": "HEADER",
              "format": "TEXT",
              "text": "Exclusive Summer VIP Offer"
          },
          {
              "type": "BODY",
              "text": "Hi {{1}}, thank you for being a valued customer! Enjoy 20% off with code {{2}}."
          },
          {
              "type": "FOOTER",
              "text": "Reply STOP to unsubscribe"
          },
          {
              "type": "BUTTONS",
              "buttons": [
                  {
                      "type": "URL",
                      "text": "Shop Now",
                      "url": "https://example.com/shop"
                  }
              ]
          }
      ]
  }

  headers = {
      "Authorization": "Bearer <token>",
      "Content-Type": "application/json"
  }

  response = requests.post(url, json=payload, headers=headers)
  print(response.status_code)
  print(response.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.sayvy.ai/api/v1/templates", {
    method: "POST",
    headers: {
      "Authorization": "Bearer <token>",
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      channel_id: "8f3b0e2a-71d3-4a5f-9e6b-123456789abc",
      name: "summer_promo_2026",
      language: "en_US",
      category: "MARKETING",
      components: [
        {
          "type": "BODY",
          "text": "Hi {{1}}, your order {{2}} is being processed."
        }
      ]
    })
  });

  const data = await response.json();
  console.log(data);
  ```

  ```java Java theme={null}
  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.sayvy.ai/api/v1/templates"))
      .header("Authorization", "Bearer <token>")
      .header("Content-Type", "application/json")
      .POST(HttpRequest.BodyPublishers.ofString("""
        {
          "channel_id": "8f3b0e2a-71d3-4a5f-9e6b-123456789abc",
          "name": "summer_promo_2026",
          "language": "en_US",
          "category": "MARKETING",
          "components": [
            {
              "type": "BODY",
              "text": "Hi {{1}}, your booking is confirmed."
            }
          ]
        }
      """))
      .build();

  HttpResponse<String> response =
      HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString());
  System.out.println(response.body());
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Created theme={null}
  {
    "id": "3a4b5c6d-7e8f-9012-3456-789abcdef012",
    "account_id": "act_88492019",
    "channel_id": "8f3b0e2a-71d3-4a5f-9e6b-123456789abc",
    "waba_id": "104928374829102",
    "meta_template_id": null,
    "name": "summer_promo_2026",
    "language": "en_US",
    "category": "MARKETING",
    "status": "PENDING",
    "components": [
      {
        "type": "HEADER",
        "format": "TEXT",
        "text": "Exclusive Summer VIP Offer"
      },
      {
        "type": "BODY",
        "text": "Hi {{1}}, thank you for being a valued customer! Enjoy 20% off your next purchase with code {{2}}."
      },
      {
        "type": "FOOTER",
        "text": "Reply STOP to unsubscribe"
      }
    ],
    "quality_score": "",
    "created_at": "2026-09-07T11:20:00Z",
    "updated_at": "2026-09-07T11:20:00Z"
  }
  ```

  ```json 400 Bad Request theme={null}
  {
    "detail": "WhatsApp channel/phone number not found for this organization."
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "detail": "Unauthorized"
  }
  ```
</ResponseExample>

***

<div
  style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
backgroundColor: "rgba(255, 255, 255, 0.03)",
border: "1px solid rgba(255, 255, 255, 0.08)",
borderRadius: "16px",
padding: "10px 18px",
marginTop: "40px",
gap: "16px",
flexWrap: "wrap"
}}
>
  <a
    href="/api-reference/templates/overview"
    style={{
display: "inline-flex",
alignItems: "center",
gap: "6px",
color: "#94A3B8",
textDecoration: "none",
fontSize: "14px",
fontWeight: "500",
padding: "4px 8px"
}}
  >
    <span style={{ fontSize: "16px" }}>‹</span> Previous
  </a>

  <div
    style={{
display: "flex",
alignItems: "center",
gap: "16px",
backgroundColor: "rgba(255, 255, 255, 0.04)",
border: "1px solid rgba(255, 255, 255, 0.06)",
borderRadius: "12px",
padding: "8px 16px",
marginLeft: "auto"
}}
  >
    <div style={{ textAlign: "right" }}>
      <div style={{ fontSize: "13px", fontWeight: "700", color: "#F8FAFC" }}>List templates</div>

      <div style={{ fontSize: "11px", color: "#94A3B8", maxWidth: "260px", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
        GET /api/v1/templates
      </div>
    </div>

    <div style={{ width: "1px", height: "24px", backgroundColor: "rgba(255, 255, 255, 0.1)" }} />

    <a
      href="/api-reference/templates/list-templates"
      style={{
  display: "inline-flex",
  alignItems: "center",
  gap: "6px",
  color: "#94A3B8",
  textDecoration: "none",
  fontSize: "14px",
  fontWeight: "500"
}}
    >
      Next <span style={{ fontSize: "16px" }}>›</span>
    </a>
  </div>
</div>
