# Retrieve a messaging template

> Read one messaging template with its content, the values a send needs, and its WhatsApp approval on each account.

`GET https://api-connect.nxiom.com/api/v1/messaging/templates/{templateId}`

## Authorization

Requires `whatsapp.send`. A key with `whatsapp.full_access` can also read templates. WhatsApp must be turned on for your organization.

## Path parameters

| Field | Type | Description |
| --- | --- | --- |
| `templateId` | string · required | The template ID, starting with `mtp_`, shown on the template's page in the dashboard under **Details**, or returned by [List messaging templates](/docs/api/messaging/templates/list). |

## Request

### cURL

```shell
curl "https://api-connect.nxiom.com/api/v1/messaging/templates/mtp_example" \
  -H "Authorization: Bearer $NEXIOM_API_KEY"
```

### Node.js

```typescript
const apiKey = process.env.NEXIOM_API_KEY;
if (!apiKey) throw new Error('Set NEXIOM_API_KEY');

const response = await fetch(
  'https://api-connect.nxiom.com/api/v1/messaging/templates/mtp_example',
  {
    method: 'GET',
    headers: {
      Authorization: `Bearer ${apiKey}`,
    },
  },
);

const result = await response.json();
if (!response.ok) {
  throw new Error(result.message ?? `HTTP ${response.status}`);
}
console.log(result);
```

### PHP

```php
<?php

$apiKey = getenv('NEXIOM_API_KEY');
if (!$apiKey) {
    throw new RuntimeException('Set NEXIOM_API_KEY');
}

$request = curl_init("https://api-connect.nxiom.com/api/v1/messaging/templates/mtp_example");
curl_setopt_array($request, [
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $apiKey",
    ],
]);

$raw = curl_exec($request);
$status = curl_getinfo($request, CURLINFO_HTTP_CODE);
$error = curl_error($request);
curl_close($request);

if ($raw === false) {
    throw new RuntimeException($error);
}
$result = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
if ($status >= 400) {
    throw new RuntimeException($result["message"] ?? "HTTP $status");
}
print_r($result);
```

## Response

HTTP `200`. Example identifiers below are illustrative.

