← Blog

·

WhatsApp API errors 132000 and 132012: template parameters don’t match

Updated on October 29, 2026

WhatsApp error 132000 means the number of parameters you sent doesn’t match the number of variables defined in the template. Error 132012 is its close cousin: the count is right, but the format of some value isn’t what the template expects. Both are fixed the same way: read the structure of the approved template and build the payload from it, not from memory.

This guide explains what each error in the 132xxx family means, shows broken and fixed payload examples, and gives you a validation function to run before every send.

The 132xxx family: what each code means

The 132xxx codes cover problems with templates (message templates). The table below summarizes the ones that show up most often when sending, based on Meta’s official error code table:

CodeWhat Meta saysMost common cause in practice
132000The number of parameters sent doesn’t match the number of variables in the templateOne item missing or extra in parameters, or the right component (header, body, button) left out
132001The template doesn’t exist in the requested language or hasn’t been approvedMisspelled name, language.code different from the approved one (pt_BR vs. pt) or template still under review
132005The translated text is too longTemplate translation missing or too long in the language sent
132007The template content violates a WhatsApp policyRejected template or sent content that breaks the policy
132012The parameter values are in the wrong formatParameter type different from the one defined (text where an image is expected, for example) or a parameter name that doesn’t exist
132015Template paused due to low qualityToo many blocks or reports from recipients
132016Template permanently disabled after repeated pausesYou need to create a new template
132018Template validation errorSome parameter has a problem; the details come in the response

Codes 132015 and 132016 have nothing to do with the payload; they’re about template quality. We cover them in paused or disabled template. For the full list of API codes, see WhatsApp API error codes.

How the error response arrives

The error can arrive in two ways. In the most common case, the call to POST /<PHONE_NUMBER_ID>/messages comes straight back with an HTTP error status and an error object in the body. The example below is illustrative; the fields follow the Graph API error format:

{
  "error": {
    "message": "(#132000) ...",
    "type": "OAuthException",
    "code": 132000,
    "error_data": {
      "messaging_product": "whatsapp",
      "details": "<description of the problem, with the component and the count>"
    },
    "fbtrace_id": "A1b2C3d4E5f6"
  }
}

The field that solves the problem is error_data.details. That’s where Meta describes the issue in more detail. Always log the full body of the error response, not just the code.

The exact wording of the message and of details varies; use code for your system’s logic and details for whoever is debugging. In some cases the call is accepted and the failure shows up later, in the status webhook, with status: "failed" and the same code inside errors. The article on message status via webhook shows that format.

Want to try it while you read? Create a Vectalk account and send your first message through the official API. Create free account →

Error 132000: too many or too few parameters

Take an approved utility template with this body:

{
  "type": "BODY",
  "text": "Hi {{1}}, your order {{2}} is out for delivery."
}

There are two variables in the body. The payload below sends only one and gets 132000:

{
  "messaging_product": "whatsapp",
  "to": "5511999999999",
  "type": "template",
  "template": {
    "name": "pedido_em_rota",
    "language": { "code": "pt_BR" },
    "components": [
      {
        "type": "body",
        "parameters": [
          { "type": "text", "text": "Maria" }
        ]
      }
    ]
  }
}

The correct version has one item per variable, in the order they appear in the text:

{
  "messaging_product": "whatsapp",
  "to": "5511999999999",
  "type": "template",
  "template": {
    "name": "pedido_em_rota",
    "language": { "code": "pt_BR" },
    "components": [
      {
        "type": "body",
        "parameters": [
          { "type": "text", "text": "Maria" },
          { "type": "text", "text": "#4821" }
        ]
      }
    ]
  }
}

The causes of 132000 we see most often:

  • Template edited after the code was written. Someone added {{3}} to the text, Meta approved the new version and the system keeps sending two values.
  • Forgotten header or button. If the header has a variable (Order {{1}}) or the URL button has a dynamic suffix, each one needs its own component in the payload. A text header accepts at most one variable; the URL button also accepts one, at the end of the URL.
  • Empty value removed by the code. Some routines filter out parameters with null values before sending. The result is one item short. Replace the empty value with a default text instead of removing the item.
  • Template with the same name in another language. The pt_BR and en_US versions of a template can have different numbers of variables. The payload must follow the version for the language being sent.

