smartchat

Create template

Creates a WhatsApp message template as a draft. Nothing goes to WhatsApp until you submit it with create_template_submissions. Needs an idempotency key and returns the template.

POST /v1/templates

Permissiontemplates:write (all permissions)
RiskWrite (no outside effect)
Idempotency-KeyRequired (how it works)
Safe to repeatSafe to repeat with the same Idempotency-Key: the first answer comes back and nothing is done twice.
Rate limit classwrite (120 requests per minute per key)
ConfirmationNone
MCP toolsave_template
Since version2026-10-25

#What it does

  • Changes data in your account. It does not send messages to contacts.
  • Safe to repeat with the same Idempotency-Key.

#Request

Header

NameRequiredDescription
AuthorizationyesBearer <key>
Idempotency-KeyyesA unique value for this operation, for example a UUID (1 to 255 visible ASCII characters).

Body (JSON)

NameTypeRequiredDescription
namestringyesName of the template, at most 120 characters. length 1 to 120
purposestringnomarketing for offers and news. utility for neutral service messages. one of: marketing, utility; default "marketing"
textstringyesMessage text, at most 1024 characters. Placeholders: {{first_name}}, {{last_name}}, {{full_name}}, {{phone}}, {{email}}, {{date}}, {{time}}, {{amount}}, {{service}}, {{location}}. It must not start or end with a placeholder. length 1 to 1024
languagestringnoLanguage of the text, for example en or de. Default: the account language. length 2 to 10
footerstring or nullnoFooter line, at most 60 characters, no placeholder. Null removes it. up to 60 characters
buttonsarray of objectnoUp to 2 buttons. up to 2 items
buttons[].typestringyesquick_reply sends the label back as a reply. url opens a web address. one of: quick_reply, url
buttons[].textstringyesLabel on the button, no placeholder. At most 25 characters for quick_reply and 40 for url. length 1 to 40
buttons[].urlstringnoWeb address starting with https:// (only for type url). up to 2000 characters

#Examples

curl -X POST "https://api.smartchat.marketing/v1/templates" \
  -H "Authorization: Bearer $SMARTCHAT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Autumn menu",
  "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week.",
  "language": "en",
  "buttons": [
    {
      "type": "quick_reply",
      "text": "Book a table"
    }
  ]
}'
import os
import uuid
import requests

response = requests.post(
    "https://api.smartchat.marketing/v1/templates",
    headers={
        "Authorization": "Bearer " + os.environ["SMARTCHAT_API_KEY"],
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "name": "Autumn menu",
        "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week.",
        "language": "en",
        "buttons": [
            {
                "type": "quick_reply",
                "text": "Book a table",
            },
        ],
    },
)
response.raise_for_status()
print(response.json())
const response = await fetch("https://api.smartchat.marketing/v1/templates", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SMARTCHAT_API_KEY}`,
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "name": "Autumn menu",
    "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week.",
    "language": "en",
    "buttons": [
      {
        "type": "quick_reply",
        "text": "Book a table"
      }
    ]
  }),
});
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());

Response (201):

{
  "object": "template",
  "id": "tpl_0f8c1a2e4b7d4c3e9a5b6d7e8f901234",
  "name": "Autumn menu",
  "channel": "whatsapp",
  "purpose": "marketing",
  "language": "en",
  "text": "Hi {{first_name}}, our autumn menu is here. Book a table for this week.",
  "footer": "Reply STOP to unsubscribe",
  "buttons": [
    {
      "type": "quick_reply",
      "text": "Book a table",
      "url": null
    }
  ],
  "status": "draft",
  "sendable": false,
  "variables": [
    "first_name"
  ],
  "settable_variables": [],
  "submittable": true,
  "issues": [],
  "rejection_reason": null,
  "created_at": "2026-10-25T09:41:07Z",
  "updated_at": "2026-10-25T09:41:07Z"
}

#Response

Status 201. Every response has the headers Request-Id, SmartChat-Version and X-RateLimit-*.

NameTypeDescription
objectstringAlways "template". always template
idstringTemplate ID.
namestringName of the template. up to 120 characters
channelstringChannel. Only whatsapp exists. one of: whatsapp
purposestringPurpose of the template, for example marketing or utility. up to 40 characters
languagestring or nullLanguage version at WhatsApp, for example en or de. up to 10 characters
textstringMessage text with placeholders such as {{1}}. up to 20000 characters
footerstring or nullFooter line or null. up to 60 characters
buttonsarray of objectButtons of the template. up to 10 items
buttons[].typestringquick_reply sends the label back as a reply. url opens a web address. one of: quick_reply, url
buttons[].textstringLabel on the button. up to 60 characters
buttons[].urlstring or nullWeb address for a url button, otherwise null. up to 2000 characters
statusstringApproval state at WhatsApp. Only approved templates can be sent outside the 24-hour window. one of: draft, pending, approved, rejected, paused, disabled
sendablebooleanTrue if the template can be sent through the API now (approved, WhatsApp, not a system template).
variablesarray of stringAll placeholders in the approved text. up to 50 items
settable_variablesarray of stringPlaceholders a caller may fill. The others come from the contact. up to 50 items
submittablebooleanTrue if the template can be submitted to WhatsApp now (draft or rejected and without issues).
issuesarray of stringWhy the template cannot be submitted yet. Empty if there are no issues. up to 50 items
rejection_reasonstring or nullReason given by WhatsApp when the template was rejected, otherwise null. up to 500 characters
created_atstringWhen the template was created. up to 40 characters; format date-time
updated_atstringWhen the template was last changed. up to 40 characters; format date-time

#Errors

CodeStatusWhen
bad_request400The request could not be read.
idempotency_key_invalid400The 'Idempotency-Key' header must be 1 to 255 visible ASCII characters.
idempotency_key_required400This call needs an 'Idempotency-Key' header.
missing_parameter400A required field is missing.
unknown_parameter400A field is not known.
api_key_expired401This API key has expired.
api_key_invalid401This API key is not valid.
api_key_revoked401This API key was revoked.
authentication_required401No API key was sent. Send 'Authorization: Bearer <key>'.
account_blocked403This account is blocked.
insufficient_scope403This key lacks a required permission.
ip_not_allowed403This IP address is not allowed for this key.
idempotency_in_progress409A request with this idempotency key is still running.
idempotency_key_reused422This idempotency key was already used with a different request.
template_rejected422WhatsApp rejected the template.
validation_failed422A field is not valid.
rate_limited429Too many requests. Wait and try again.
internal_error500Something went wrong on our side.
service_unavailable503The service is temporarily unavailable.

All errors use one format.