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

# Creating templates

> Make a template with the API and send it for review.

`POST /v1/templates` makes a template and sends it to WhatsApp for review, with the same rules as the app. It starts as `pending`; you get `template.status_changed` when WhatsApp approves or rejects it. A Full key is needed.

```bash cURL theme={null}
curl https://api.getreply.in/v1/templates \
  -H "Authorization: Bearer gr_live_…" \
  -H "Idempotency-Key: template-diwali-offer" \
  -H "Content-Type: application/json" \
  -d '{"name": "diwali_offer", "language": "en", "category": "marketing", "header": {"type": "image", "url": "https://example.com/offer.jpg"}, "body": "Hi {{name}}, enjoy {{discount}} off this Diwali.", "footer": "Reply STOP to opt out", "examples": {"body:name": "Riya", "body:discount": "20%", "button:1:code": "DIWALI20"}, "buttons": [{"type": "quick_reply", "text": "Show me more"}, {"type": "url", "text": "Shop now", "url": "https://example.com/shop/{{code}}"}, {"type": "phone_number", "text": "Call us", "phone": "+9198250*****"}, {"type": "copy_code"}], "copy_code_example": "DIWALI20"}'
```

```javascript Node.js theme={null}
const res = await fetch("https://api.getreply.in/v1/templates", {
  method: "POST",
  headers: {
    "Authorization": "Bearer gr_live_…",
    "Idempotency-Key": "template-diwali-offer",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "name": "diwali_offer",
    "language": "en",
    "category": "marketing",
    "header": {
      "type": "image",
      "url": "https://example.com/offer.jpg"
    },
    "body": "Hi {{name}}, enjoy {{discount}} off this Diwali.",
    "footer": "Reply STOP to opt out",
    "examples": {
      "body:name": "Riya",
      "body:discount": "20%",
      "button:1:code": "DIWALI20"
    },
    "buttons": [
      {
        "type": "quick_reply",
        "text": "Show me more"
      },
      {
        "type": "url",
        "text": "Shop now",
        "url": "https://example.com/shop/{{code}}"
      },
      {
        "type": "phone_number",
        "text": "Call us",
        "phone": "+9198250*****"
      },
      {
        "type": "copy_code"
      }
    ],
    "copy_code_example": "DIWALI20"
  }),
});
console.log(await res.json());
```

```php PHP theme={null}
<?php
$ch = curl_init("https://api.getreply.in/v1/templates");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer gr_live_…",
    "Idempotency-Key: template-diwali-offer",
    "Content-Type: application/json",
  ],
  CURLOPT_POSTFIELDS => '{"name": "diwali_offer", "language": "en", "category": "marketing", "header": {"type": "image", "url": "https://example.com/offer.jpg"}, "body": "Hi {{name}}, enjoy {{discount}} off this Diwali.", "footer": "Reply STOP to opt out", "examples": {"body:name": "Riya", "body:discount": "20%", "button:1:code": "DIWALI20"}, "buttons": [{"type": "quick_reply", "text": "Show me more"}, {"type": "url", "text": "Shop now", "url": "https://example.com/shop/{{code}}"}, {"type": "phone_number", "text": "Call us", "phone": "+9198250*****"}, {"type": "copy_code"}], "copy_code_example": "DIWALI20"}',
]);
echo curl_exec($ch);
```

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