Example with a header and a dynamic URL button, with every component present:

{
  "messaging_product": "whatsapp",
  "to": "5511999999999",
  "type": "template",
  "template": {
    "name": "pedido_em_rota_rastreio",
    "language": { "code": "pt_BR" },
    "components": [
      {
        "type": "header",
        "parameters": [ { "type": "text", "text": "#4821" } ]
      },
      {
        "type": "body",
        "parameters": [
          { "type": "text", "text": "Maria" },
          { "type": "text", "text": "today by 6 pm" }
        ]
      },
      {
        "type": "button",
        "sub_type": "url",
        "index": "0",
        "parameters": [ { "type": "text", "text": "4821XYZ" } ]
      }
    ]
  }
}

In the button, index is the button’s position in the template, starting at zero. Meta asks that values with special characters in the URL suffix be encoded (percent-encoding) before sending; otherwise, the generated URL may fail validation.

Error 132012: wrong parameter format

132012 shows up when the value exists but doesn’t have the format the template defined. Two cases account for most occurrences.

Parameter type different from the component

If the template header is an image, the header parameter must be of type image. Sending text there throws an error:

{
  "type": "header",
  "parameters": [ { "type": "text", "text": "https://exemplo.com/banner.jpg" } ]
}

Correct:

{
  "type": "header",
  "parameters": [
    { "type": "image", "image": { "link": "https://exemplo.com/banner.jpg" } }
  ]
}

The same rule applies to video (video), document (document) and location (location) headers.

Named vs. positional parameters

Ever since Meta started accepting named parameters ({{nome_cliente}} instead of {{1}}), there’s another source of errors. The format is set when the template is created, through the parameter_format field, which can be positional (the default) or named, according to the templates overview.

In a named template, each parameter you send needs a parameter_name field equal to the variable name:

{
  "type": "body",
  "parameters": [
    { "type": "text", "parameter_name": "nome_cliente", "text": "Maria" },
    { "type": "text", "parameter_name": "numero_pedido", "text": "#4821" }
  ]
}

The typical mistakes here are sending a named template without parameter_name, sending a name that doesn’t exist (nome instead of nome_cliente) or using uppercase letters, since Meta requires lowercase names with underscores. In named templates, the order of the items doesn’t matter; in positional ones, it matters a lot.

The neighbors: 132001, 132005 and 132007

132001: template doesn’t exist or isn’t approved in that language

Check three things, in this order:

  1. The exact name. Template names use only lowercase letters, numbers and underscores. Pedido_em_rota and pedido_em_rota are different templates.
  2. The language code. language.code must be exactly the one that was approved. Brazilian Portuguese is pt_BR; pt_PT is European Portuguese.
  3. The status. A PENDING, REJECTED or just-created template can’t be sent yet.

The rejection reasons and how to fix them are in WhatsApp template rejected.

132005: translated text too long

Meta’s table says to check in WhatsApp Manager that the template has been translated and points to the template quality page. In practice, open the version for the language you’re sending and confirm it exists, is complete and stays within the 1,024-character body limit.

132007: content violates the policy

Changing the payload won’t help here. The template text or the content sent in the variables breaks the WhatsApp Business Messaging Policy. Review the template and what’s going into the variables. Using a variable to sneak marketing text into a utility template is a well-known path to trouble.

Validation before sending

The safest way to avoid 132000 and 132012 is to stop building the payload by hand. Fetch the template structure from the API, cache it and compare before sending. The messaging account’s template list accepts a field filter, as shown in the template management documentation:

curl "https://graph.facebook.com/v26.0/<WABA_ID>/message_templates?fields=name,language,status,components&name=pedido_em_rota" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

With the components in hand, a simple function counts the variables in each part and compares them with what you’re about to send. Example in JavaScript:

const VAR = /\{\{\s*([a-z0-9_]+)\s*\}\}/g;

