Error 132000 WhatsApp API: Template Not Found — How to Fix
How to fix error 132000 (template not found) and related errors 132001, 132005 and 132012 in WhatsApp Business API
What is Error 132000?
Error 132000 means the template you specified was not found in your WhatsApp Business account. It's one of the most common errors when working with template messages — and it usually has a straightforward cause.
{
"error": {
"message": "(#132000) Template Not Found",
"type": "OAuthException",
"code": 132000,
"fbtrace_id": "..."
}
}
Cause 1: Typo in the template name
The template name is case-sensitive and must match exactly what's registered in Meta for Developers. An extra space, a capital letter, or a misplaced underscore is enough to trigger 132000.
Incorrect payload
{
"messaging_product": "whatsapp",
"to": "5511999999999",
"type": "template",
"template": {
"name": "welcome_message",
"language": { "code": "en_US" }
}
}
Correct payload (template is actually named welcome_msg)
{
"messaging_product": "whatsapp",
"to": "5511999999999",
"type": "template",
"template": {
"name": "welcome_msg",
"language": { "code": "en_US" }
}
}
Solution: list your templates via API
async function listTemplates(wabaId, accessToken) {
const response = await fetch(
`https://graph.facebook.com/v18.0/${wabaId}/message_templates?fields=name,status,language&limit=100`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
const data = await response.json();
// Print all templates and their statuses
data.data.forEach(template => {
console.log(`Name: ${template.name} | Status: ${template.status} | Language: ${template.language}`);
});
return data.data;
}
// Find a specific template by name
async function findTemplate(wabaId, accessToken, templateName) {
const templates = await listTemplates(wabaId, accessToken);
const found = templates.find(t => t.name === templateName);
if (!found) {
console.error(`❌ Template "${templateName}" not found.`);
console.log('Available templates:', templates.map(t => t.name).join(', '));
} else {
console.log(`✅ Template found: ${found.name} (${found.status})`);
}
return found;
}
Cause 2: Wrong language code
A very common mistake: passing en instead of en_US. Meta does not do approximate matching — the language code must be exact.
Incorrect payload
{
"template": {
"name": "welcome_msg",
"language": { "code": "en" }
}
}
Correct payload
{
"template": {
"name": "welcome_msg",
"language": { "code": "en_US" }
}
}
Most common language codes
| Language | Correct code |
|----------|-------------|
| English (US) | en_US |
| English (UK) | en_GB |
| Portuguese (Brazil) | pt_BR |
| Portuguese (Portugal) | pt_PT |
| Spanish (Mexico) | es_MX |
| Spanish (Argentina) | es_AR |
| French | fr_FR |
| German | de_DE |
| Italian | it_IT |
Check the full list of supported languages in the official docs.
Cause 3: Template rejected or paused (Error 132012)
Meta can reject or pause a template without immediate notification. The status silently changes from APPROVED to PAUSED or REJECTED — and your next sends will fail with 132000 or 132012.
{
"error": {
"message": "(#132012) Message Failed to Send because more than 24 hours have passed since the customer last replied to this number / Template is paused due to low quality rating",
"type": "OAuthException",
"code": 132012
}
}
Check template status via API
async function checkTemplateStatus(wabaId, accessToken, templateName) {
const response = await fetch(
`https://graph.facebook.com/v18.0/${wabaId}/message_templates?name=${templateName}&fields=name,status,quality_score,rejected_reason`,
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
const data = await response.json();
const template = data.data[0];
if (!template) {
console.log(`Template "${templateName}" not found.`);
return null;
}
console.log(`Status: ${template.status}`);
console.log(`Quality score: ${JSON.stringify(template.quality_score)}`);
if (template.rejected_reason) {
console.log(`Rejection reason: ${template.rejected_reason}`);
}
return template;
}
What to do based on status
| Status | Meaning | Action |
|--------|---------|--------|
| APPROVED | Working | Something else is wrong |
| PAUSED | Paused due to low quality | Edit template, wait for reactivation |
| REJECTED | Rejected by Meta | Review content, create a new template |
| PENDING | Awaiting approval | Wait (can take up to 24h) |
| DISABLED | Permanently disabled | Create a new template |
Note: Paused templates can be reactivated by editing the content and waiting for re-review. Rejected templates need a fresh submission.
Cause 4: Stale data after template edit
When you edit a template (name, language, or content), Meta processes the change, but your code may still reference outdated data — especially if you store the template name/language in a database or environment variable.
Typical scenario:
- Template
billing_v1approved and working - Dev renames it to
billing_v2and updates the dashboard - Production code still calls
billing_v1→ 132000
Solution: always read the template name from a reliable source (updated database, config panel) and never hardcode template names without an update mechanism.
// ❌ Avoid — hardcoded name
const TEMPLATE_NAME = 'billing_v1';
// ✅ Better — read from centralized config
const TEMPLATE_NAME = process.env.WHATSAPP_TEMPLATE_BILLING;
// ✅ Best — validate on startup
async function initialize() {
const templateName = process.env.WHATSAPP_TEMPLATE_BILLING;
const template = await findTemplate(WABA_ID, ACCESS_TOKEN, templateName);
if (!template || template.status !== 'APPROVED') {
throw new Error(`Template "${templateName}" is invalid or not approved. Check your configuration.`);
}
console.log(`✅ Template "${templateName}" validated and ready.`);
}
Related Errors
Error 132001 — Parameter Missing
The template requires N variables, but the payload sent fewer than expected.
// Template "welcome_msg" has two parameters: {{1}} and {{2}}
// ❌ Incorrect payload — missing second parameter
const wrongPayload = {
template: {
name: 'welcome_msg',
language: { code: 'en_US' },
components: [
{
type: 'body',
parameters: [
{ type: 'text', text: 'John' }
// Missing second parameter!
]
}
]
}
};
// ✅ Correct payload
const correctPayload = {
template: {
name: 'welcome_msg',
language: { code: 'en_US' },
components: [
{
type: 'body',
parameters: [
{ type: 'text', text: 'John' },
{ type: 'text', text: 'Premium Plan' }
]
}
]
}
};
Error 132005 — Parameter Format Mismatch
The parameter type doesn't match what the template expects. For example, sending a text where the template expects an image.
// Template with image header
// ❌ Incorrect — passing text in a header that expects image
const wrongPayload = {
template: {
name: 'promo_image',
language: { code: 'en_US' },
components: [
{
type: 'header',
parameters: [
{ type: 'text', text: 'Promotion' } // header expects image!
]
}
]
}
};
// ✅ Correct payload
const correctPayload = {
template: {
name: 'promo_image',
language: { code: 'en_US' },
components: [
{
type: 'header',
parameters: [
{ type: 'image', image: { link: 'https://yoursite.com/promo.jpg' } }
]
}
]
}
};
Helper Function: Preflight Check
Validate everything before sending the message. This function prevents errors 132000, 132001, 132005, and 132012 at runtime.
Node.js
async function preflightCheck(wabaId, accessToken, payload) {
const { name: templateName, language, components = [] } = payload.template;
// 1. Fetch template from API
const response = await fetch(
`https://graph.facebook.com/v18.0/${wabaId}/message_templates?name=${templateName}&fields=name,status,language,components`,
{
headers: { 'Authorization': `Bearer ${accessToken}` }
}
);
const data = await response.json();
const template = data.data?.find(
t => t.name === templateName && t.language === language.code
);
// 2. Check existence
if (!template) {
const available = data.data?.map(t => `${t.name} (${t.language})`).join(', ') || 'none';
throw new Error(
`Template "${templateName}" with language "${language.code}" not found.\n` +
`Available templates: ${available}`
);
}
// 3. Check status
if (template.status !== 'APPROVED') {
throw new Error(
`Template "${templateName}" is not approved. Current status: ${template.status}`
);
}
// 4. Check parameter count per component
for (const componentPayload of components) {
const componentTemplate = template.components?.find(
c => c.type.toLowerCase() === componentPayload.type.toLowerCase()
);
if (!componentTemplate) continue;
// Count variables in template ({{1}}, {{2}}, etc.)
const expectedParams = (componentTemplate.text?.match(/\{\{\d+\}\}/g) || []).length;
const sentParams = componentPayload.parameters?.length || 0;
if (sentParams < expectedParams) {
throw new Error(
`Component "${componentPayload.type}": expected ${expectedParams} parameter(s), got ${sentParams}.`
);
}
}
console.log(`✅ Preflight OK: template "${templateName}" (${language.code}) ready to send.`);
return true;
}
// Usage
async function sendWithValidation(wabaId, accessToken, phoneNumberId, to, templatePayload) {
await preflightCheck(wabaId, accessToken, templatePayload);
const response = await fetch(
`https://graph.facebook.com/v18.0/${phoneNumberId}/messages`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
messaging_product: 'whatsapp',
to,
type: 'template',
template: templatePayload.template
})
}
);
return response.json();
}
Python
import requests
import re
def preflight_check(waba_id: str, access_token: str, payload: dict) -> bool:
template_name = payload["template"]["name"]
language_code = payload["template"]["language"]["code"]
components = payload["template"].get("components", [])
# 1. Fetch template from API
response = requests.get(
f"https://graph.facebook.com/v18.0/{waba_id}/message_templates",
params={
"name": template_name,
"fields": "name,status,language,components"
},
headers={"Authorization": f"Bearer {access_token}"}
)
data = response.json()
# 2. Check existence
template = next(
(t for t in data.get("data", [])
if t["name"] == template_name and t["language"] == language_code),
None
)
if not template:
available = [f"{t['name']} ({t['language']})" for t in data.get("data", [])]
raise ValueError(
f'Template "{template_name}" with language "{language_code}" not found.\n'
f'Available: {", ".join(available) or "none"}'
)
# 3. Check status
if template["status"] != "APPROVED":
raise ValueError(
f'Template "{template_name}" is not approved. Status: {template["status"]}'
)
# 4. Check parameter count
for comp_payload in components:
comp_type = comp_payload["type"].upper()
comp_template = next(
(c for c in template.get("components", []) if c["type"] == comp_type),
None
)
if not comp_template:
continue
expected_params = len(re.findall(r'\{\{\d+\}\}', comp_template.get("text", "")))
sent_params = len(comp_payload.get("parameters", []))
if sent_params < expected_params:
raise ValueError(
f'Component "{comp_type}": expected {expected_params} parameter(s), got {sent_params}.'
)
print(f'✅ Preflight OK: template "{template_name}" ({language_code}) ready to send.')
return True
# Usage
def send_with_validation(waba_id, access_token, phone_number_id, to, template_payload):
preflight_check(waba_id, access_token, template_payload)
response = requests.post(
f"https://graph.facebook.com/v18.0/{phone_number_id}/messages",
headers={
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
},
json={
"messaging_product": "whatsapp",
"to": to,
"type": "template",
"template": template_payload["template"]
}
)
return response.json()
Quick Diagnostic Checklist
- [ ] Is the template name spelled correctly (case-sensitive, no extra spaces)?
- [ ] Is
language.codein the correct format (e.g.,en_US, noten)? - [ ] Does the template have
APPROVEDstatus in Meta for Developers? - [ ] Does the number of parameters in the payload match the template?
- [ ] Is the type of each parameter (text, image, document) correct?
- [ ] Was the template recently edited or renamed without updating the code?
- [ ] Was the template paused due to low quality (too many user blocks)?
Conclusion
Errors in the 132xxx family usually have a direct, fixable cause: wrong name, wrong language, template out of service. A preflight check eliminates most of these problems before the message is sent — turning production failures into development-time validations.
Need help implementing the WhatsApp Business API? Get in touch for consulting.