> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gateway.connexease.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Templates

> List the WhatsApp message templates of an application, with filtering, search, expansion, and cursor pagination.

## What it does

Lists an application's WhatsApp templates: cursor pagination + status/category/language filters + name/content search + expand. Data is read fresh directly from Meta (no caching); the `app_id` is verified to belong to the organization.

***

## Endpoint

```text theme={null}
GET /public/api/v1/wa/{app_id}/templates
```

### Headers

<ParamField header="Authorization" type="string" required>
  Secret key in `Bearer sk_...` format. See [Secret Key authentication](/essentials/authentication#secret-key).
</ParamField>

### Path parameters

<ParamField path="app_id" type="string" required>
  Application ID. Must belong to the organization (otherwise `404`).
</ParamField>

### Query parameters

All query parameters are optional.

<ParamField query="limit" default="20" type="integer">
  Maximum records per page. Range `1–100`.
</ParamField>

<ParamField query="after" type="string">
  Next-page cursor (the `nextCursor` from a previous response). Do not pass it on the first request.
</ParamField>

<ParamField query="before" type="string">
  Previous-page cursor (the `previousCursor` from a response). Cannot be used together with `after`.
</ParamField>

<ParamField query="status" type="string">
  Status filter. See [Template Status](/public-api-reference/template/reference/enums#template-status).
</ParamField>

<ParamField query="category" type="string">
  Category filter. See [Template Category](/public-api-reference/template/reference/enums#template-category).
</ParamField>

<ParamField query="language" type="string">
  Language filter: a BCP-47 code (e.g. `en`, `tr`).
</ParamField>

<ParamField query="search" type="string">
  Meta `name_or_content` search (matches the template name or body text).
</ParamField>

<ParamField query="expand" type="string[]">
  `components` → also returns the components (not returned by default). Repeatable.
</ParamField>

<Tip>
  **Pagination:** don't pass a cursor on the first request; send the response's `nextCursor` as `after=` on the next request.
</Tip>

***

## Response

Type: `CursorPagingResult[TemplateResponseModel]`. The envelope is `{ "data": [ ... ], "pagingMetadata": { ... }, "isSuccess": true }`.

<ResponseField name="isSuccess" type="boolean">
  `true` when the request completed successfully.
</ResponseField>

<ResponseField name="data" type="object[]">
  The list of templates (`TemplateResponseModel`).

  <Expandable title="template">
    <ResponseField name="sourceId" type="string">
      The template's Meta ID.
    </ResponseField>

    <ResponseField name="name" type="string">
      Template name.
    </ResponseField>

    <ResponseField name="language" type="string">
      Language code.
    </ResponseField>

    <ResponseField name="category" type="string">
      See [Template Category](/public-api-reference/template/reference/enums#template-category).
    </ResponseField>

    <ResponseField name="status" type="string">
      See [Template Status](/public-api-reference/template/reference/enums#template-status).
    </ResponseField>

    <ResponseField name="components" type="object[]">
      Component details. Returned only with `expand=components`. Each component has a `type` (`HEADER` / `BODY` / `FOOTER` / `BUTTONS`) and the fields relevant to that type.
    </ResponseField>

    <ResponseField name="qualityScore" type="string">
      See [Template Quality Score](/public-api-reference/template/reference/enums#template-quality-score).
    </ResponseField>

    <ResponseField name="rejectedReason" type="string">
      Rejection reason (`NONE` / `ABUSIVE_CONTENT`…).
    </ResponseField>

    <ResponseField name="parameterFormat" type="string">
      See [Template Parameter Format](/public-api-reference/template/reference/enums#template-parameter-format).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="pagingMetadata" type="object">
  <Expandable title="pagingMetadata">
    <ResponseField name="nextCursor" type="string">
      Next-page cursor (dropped if absent). Pass it as `after`.
    </ResponseField>

    <ResponseField name="previousCursor" type="string">
      Previous-page cursor (dropped if absent). Pass it as `before`.
    </ResponseField>

    <ResponseField name="hasNext" type="boolean">
      Whether a next page exists.
    </ResponseField>

    <ResponseField name="hasPrevious" type="boolean">
      Whether a previous page exists.
    </ResponseField>

    <ResponseField name="pageSize" type="integer">
      Number of records in this page.
    </ResponseField>
  </Expandable>
</ResponseField>

<Note>
  Null fields (`id`, `createdAt`, `messageSendTtlSeconds`, `correctCategory`, `previousCategory`) are dropped from the response. On the first request, do not pass `after`/`before` — take the cursors from the response.
</Note>

***

## Examples

<AccordionGroup>
  <Accordion title="Demo 1 — all (default)">
    ```text theme={null}
    GET /public/api/v1/wa/{app_id}/templates
    Authorization: Bearer sk_...
    ```

    ```json theme={null}
    {
      "data": [
        { "sourceId": "842802041844912", "name": "order_confirmation", "language": "en", "category": "UTILITY", "status": "APPROVED", "qualityScore": "GREEN", "rejectedReason": "NONE", "parameterFormat": "POSITIONAL" },
        { "sourceId": "1560534655590931", "name": "summer_sale", "language": "en", "category": "MARKETING", "status": "APPROVED", "qualityScore": "YELLOW", "rejectedReason": "NONE", "parameterFormat": "POSITIONAL" }
      ],
      "pagingMetadata": { "hasNext": false, "hasPrevious": false, "pageSize": 2 },
      "isSuccess": true
    }
    ```
  </Accordion>

  <Accordion title="Demo 2 — status filter">
    ```text theme={null}
    GET /public/api/v1/wa/{app_id}/templates?status=APPROVED
    Authorization: Bearer sk_...
    ```

    ```json theme={null}
    {
      "data": [
        { "sourceId": "842802041844912", "name": "order_confirmation", "language": "en", "category": "UTILITY", "status": "APPROVED", "qualityScore": "GREEN", "rejectedReason": "NONE", "parameterFormat": "POSITIONAL" }
      ],
      "pagingMetadata": { "hasNext": false, "hasPrevious": false, "pageSize": 1 },
      "isSuccess": true
    }
    ```
  </Accordion>

  <Accordion title="Demo 3 — category + language">
    ```text theme={null}
    GET /public/api/v1/wa/{app_id}/templates?category=UTILITY&language=en
    Authorization: Bearer sk_...
    ```

    ```json theme={null}
    {
      "data": [
        { "sourceId": "842802041844912", "name": "order_confirmation", "language": "en", "category": "UTILITY", "status": "APPROVED", "qualityScore": "GREEN", "rejectedReason": "NONE", "parameterFormat": "POSITIONAL" }
      ],
      "pagingMetadata": { "hasNext": false, "hasPrevious": false, "pageSize": 1 },
      "isSuccess": true
    }
    ```
  </Accordion>

  <Accordion title="Demo 4 — search">
    ```text theme={null}
    GET /public/api/v1/wa/{app_id}/templates?search=order
    Authorization: Bearer sk_...
    ```

    ```json theme={null}
    {
      "data": [
        { "sourceId": "842802041844912", "name": "order_confirmation", "language": "en", "category": "UTILITY", "status": "APPROVED", "qualityScore": "GREEN", "rejectedReason": "NONE", "parameterFormat": "POSITIONAL" }
      ],
      "pagingMetadata": { "hasNext": false, "hasPrevious": false, "pageSize": 1 },
      "isSuccess": true
    }
    ```
  </Accordion>

  <Accordion title="Demo 5 — with components (expand=components)">
    ```text theme={null}
    GET /public/api/v1/wa/{app_id}/templates?expand=components&status=APPROVED
    Authorization: Bearer sk_...
    ```

    ```json theme={null}
    {
      "data": [
        {
          "sourceId": "842802041844912",
          "name": "order_confirmation",
          "language": "en",
          "category": "UTILITY",
          "status": "APPROVED",
          "components": [
            { "type": "HEADER", "format": "TEXT", "text": "Order #{{1}} confirmed", "example": { "headerText": ["12345"] } },
            { "type": "BODY", "text": "Hello {{1}}, your order {{2}} has been confirmed.", "example": { "bodyText": [["John", "#12345"]] } },
            { "type": "FOOTER", "text": "Sent via Connexease" },
            { "type": "BUTTONS", "buttons": [ { "type": "QUICK_REPLY", "text": "Track" } ] }
          ],
          "qualityScore": "GREEN",
          "rejectedReason": "NONE",
          "parameterFormat": "POSITIONAL"
        }
      ],
      "pagingMetadata": { "hasNext": false, "hasPrevious": false, "pageSize": 1 },
      "isSuccess": true
    }
    ```
  </Accordion>

  <Accordion title="Demo 6 — pagination (cursor)">
    First page:

    ```text theme={null}
    GET /public/api/v1/wa/{app_id}/templates?limit=2
    Authorization: Bearer sk_...
    ```

    ```json theme={null}
    {
      "data": [
        { "sourceId": "842802041844912", "name": "order_confirmation", "language": "en", "category": "UTILITY", "status": "APPROVED", "qualityScore": "GREEN", "rejectedReason": "NONE", "parameterFormat": "POSITIONAL" },
        { "sourceId": "1831871288221211", "name": "order_update", "language": "en", "category": "UTILITY", "status": "PENDING", "qualityScore": "UNKNOWN", "rejectedReason": "NONE", "parameterFormat": "POSITIONAL" }
      ],
      "pagingMetadata": { "nextCursor": "MAZDZDhYbVZ3PQ", "hasNext": true, "hasPrevious": false, "pageSize": 2 },
      "isSuccess": true
    }
    ```

    Next page (`nextCursor` → `after`):

    ```text theme={null}
    GET /public/api/v1/wa/{app_id}/templates?limit=2&after=MAZDZDhYbVZ3PQ
    Authorization: Bearer sk_...
    ```

    ```json theme={null}
    {
      "data": [
        { "sourceId": "1560534655590931", "name": "summer_sale", "language": "en", "category": "MARKETING", "status": "APPROVED", "qualityScore": "YELLOW", "rejectedReason": "NONE", "parameterFormat": "POSITIONAL" }
      ],
      "pagingMetadata": { "previousCursor": "MQZDZDhYbVZ3PQ", "hasNext": false, "hasPrevious": true, "pageSize": 1 },
      "isSuccess": true
    }
    ```
  </Accordion>
</AccordionGroup>

<Note>
  Empty result: `"data": []` with `"pagingMetadata": { "hasNext": false, "hasPrevious": false, "pageSize": 0 }`.
</Note>

***

## Errors

<ResponseField name="errors" type="object">
  Error details with `code`, `group`, and `description`; `isSuccess` is `false`.
</ResponseField>

### Auth / tenant

| HTTP | Code                      | When                                          |
| ---- | ------------------------- | --------------------------------------------- |
| 401  | `ORGANIZATION_SECRET_010` | Secret key is missing.                        |
| 401  | `ORGANIZATION_SECRET_011` | Secret key is invalid.                        |
| 404  | `APPLICATION_004`         | `app_id` does not belong to the organization. |

### Request validation (422)

| HTTP | When                                                                                   |
| ---- | -------------------------------------------------------------------------------------- |
| 422  | `limit` outside 1–100; invalid `status`/`category` enum value; invalid `expand` value. |

### Meta-side (`list_templates_async` — no subcode routing)

| HTTP | Code       | When                              |
| ---- | ---------- | --------------------------------- |
| 401  | `META_034` | Token invalid/expired (190).      |
| 403  | `META_035` | Permission denied (10 / 200–299). |
| 429  | `META_036` | Rate limit (4 / 80007).           |
| 400  | `META_037` | Invalid parameter (100).          |
| 502  | `META_004` | General/fallback listing error.   |

Example error response (429 rate limit):

```json theme={null}
{ "errors": { "code": "META_036", "group": "...", "description": "Failed to fetch templates. Details: ..." }, "isSuccess": false }
```
