curl --request POST \
--url https://app.thinnest.ai/api/v1/templates/{name}/submit \
--header 'Authorization: Bearer <token>'const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.thinnest.ai/api/v1/templates/{name}/submit', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.thinnest.ai/api/v1/templates/{name}/submit"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text){
"name": "order_ready",
"language": "en",
"category": "utility",
"status": "pending",
"agent": "ag_5c4a5f93-2b1e-4c0a-9d3f-7e8a1b2c3d4e",
"body": "Hello {{1}}, your Kesar Naturals order {{2}} is packed and on its way.",
"variableCount": 2,
"variableLabels": [
{
"position": 1,
"sample": "Priya"
},
{
"position": 2,
"sample": "#10432"
}
],
"buttonVariableCount": 1,
"headerKind": "none",
"createdAt": "2026-10-06T10:00:01.874Z",
"headerText": null,
"footer": "Kesar Naturals, Jaipur",
"buttons": [
{
"kind": "url",
"label": "Track order",
"url": "https://kesarnaturals.in/track/{{1}}"
}
],
"reviewNote": null,
"message": "Sent for review. WhatsApp usually takes minutes, occasionally days."
}{
"error": "Send a valid API key as `Authorization: Bearer <key>`."
}{
"error": "This API key is read-only: it can read everything but change nothing."
}{
"error": "That template was not found."
}{
"error": "Connect a WhatsApp number first — this is submitted to your own WhatsApp Business Account, and until one is connected there is no account to submit it to."
}{
"error": "Could not submit that template."
}{
"error": "Over 240 requests a minute. Slow down and retry."
}{
"error": "WhatsApp is not configured on this deployment yet."
}Submit Template
Sends a draft template to your own WhatsApp Business Account for review, after the same last checks as the console’s Submit. The template moves to pending only if WhatsApp accepted it. Review usually takes minutes, occasionally days; follow it with Get Template, whose status becomes approved or rejected (with the reason in reviewNote). A workspace with no connected WhatsApp number has no account to submit to. Needs a full key.
curl --request POST \
--url https://app.thinnest.ai/api/v1/templates/{name}/submit \
--header 'Authorization: Bearer <token>'const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.thinnest.ai/api/v1/templates/{name}/submit', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.thinnest.ai/api/v1/templates/{name}/submit"
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, headers=headers)
print(response.text){
"name": "order_ready",
"language": "en",
"category": "utility",
"status": "pending",
"agent": "ag_5c4a5f93-2b1e-4c0a-9d3f-7e8a1b2c3d4e",
"body": "Hello {{1}}, your Kesar Naturals order {{2}} is packed and on its way.",
"variableCount": 2,
"variableLabels": [
{
"position": 1,
"sample": "Priya"
},
{
"position": 2,
"sample": "#10432"
}
],
"buttonVariableCount": 1,
"headerKind": "none",
"createdAt": "2026-10-06T10:00:01.874Z",
"headerText": null,
"footer": "Kesar Naturals, Jaipur",
"buttons": [
{
"kind": "url",
"label": "Track order",
"url": "https://kesarnaturals.in/track/{{1}}"
}
],
"reviewNote": null,
"message": "Sent for review. WhatsApp usually takes minutes, occasionally days."
}{
"error": "Send a valid API key as `Authorization: Bearer <key>`."
}{
"error": "This API key is read-only: it can read everything but change nothing."
}{
"error": "That template was not found."
}{
"error": "Connect a WhatsApp number first — this is submitted to your own WhatsApp Business Account, and until one is connected there is no account to submit it to."
}{
"error": "Could not submit that template."
}{
"error": "Over 240 requests a minute. Slow down and retry."
}{
"error": "WhatsApp is not configured on this deployment yet."
}Authorizations
Your API key (ta_live_…) from Settings → API keys, sent as Authorization: Bearer <key>. Keep it on a server: it can message every customer you have. A key is full, build or read-only; a request its level does not allow is refused with 403.
Headers
Developers only: the customer workspace this request acts in — its org_… id from POST /customers. Leave it out to act in your own workspace.
"org_3fKq9TzQ1mN8vB2xR7cLpA"
Path Parameters
The template's name: lowercase letters, numbers and underscores.
^[a-z0-9_]{1,512}$Query Parameters
The template's language code. Needed only when the name exists in more than one language; without it such a name is a 409 that lists them.
Response
Sent for review. The template as it now is (status: "pending"), plus message.
The template, plus a sentence about what just happened.
The template's name — what Send Message and Create Campaign take.
"order_ready"
Its language code.
"en"
WhatsApp's category, which decides its price and its rules.
utility, marketing, authentication draft until submitted, pending while WhatsApp reviews it, then approved or rejected. WhatsApp may later pause an approved template that recipients flag. Only approved can be sent.
draft, pending, approved, rejected, paused The agent the template belongs to (ag_…).
"ag_5c4a5f93-2b1e-4c0a-9d3f-7e8a1b2c3d4e"
The message, with {{1}}, {{2}} … for the blanks. For an authentication template, the sentence WhatsApp writes around the code.
How many body values a send must carry, in order: the highest {{n}} in the body.
x >= 0The example given for each body blank.
Show child attributes
Show child attributes
How many button values a send must carry: one per link button whose address ends in a blank.
x >= 0The header. image, video or document means a send must pass a media link for it.
none, text, image, video, document When it was created.
A text header's words. null for any other header.
The footer line. Empty when there is none.
The template's buttons, in order.
Show child attributes
Show child attributes
Why WhatsApp refused it, when it did. null otherwise.
What happened: saved as a draft, sent for review, or — with submit: true — saved as a draft with the reason the submission was refused.
"Saved as a draft."