`data` is the [template object](#the-template-object).

### 200 OK

A template with two quick-reply buttons, approved on one WhatsApp account.

```json
{
  "message": "Template fetched",
  "data": {
    "id": "mtp_example",
    "name": "order_confirmation",
    "language": "en",
    "category": "utility",
    "content_type": "quick_reply",
    "status": "submitted",
    "source": "library",
    "library_key": "order_confirmation",
    "content": {
      "header": null,
      "body": {
        "text": "Hello {{1}}, we received your order {{2}} for {{3}}. Please confirm it so we can prepare it for delivery.",
        "examples": { "1": "Amina", "2": "A-1234", "3": "4,500 DZD" }
      },
      "footer": null,
      "buttons": [
        { "type": "quick_reply", "text": "Confirm order" },
        { "type": "quick_reply", "text": "Cancel order" }
      ],
      "authentication": null,
      "cards": []
    },
    "variables": {
      "header": [],
      "body": ["1", "2", "3"],
      "header_media": null,
      "buttons": [
        { "index": 0, "type": "quick_reply", "required": false },
        { "index": 1, "type": "quick_reply", "required": false }
      ],
      "code": false,
      "cards": []
    },
    "channels": ["whatsapp"],
    "channel_status": {
      "whatsapp": {
        "ready": true,
        "approvals": [
          {
            "whatsapp_template_id": "wat_example",
            "account_id": "wac_example",
            "waba_id": "100000000000001",
            "status": "active",
            "approval_status": "approved",
            "category": "utility",
            "rejection_reason": null,
            "unsupported_reason": null,
            "matches_content": true,
            "submitted_at": "2026-10-17T08:00:00.000Z",
            "last_synced_at": "2026-10-17T08:05:00.000Z"
          }
        ]
      },
      "sms": { "ready": false }
    },
    "unsupported_reason": null,
    "duplicated_from_id": null,
    "submitted_at": "2026-10-17T08:00:00.000Z",
    "archived_at": null,
    "created_at": "2026-10-17T07:50:00.000Z",
    "updated_at": "2026-10-17T08:00:00.000Z"
  }
}
```

### 400 Bad Request

The request is invalid. Correct it before retrying; `details` lists the failing fields.

```json
{
  "error": "invalid_argument",
  "message": "Request doesn't match the schema",
  "correlationId": "req_example",
  "details": {
    "context": "body",
    "issues": []
  }
}
```

### 401 Unauthorized

The API key is missing, malformed, revoked, or expired.

```json
{
  "error": "unauthorized",
  "message": "Invalid API key",
  "correlationId": "req_example"
}
```

### 403 Forbidden

The API key lacks whatsapp.send, or WhatsApp is not turned on for your organization (code: FEATURE_NOT_AVAILABLE).

```json
{
  "error": "not_allowed",
  "message": "Missing required API key permissions: whatsapp.send",
  "correlationId": "req_example"
}
```

### 404 Not Found

No template with this ID exists in the key's project, or it was deleted. Only template IDs starting with mtp_ are found here.

```json
{
  "error": "not_found",
  "code": "messaging_template_not_found",
  "message": "Template not found.",
  "correlationId": "req_example"
}
```

## The template object

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Template ID, starting with `mtp_`. Send it in `template.id` with [Send a message](/docs/api/messaging/send#template). |
| `name` | string | Lowercase letters, numbers, and underscores, such as `order_confirmation`. |
| `language` | string | The language code, such as `en`, `fr`, `ar`, or `en_US`. Each name and language pair is its own template. |
| `category` | string | `marketing`, `utility`, or `authentication`. WhatsApp can recategorize a template on an account; see the approval's `category`. |
| `content_type` | string | `text`, `media`, `quick_reply`, `call_to_action`, `card`, `authentication`, or `carousel`. See [Content types](/docs/whatsapp/templates#content-types). |
| `status` | string | `draft`, `submitted`, or `archived`. Only submitted templates can be sent. See [Drafts and submitted templates](/docs/whatsapp/templates#drafts-and-submitted-templates). |
| `source` | string | `nexiom` for a template created in Nexiom Connect, `library` for one started from the [library](/docs/whatsapp/templates#start-from-the-library), or `whatsapp_sync` for one found in WhatsApp Manager. |
| `library_key` | string or null | The library entry it was started from, such as `order_confirmation`. |
| `content` | object | What the template says. See [Content](#content). |
| `variables` | object | What a send of the template must give. See [Variables](#variables). |
| `channels` | string[] | The channels its content fits: `whatsapp` for every type, plus `sms` for `text` templates. Sending by SMS isn't available yet. |
| `channel_status` | object | Where it can be sent now. See [Channel status](#channel-status). |
| `unsupported_reason` | string or null | Why a template synced from WhatsApp Manager can't be sent from Nexiom Connect, such as a location header. |
| `duplicated_from_id` | string or null | The template this one was duplicated from. |
| `submitted_at` | string or null | When it was submitted, and its content frozen. |
| `archived_at` | string or null | When it was archived. |
| `created_at` | string | When it was created. |
| `updated_at` | string | When it last changed. |

Timestamps are ISO 8601 strings in UTC.

## Content

The parts a template uses depend on its `content_type`; the others are `null` or empty.

| Field | Type | Description |
| --- | --- | --- |
| `content.header` | object or null | A text header (`type` `text`, with `text` and `example`) or a media header (`type` `image`, `video`, or `document`, with `example_file_id`). |
| `content.body` | object or null | The message: `text`, with numbered variables such as `{{1}}`, and `examples`, an example value by variable number. `null` for `authentication`. |
| `content.footer` | string or null | A short line without variables. |
| `content.buttons` | array | The buttons, in order. See [Buttons](#buttons). |
| `content.authentication` | object or null | For `authentication` only: the options of the verification code message. See [Verification code options](#verification-code-options). |
| `content.cards` | array | For `carousel` only: 2 to 10 cards, each with a `header` (`type` `image` or `video`, with `example_file_id`), a `body` with `text` and `examples`, and `buttons`. |

| Type | Uses |
| --- | --- |
| `text` | `body`, and optionally a text `header` and a `footer`. |
| `media` | A media `header`, `body`, and optionally a `footer`. |
| `quick_reply` | `body`, `buttons` of type `quick_reply`, and optionally a `header` and a `footer`. |
| `call_to_action` | `body`, buttons of type `url`, `phone_number`, and `copy_code`, and optionally a `header` and a `footer`. |
| `card` | `body`, any mix of buttons, and optionally a `header` and a `footer`. |
| `authentication` | `authentication` only. WhatsApp writes the text. |
| `carousel` | `body` and `cards`. |

Examples are what WhatsApp reviewed. They are never sent. Templates synced from WhatsApp Manager have no examples and an empty `example_file_id`, since WhatsApp doesn't return them.

### Buttons

| Field | Type | Description |
| --- | --- | --- |
| `type` | string | `quick_reply`, `url`, `phone_number`, or `copy_code`. |
| `text` | string | The button label, up to 25 characters. Copy-code buttons have none: WhatsApp labels them. |
| `url` | string | For `url`: the link. A link ending with `{{1}}` takes its ending with each send. |
| `example` | string or null | For `url` ending with `{{1}}`: a full example link. For `copy_code`: an example code. |
| `phone_number` | string | For `phone_number`: the number called, in E.164 format. |

### Verification code options

| Field | Type | Description |
| --- | --- | --- |
| `add_security_recommendation` | boolean | Adds "For your security, do not share this code." to the message. |
| `code_expiration_minutes` | number or null | Adds "This code expires in N minutes." to the footer, from 1 to 90. |
| `otp_type` | string | `copy_code`, `one_tap`, or `zero_tap`. How the customer uses the code. |
| `button_text` | string or null | The copy-code button label, up to 25 characters. `null` uses WhatsApp's translated label. |
| `autofill_text` | string or null | For `one_tap` and `zero_tap`: the autofill button label, up to 25 characters. |
| `supported_apps` | array | For `one_tap` and `zero_tap`: 1 to 5 Android apps that receive the code, each with a `package_name` and an 11-character `signature_hash`. |
| `zero_tap_terms_accepted` | boolean | `true` for `zero_tap`: WhatsApp's zero-tap terms were accepted. |
| `message_send_ttl_seconds` | number or null | An undelivered code is dropped after this many seconds, from 30 to 900. `null` uses WhatsApp's default. |

See [Verification code templates](/docs/whatsapp/templates#verification-code-templates).

## Variables

What [Send a message](/docs/api/messaging/send#template) must give for this template, worked out from its content.

| Field | Type | Description |
| --- | --- | --- |
| `variables.header` | string[] | Header variable keys, such as `["1"]`. Give each in `template.variables.header`. |
| `variables.body` | string[] | Body variable keys, such as `["1", "2"]`. Give each in `template.variables.body`. |
| `variables.header_media` | string or null | `image`, `video`, or `document` when each send needs `template.header_media`. |
| `variables.buttons` | array | The buttons that take a value, each with its `index`, its `type` (`url`, `copy_code`, or `quick_reply`), and whether it is `required`. |
| `variables.code` | boolean | `true` for a verification code template: each send needs `template.code`. |
| `variables.cards` | array | For a carousel, one entry per card: its `index`, its `header_media` (`image` or `video`), its `body` variable keys, and its `buttons`. Each send needs `template.cards`. |

## Channel status

| Field | Type | Description |
| --- | --- | --- |
| `channel_status.whatsapp.ready` | boolean | `true` when the template is submitted and approved on at least one WhatsApp account, so it can be sent from that account's number. |
| `channel_status.whatsapp.approvals` | array | One [approval](#whatsapp-approvals) per WhatsApp account the template was submitted to or synced from. |
| `channel_status.sms.ready` | boolean | `true` when the template is submitted and its content fits SMS. Sending by SMS isn't available yet. |

### WhatsApp approvals

WhatsApp reviews a template separately on each WhatsApp account it is submitted to. A template can be sent from a number only when its approval on that number's account is approved.

| Field | Type | Description |
| --- | --- | --- |
| `whatsapp_template_id` | string | The approval ID, starting with `wat_`. A send can name it in `template.id` instead of the `mtp_` ID. |
| `account_id` | string | The WhatsApp account in Nexiom Connect, starting with `wac_`. |
| `waba_id` | string | The WhatsApp Business Account ID in Meta. |
| `status` | string | `active`, or `archived` once the template was deleted in WhatsApp. An archived approval can't be sent. |
| `approval_status` | string | `pending`, `approved`, `rejected`, `paused`, or `disabled`. See [Review and approval](/docs/whatsapp/templates#review-and-approval). |
| `category` | string | The category WhatsApp holds for the template on this account. WhatsApp can change it. |
| `rejection_reason` | string or null | WhatsApp's reason, for a rejected template. |
| `unsupported_reason` | string or null | Why this account's template can't be sent from Nexiom Connect. |
| `matches_content` | boolean | `false` when the template was changed in WhatsApp Manager and no longer matches its content here. Messages then send WhatsApp's version. Always `true` for verification code templates and templates synced from WhatsApp Manager, which follow WhatsApp's wording. |
| `submitted_at` | string or null | When it was submitted to this account. |
| `last_synced_at` | string or null | When it was last read from WhatsApp. |

---

Source: https://connect.nxiom.com/docs/api/messaging/templates/retrieve