function expectedParams(template) {
  const exp = {};
  for (const c of template.components) {
    const type = c.type.toLowerCase();
    if (type === "header" && c.format && c.format !== "TEXT") {
      exp.header = { count: 1, media: c.format.toLowerCase() };
    } else if ((type === "header" || type === "body") && c.text) {
      const names = [...c.text.matchAll(VAR)].map((m) => m[1]);
      if (names.length) exp[type] = { count: names.length, names };
    } else if (type === "buttons") {
      c.buttons.forEach((b, i) => {
        if (b.type === "URL" && VAR.test(b.url)) exp[`button_${i}`] = { count: 1 };
        VAR.lastIndex = 0;
      });
    }
  }
  return exp;
}

function validate(template, components) {
  const exp = expectedParams(template);
  const named = String(template.parameter_format).toLowerCase() === "named";
  const errors = [];
  for (const [key, rule] of Object.entries(exp)) {
    const comp = components.find((c) =>
      key.startsWith("button_")
        ? c.type === "button" && String(c.index) === key.split("_")[1]
        : c.type === key
    );
    const params = comp?.parameters ?? [];
    if (params.length !== rule.count) {
      errors.push(`${key}: expected ${rule.count}, sent ${params.length}`);
    }
    if (rule.media && params[0]?.type !== rule.media) {
      errors.push(`${key}: expected parameter of type ${rule.media}`);
    }
    if (named && rule.names) {
      for (const p of params) {
        if (!rule.names.includes(p.parameter_name)) {
          errors.push(`${key}: invalid parameter_name "${p.parameter_name}"`);
        }
      }
    }
    for (const p of params) {
      if (p.type === "text" && !String(p.text ?? "").trim()) {
        errors.push(`${key}: empty text value`);
      }
    }
  }
  return errors;
}

If validate returns any error, don’t send: log it and alert whoever owns the template. Three habits round out the protection:

  • Refresh the cache when the template changes. The message_template_status_update webhook reports status changes; use that event to reload the structure.
  • Version by name. Instead of editing a template in production, create pedido_em_rota_v2 and switch the code and the template together.
  • Test with an internal number for every new template, before turning on automated sending.

To build payloads with media, buttons and carousels from scratch, see how to send a template message through the API with full JSON. To create and edit templates in code, see create a template via the API.

How to do it with Vectalk

Vectalk is a proxy for the official WhatsApp API: the template payload is the same as Meta’s, and so are the error codes. You send to POST https://apis.vectalk.com.br/api/messages and, with an instance token, the phone_number_id is resolved automatically. To validate before sending, the listing GET https://apis.vectalk.com.br/api/templates?name=pedido_em_rota returns the template’s components, and the same function above works on that response.

In the dashboard, the templates area shows the approved text of each template, and the logs show the full error response for every send, which helps you find details without opening the code. The reference is at docs.vectalk.com.br, and sign-up is at apps.vectalk.com.br/register.

Frequently asked questions

Am I charged for a message that fails with error 132000?

Meta charges per delivered message. A message rejected with 132000 never reaches the recipient, so it doesn’t generate a template charge.

Can 132000 appear suddenly, without me changing the code?

Yes. The classic case is someone editing the template in WhatsApp Manager and adding a variable. Once the new version is approved, the old payload now has too few parameters. That’s why it pays to fetch the template structure from the API instead of hardcoding it.

What’s the difference between 132000 and 132012?

132000 is about quantity: the number of parameters sent differs from the number of variables. 132012 is about format: the count matches, but some value isn’t in the format defined in the template, such as text in an image header or a parameter_name that doesn’t exist.

Can I send empty text in a variable?

Avoid it. An empty value is often stripped by libraries or rejected by the API, and ends up turning into 132000 or another validation error. Use a default text, such as “customer”, when the data doesn’t exist.

Error 132001 shows up even though the template is approved. Why?

It’s almost always the language. The template may be approved in pt_BR while the payload asks for pt_PT or en_US. It’s also worth checking that the template belongs to the same messaging account as the number doing the sending.


Official sources consulted on October 29, 2026: Error codes (Meta), Template fundamentals: parameters (Meta), Template components (Meta), Template management (Meta), WhatsApp Business Messaging Policy, Vectalk: send template, Vectalk: list templates.

Try the official WhatsApp API today

Create your account, generate a token and send your first message with the quick-start guide. Same payloads and webhooks as Meta's Cloud API.