res = requests.post(
    "https://api.getreply.in/v1/templates",
    headers={
        "Authorization": "Bearer gr_live_…",
        "Idempotency-Key": "template-diwali-offer",
    },
    json={
        "name": "diwali_offer",
        "language": "en",
        "category": "marketing",
        "header": {
            "type": "image",
            "url": "https://example.com/offer.jpg"
        },
        "body": "Hi {{name}}, enjoy {{discount}} off this Diwali.",
        "footer": "Reply STOP to opt out",
        "examples": {
            "body:name": "Riya",
            "body:discount": "20%",
            "button:1:code": "DIWALI20"
        },
        "buttons": [
            {
                "type": "quick_reply",
                "text": "Show me more"
            },
            {
                "type": "url",
                "text": "Shop now",
                "url": "https://example.com/shop/{{code}}"
            },
            {
                "type": "phone_number",
                "text": "Call us",
                "phone": "+9198250*****"
            },
            {
                "type": "copy_code"
            }
        ],
        "copy_code_example": "DIWALI20"
    },
)
print(res.json())
```

## Name, language and category

* `name`: lowercase letters, numbers and underscores.
* `language`: a language code, e.g. `en` or `hi`.
* `category`: `marketing`, `utility` or `authentication`.

## Text

* `body`: the message, at most 1,024 characters. It is needed for marketing and utility templates.
* `footer`: optional, at most 60 characters, no variables.

## Header

`header` is optional. One of:

* Text: `{"type": "text", "text": "Order {{order}}"}` — at most 60 characters and one variable.
* A file: `{"type": "image", "url": "https://…"}`, `"video"` or `"document"`. The file is the sample WhatsApp reviews: an image JPEG or PNG up to 5 MB, a video MP4 up to 16 MB, a document PDF up to 100 MB. When you send the template you give the file each person gets.

## Variables

Write a variable as `{{name}}`: lowercase letters, numbers and underscores, starting with a letter. A variable can't be the first or last thing in the body, and two can't stand side by side.

Give a sample for each variable in `examples`, by where it is:

* `"body:name": "Riya"` for the body,
* `"header:order": "#4521"` for a text header,
* `"button:1:code": "DIWALI20"` for a link button's variable (1 is the button's place in `buttons`, from 0).

## Buttons

`buttons` holds up to 10, in this order of kinds: quick replies together, the others together.

| `type` | What it does | Fields | How many |
| - | - | - | - |
| `quick_reply` | The person taps a reply. | `text` (at most 25 characters) | up to 10 |
| `url` | Opens a link. | `text`, `url` (https; one variable at the end) | up to 2 |
| `phone_number` | Calls a number. | `text`, `phone` (with its country code) | 1 |
| `copy_code` | Copies a coupon code. | none — give `copy_code_example` (at most 20 characters) | 1 |

A coupon code itself is given when you send the template (`buttons` with `type: "copy_code"` and its `value`).

## OTP (authentication)

An authentication template has no body of your own: WhatsApp writes the words ("482915 is your verification code.") and adds a button that copies the code.

```bash cURL theme={null}
curl https://api.getreply.in/v1/templates \
  -H "Authorization: Bearer gr_live_…" \
  -H "Idempotency-Key: template-login-code" \
  -H "Content-Type: application/json" \
  -d '{"name": "login_code", "language": "en", "category": "authentication", "auth": {"add_security_recommendation": true, "code_expiration_minutes": 10}}'
```

```javascript Node.js theme={null}
const res = await fetch("https://api.getreply.in/v1/templates", {
  method: "POST",
  headers: {
    "Authorization": "Bearer gr_live_…",
    "Idempotency-Key": "template-login-code",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "name": "login_code",
    "language": "en",
    "category": "authentication",
    "auth": {
      "add_security_recommendation": true,
      "code_expiration_minutes": 10
    }
  }),
});
console.log(await res.json());
```

```php PHP theme={null}
<?php
$ch = curl_init("https://api.getreply.in/v1/templates");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer gr_live_…",
    "Idempotency-Key: template-login-code",
    "Content-Type: application/json",
  ],
  CURLOPT_POSTFIELDS => '{"name": "login_code", "language": "en", "category": "authentication", "auth": {"add_security_recommendation": true, "code_expiration_minutes": 10}}',
]);
echo curl_exec($ch);
```

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

res = requests.post(
    "https://api.getreply.in/v1/templates",
    headers={
        "Authorization": "Bearer gr_live_…",
        "Idempotency-Key": "template-login-code",
    },
    json={
        "name": "login_code",
        "language": "en",
        "category": "authentication",
        "auth": {
            "add_security_recommendation": true,
            "code_expiration_minutes": 10
        }
    },
)
print(res.json())
```

* `auth.add_security_recommendation`: adds "For your security, do not share this code."
* `auth.code_expiration_minutes`: 1 to 90; adds "This code expires in N minutes."
* `auth.button_text`: the button's text (optional).

Send it with `POST /v1/messages/otp` — see [Sending OTPs](https://docs.getreply.in/guides/sending-otps.md).

## Edit and delete

* `PATCH /v1/templates/{name}?language=en`: change the body, footer, header, buttons or samples; it goes for review again. The name and language stay, and an approved template's category stays. WhatsApp allows an approved template to be edited once in 24 hours and 10 times in 30 days (`template_edit_limit`).
* `DELETE /v1/templates/{name}`: moves it to the bin (one language with `?language=`, or every language of the name).

## Not available yet

These can't be made with the API today — see [What is not available yet](https://docs.getreply.in/guides/not-yet-available.md):

* Numbered variables (`{{1}}`). A template made elsewhere with numbered variables can still be sent.
* Carousel templates.
* Limited-time offer templates.
* Catalog, product, flow and call-permission buttons.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.