templates:write. Submits an AUTHENTICATION (one-time code) template to Meta for review and returns it as PENDING; approval is asynchronous, follow it with GET /templates?status=PENDING. Meta writes the message text itself, so the body only carries the options below. Send it with POST /messages (type: template) once APPROVED, passing the code as the single entry of parameters: the same code goes into the body and the copy-code button. Only category: AUTHENTICATION is accepted (422 category_not_supported); a template with the same name and language answers 409 template_already_exists; a refusal from Meta answers 422 template_rejected. Since 1.57.curl --location '/templates' \
--header 'Content-Type: application/json' \
--data '{
"name": "codigo_login",
"language": "pt_BR",
"category": "AUTHENTICATION",
"code_expiration_minutes": 10
}'{
"data": {
"uuid": "c81f2d64-9a0e-42b7-8e35-1f7d4b2c6a90",
"name": "order_confirmed",
"language": "pt_BR",
"status": "APPROVED",
"category": "UTILITY",
"channel_uuid": "123e4567-e89b-12d3-a456-426614174000",
"variables": {
"body_parameter_count": 2,
"body_named_parameters": [],
"header": {
"format": "TEXT",
"has_variable": false
},
"has_dynamic_buttons": true,
"buttons": [
{
"index": 0,
"type": "URL",
"text": "Track order",
"parameter": "url_suffix"
}
],
"cards": [],
"limited_time_offer": null
},
"created_at": "2026-07-10T10:00:00.000-03:00",
"updated_at": "2026-08-01T08:30:00.000-03:00"
}
}