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

# View templates

> Retrieve a paginated list of message templates from your OneSignal app. This endpoint returns summary information for each template, including ID, name, creation, and update timestamps.

## Overview

Use this endpoint to retrieve a list of message templates associated with a specific OneSignal app. The response provides summary information only:

* `template_id`
* `name`
* `created_at`
* `updated_at`

<Note>
  This endpoint does **not** return full template content such as message bodies, channel properties, or delivery configuration. For detailed template data, use the [View Template](/reference/view-template) endpoint.
</Note>

***

## How to Use This API

### Required Parameters

* **`app_id`** (query param): The OneSignal App ID whose templates you want to retrieve.

### Optional Parameters

* **`limit`** (query param): Number of templates to return (default: `50`, maximum: `50`).
* **`offset`** (query param): Number of templates to skip. Use for pagination.

### Pagination Example

If your app has 125 templates and you're using the default limit of 50:

1. First request (first 50 templates):\
   `GET /templates?app_id={app_id}&offset=0`

2. Second request (next 50 templates):\
   `GET /templates?app_id={app_id}&offset=50`

3. Third request (final 25 templates):\
   `GET /templates?app_id={app_id}&offset=100`

Repeat the request while adjusting the `offset` until you've retrieved all templates.

***


## OpenAPI

````yaml GET /templates?app_id={app_id}&limit={limit}&offset={offset}
openapi: 3.1.0
info:
  title: api.onesignal.com
  version: '11.6'
servers:
  - url: https://api.onesignal.com
security:
  - {}
paths:
  /templates?app_id={app_id}&limit={limit}&offset={offset}:
    get:
      summary: View templates
      description: >-
        Retrieve a paginated list of message templates from your OneSignal app.
        This endpoint returns summary information for each template, including
        ID, name, creation, and update timestamps.
      operationId: view-templates
      parameters:
        - name: app_id
          in: query
          description: >-
            Your OneSignal App ID in UUID v4 format. See [Keys &
            IDs](/docs/en/keys-and-ids).
          required: true
          schema:
            type: string
            default: YOUR_APP_ID
        - name: limit
          in: query
          description: >-
            The maximum number of templates returned per request. The default
            (if omitted) and maximum is 50 templates per request.
          schema:
            type: integer
            format: int32
            default: 50
        - name: offset
          in: query
          description: >-
            The pagination or "starting point" of the templates to be returned.
            Setting it to 0 with a limit of 50 will retrieve the first 50
            templates. Increasing the offset by 50 will return the next set of
            templates, and so on.
          schema:
            type: integer
            format: int32
            default: 0
        - name: Authorization
          in: header
          description: >-
            Your App API key with prefix `Key `. See [Keys &
            IDs](/docs/en/keys-and-ids).
          required: true
          schema:
            type: string
            default: Key YOUR_APP_API_KEY
        - name: Content-Type
          in: header
          required: true
          schema:
            type: string
            default: application/json; charset=utf-8
        - name: channel
          in: query
          description: >-
            Filter the fetched templates by the delivery channel. Available
            options are: `push`, `email`, and `SMS`.
          schema:
            type: string
            enum:
              - push
              - email
              - sms
      responses:
        '200':
          description: '200'
          content:
            application/json:
              examples:
                Result:
                  value: |-
                    {
                        "limit": 50,
                        "offset": 0,
                        "templates": [
                            {
                                "id": "9e778dd4-6453-40d7-888d-9d9f327b9b66",
                                "name": "OneSignal Push: New Feature Announcement (Template)",
                                "created_at": "2021-07-23T18:02:23.956Z",
                                "updated_at": "2021-07-23T18:02:23.956Z"
                            },
                            {
                                "id": "806b4356-67af-4d33-8133-75e502f6d3b7",
                                "name": "OneSignal Push: User Action Notification (Template)",
                                "created_at": "2021-07-23T18:02:23.963Z",
                                "updated_at": "2021-07-23T18:02:23.963Z"
                            },
                            {
                                "id": "172f55b5-df07-49ae-8a8d-67037679487f",
                                "name": "OneSignal Push: Rating (Template)",
                                "created_at": "2021-07-23T18:02:23.984Z",
                                "updated_at": "2021-07-23T18:02:23.984Z"
                            }
                        ],
                        "total_count": 3
                    }
              schema:
                type: object
                properties:
                  limit:
                    type: integer
                    example: 50
                    default: 0
                  offset:
                    type: integer
                    example: 0
                    default: 0
                  templates:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          description: The ID of the template in UUID v4 format.
                        name:
                          type: string
                          description: >-
                            An internal name you set to help organize and track
                            Templates. Maximum 128 characters.
                        created_at:
                          type: string
                          description: >-
                            The date and time the template was created in ISO
                            8601 format.
                        updated_at:
                          type: string
                          description: >-
                            The date and time the template was last updated in
                            ISO 8601 format.
                  total_count:
                    type: integer
                    example: 3
                    default: 0
        '400':
          description: '400'
          content:
            application/json:
              examples:
                Bad Request (Missing App ID):
                  value: |
                    {
                      "errors": ["Request is malformed: Failed to parse app_id from request", "JSON body is None for app_id_location=body request"]
                    }
                Bad Request (Invalid Limit):
                  value: |-
                    {
                        "errors": [
                            "Invalid limit, must be within 1 to 50"
                        ]
                    }
                Bad Request (Invalid Channel):
                  value: |-
                    {
                        "errors": [
                            "Invalid channel"
                        ]
                    }
              schema:
                oneOf:
                  - title: Bad Request (Missing App ID)
                    type: object
                    properties:
                      errors:
                        type: array
                        items:
                          type: string
                          example: >-
                            Request is malformed: Failed to parse app_id from
                            request
                  - title: Bad Request (Invalid Limit)
                    type: object
                    properties:
                      errors:
                        type: array
                        items:
                          type: string
                          example: Invalid limit, must be within 1 to 50
                  - title: Bad Request (Invalid Channel)
                    type: object
                    properties:
                      errors:
                        type: array
                        items:
                          type: string
                          example: Invalid channel
        '429':
          description: '429'
          content:
            application/json:
              examples:
                Result:
                  value:
                    errors:
                      - code: Rate Limit Exceeded
                        title: Example error title
                        meta: {}
              schema:
                $ref: '#/components/schemas/StructuredErrorResponse'
          headers:
            Retry-After:
              description: >-
                Number of seconds to wait before retrying the request. Always
                emitted on 429 responses.
              schema:
                type: integer
                minimum: 0
        '503':
          description: >-
            Service temporarily unavailable. Retry after a short backoff. The
            body may be empty or non-JSON in some failure modes.
          headers:
            Retry-After:
              description: >-
                Number of seconds to wait before retrying. Optional — may be
                absent when the response is generated upstream.
              schema:
                type: integer
                minimum: 0
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BasicErrorResponse'
              example:
                errors:
                  - Service temporarily unavailable
      deprecated: false
      security: []
      x-codeSamples:
        - lang: typescript
          label: Node.js SDK
          source: >-
            import Onesignal from '@onesignal/node-onesignal';


            const configuration = Onesignal.createConfiguration({
                restApiKey: 'YOUR_REST_API_KEY',
            });

            const apiInstance = new Onesignal.DefaultApi(configuration);


            // string | Your OneSignal App ID in UUID v4 format.

            const appId: string = "00000000-0000-0000-0000-000000000000";

            // number | Maximum number of templates. Default and max is 50.
            (optional)

            const limit: number = 10;

            // number | Pagination offset. (optional)

            const offset: number = 0;

            // 'push' | 'email' | 'sms' | Filter by delivery channel. (optional)

            const channel: 'push' | 'email' | 'sms' = "push";


            try {
              const response = await apiInstance.viewTemplates(appId, limit, offset, channel);
              console.log(response);
            } catch (e) {
              if (e instanceof Onesignal.ApiException) {
                // `e.errorMessages` flattens any error-envelope shape to a `string[]`;
                // the raw parsed body remains on `e.body`.
                console.error("viewTemplates failed: HTTP " + e.code, e.errorMessages);
              } else {
                throw e;
              }
            }
        - lang: python
          label: Python SDK
          source: >-
            import onesignal

            from onesignal.api import default_api

            from onesignal.models import *

            from pprint import pprint


            # See configuration.py for a list of all supported configuration
            parameters.

            # Some of the OneSignal endpoints require ORGANIZATION_API_KEY token
            for authorization, while others require REST_API_KEY.

            # We recommend adding both of them in the configuration page so that
            you will not need to figure it out yourself.

            configuration = onesignal.Configuration(
                rest_api_key = "YOUR_REST_API_KEY", # App REST API key required for most endpoints
                organization_api_key = "YOUR_ORGANIZATION_API_KEY" # Organization key is only required for creating new apps and other top-level endpoints
            )



            # Enter a context with an instance of the API client

            with onesignal.ApiClient(configuration) as api_client:
                # Create an instance of the API class
                api_instance = default_api.DefaultApi(api_client)
                app_id = "00000000-0000-0000-0000-000000000000" # Your OneSignal App ID in UUID v4 format. 
                limit = 10  # Maximum number of templates. Default and max is 50. (optional) 
                offset = 0  # Pagination offset. (optional) 
                channel = "push"  # Filter by delivery channel. (optional) 

                try:
                    # View templates
                    api_response = api_instance.view_templates(app_id, limit=limit, offset=offset, channel=channel)
                    pprint(api_response)
                except onesignal.ApiException as e:
                    print("Exception when calling DefaultApi->view_templates: %s\n" % e)
                    print("Status Code: %s" % e.status)
                    print("Response Body: %s" % e.body)
        - lang: php
          label: PHP SDK
          source: >-
            <?php

            require_once(__DIR__ . '/vendor/autoload.php');



            // Configure Bearer authorization: rest_api_key

            $config = onesignal\client\Configuration::getDefaultConfiguration()
                                                            ->setRestApiKeyToken('YOUR_REST_API_KEY')
                                                            ->setOrganizationApiKeyToken('YOUR_ORGANIZATION_API_KEY');



            $apiInstance = new onesignal\client\Api\DefaultApi(
                // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`.
                // This is optional, `GuzzleHttp\Client` will be used as default.
                new GuzzleHttp\Client(),
                $config
            );

            $app_id = '00000000-0000-0000-0000-000000000000'; // string | Your
            OneSignal App ID in UUID v4 format.

            $limit = 10; // int | Maximum number of templates. Default and max
            is 50.

            $offset = 0; // int | Pagination offset.

            $channel = 'push'; // string | Filter by delivery channel.


            try {
                $result = $apiInstance->viewTemplates($app_id, $limit, $offset, $channel);
                print_r($result);
            } catch (\onesignal\client\ApiException $e) {
                echo 'Exception when calling DefaultApi->viewTemplates: ', $e->getMessage(), PHP_EOL;
                echo 'Status Code: ', $e->getCode(), PHP_EOL;
                // getErrorMessages() flattens any error-envelope shape to a string[];
                // the raw body remains on getResponseBody().
                echo 'Error Messages: ', implode(', ', $e->getErrorMessages()), PHP_EOL;
                echo 'Response Body: ', $e->getResponseBody(), PHP_EOL;
            } catch (\Exception $e) {
                echo 'Exception when calling DefaultApi->viewTemplates: ', $e->getMessage(), PHP_EOL;
            }
        - lang: go
          label: Go SDK
          source: |-
            package main

            import (
                "context"
                "fmt"
                "os"

                "github.com/OneSignal/onesignal-go-api/v5"
            )

            func main() {
                appId := "00000000-0000-0000-0000-000000000000" // string | Your OneSignal App ID in UUID v4 format.
                limit := int32(10) // int32 | Maximum number of templates. Default and max is 50. (optional) (default to 50)
                offset := int32(0) // int32 | Pagination offset. (optional) (default to 0)
                channel := "push" // string | Filter by delivery channel. (optional)

                configuration := onesignal.NewConfiguration()
                apiClient := onesignal.NewAPIClient(configuration)

                restAuth := context.WithValue(context.Background(), onesignal.RestApiKey, "YOUR_REST_API_KEY") // App REST API key required for most endpoints

                resp, r, err := apiClient.DefaultApi.ViewTemplates(restAuth).AppId(appId).Limit(limit).Offset(offset).Channel(channel).Execute()

                if err != nil {
                    fmt.Fprintf(os.Stderr, "Error when calling `DefaultApi.ViewTemplates``: %v\n", err)
                    fmt.Fprintf(os.Stderr, "Full HTTP response: %v\n", r)
                    if apiErr, ok := err.(*onesignal.GenericOpenAPIError); ok {
                        // ErrorMessages() flattens any error-envelope shape to a []string;
                        // the raw body remains on Body().
                        fmt.Fprintf(os.Stderr, "Error Messages: %v\n", apiErr.ErrorMessages())
                        fmt.Fprintf(os.Stderr, "Response Body: %s\n", apiErr.Body())
                    }
                }
                // response from `ViewTemplates`: TemplatesListResponse
                fmt.Fprintf(os.Stdout, "Response from `DefaultApi.ViewTemplates`: %v\n", resp)
            }
        - lang: ruby
          label: Ruby SDK
          source: >-
            require 'onesignal'

            # setup authorization

            OneSignal.configure do |config|
              # Configure Bearer authorization: rest_api_key
              config.rest_api_key = 'YOUR_REST_API_KEY'

            end


            api_instance = OneSignal::DefaultApi.new

            app_id = '00000000-0000-0000-0000-000000000000' # String | Your
            OneSignal App ID in UUID v4 format.

            opts = {
              limit: 10, # Integer | Maximum number of templates. Default and max is 50.
              offset: 0, # Integer | Pagination offset.
              channel: 'push' # String | Filter by delivery channel.
            }


            begin
              # View templates
              result = api_instance.view_templates(app_id, opts)
              p result
            rescue OneSignal::ApiError => e
              puts "Error when calling DefaultApi->view_templates: #{e}"
              puts "Status Code: #{e.code}"
              # `e.error_messages` flattens any error-envelope shape to an Array<String>;
              # the raw body remains on `e.response_body`.
              puts "Error Messages: #{e.error_messages}"
              puts "Response Body: #{e.response_body}"
            end
        - lang: java
          label: Java SDK
          source: |-
            // Import classes:
            import com.onesignal.client.ApiClient;
            import com.onesignal.client.ApiException;
            import com.onesignal.client.Configuration;
            import com.onesignal.client.auth.*;
            import com.onesignal.client.model.*;
            import com.onesignal.client.api.DefaultApi;

            public class Example {
              public static void main(String[] args) {
                ApiClient defaultClient = Configuration.getDefaultApiClient();
                defaultClient.setBasePath("https://api.onesignal.com");
                
                // Configure HTTP bearer authorization: rest_api_key
                HttpBearerAuth rest_api_key = (HttpBearerAuth) defaultClient.getAuthentication("rest_api_key");
                rest_api_key.setBearerToken("YOUR_REST_API_KEY");

                DefaultApi apiInstance = new DefaultApi(defaultClient);
                String appId = "00000000-0000-0000-0000-000000000000"; // String | Your OneSignal App ID in UUID v4 format.
                Integer limit = 10; // Integer | Maximum number of templates. Default and max is 50.
                Integer offset = 0; // Integer | Pagination offset.
                String channel = "push"; // String | Filter by delivery channel.
                try {
                  TemplatesListResponse result = apiInstance.viewTemplates(appId, limit, offset, channel);
                  System.out.println(result);
                } catch (ApiException e) {
                  System.err.println("Exception when calling DefaultApi#viewTemplates");
                  System.err.println("Status code: " + e.getCode());
                  // getErrorMessages() flattens any error-envelope shape to a List<String>;
                  // the raw body remains on getResponseBody().
                  System.err.println("Error messages: " + e.getErrorMessages());
                  System.err.println("Reason: " + e.getResponseBody());
                  System.err.println("Response headers: " + e.getResponseHeaders());
                  e.printStackTrace();
                }
              }
            }
        - lang: csharp
          label: C# SDK
          source: |-
            using System;
            using System.Collections.Generic;
            using System.Diagnostics;
            using OneSignalApi.Api;
            using OneSignalApi.Client;
            using OneSignalApi.Model;

            namespace Example
            {
                public class ViewTemplatesExample
                {
                    public static void Main()
                    {
                        Configuration config = new Configuration();
                        config.BasePath = "https://api.onesignal.com";
                        // Configure Bearer token for authorization: rest_api_key
                        config.AccessToken = "YOUR_REST_API_KEY";

                        var apiInstance = new DefaultApi(config);
                        var appId = "00000000-0000-0000-0000-000000000000";  // string | Your OneSignal App ID in UUID v4 format.
                        var limit = 10;  // int? | Maximum number of templates. Default and max is 50. (optional)  (default to 50)
                        var offset = 0;  // int? | Pagination offset. (optional)  (default to 0)
                        var channel = "push";  // string | Filter by delivery channel. (optional) 

                        try
                        {
                            // View templates
                            TemplatesListResponse result = apiInstance.ViewTemplates(appId, limit, offset, channel);
                            Debug.WriteLine(result);
                        }
                        catch (ApiException  e)
                        {
                            Debug.Print("Exception when calling DefaultApi.ViewTemplates: " + e.Message );
                            Debug.Print("Status Code: "+ e.ErrorCode);
                            // e.ErrorMessages flattens any error-envelope shape to an IReadOnlyList<string>;
                            // the raw body remains on e.ErrorContent.
                            Debug.Print("Error Messages: " + string.Join(", ", e.ErrorMessages));
                            Debug.Print("Response Body: " + e.ErrorContent);
                            Debug.Print(e.StackTrace);
                        }
                    }
                }
            }
        - lang: rust
          label: Rust SDK
          source: |-
            use onesignal_rust_api::apis::configuration::Configuration;
            use onesignal_rust_api::apis::default_api;


            #[tokio::main]
            async fn main() {
                let mut configuration = Configuration::new();
                configuration.rest_api_key_token = Some("YOUR_REST_API_KEY".to_string());


                // Realistic values are pulled from the spec's `example:` fields where present.
                let app_id: &str = "00000000-0000-0000-0000-000000000000";
                let limit: Option<i32> = None;
                let offset: Option<i32> = None;
                let channel: Option<&str> = None;

                match default_api::view_templates(&configuration, app_id, limit, offset, channel).await {
                    Ok(resp) => println!("{:?}", resp),
                    Err(e @ onesignal_rust_api::apis::Error::ResponseError(_)) => {
                        // `e.error_messages()` flattens any error-envelope shape to a Vec<String>;
                        // the raw response remains on the ResponseError variant.
                        eprintln!("view_templates failed: {:?}", e.error_messages());
                    }
                    Err(e) => eprintln!("view_templates failed: {:?}", e),
                }
            }
components:
  schemas:
    StructuredErrorResponse:
      type: object
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/StructuredErrorItem'
    BasicErrorResponse:
      type: object
      properties:
        errors:
          type: array
          items:
            type: string
          description: One or more human-readable error messages.
        success:
          type: boolean
          description: >-
            Present (and `false`) on some endpoints (notifications, templates,
            segments). Not emitted by every endpoint.
        reference:
          type: array
          items:
            type: string
          description: >-
            Documentation URL fragments related to the error. Only emitted by
            the API-key auth error helpers.
    StructuredErrorItem:
      type: object
      required:
        - code
        - title
      properties:
        code:
          type: string
          description: >-
            Stable error-code identifier. Use this for programmatic branching in
            your integration.
        title:
          type: string
          description: >-
            Human-readable error message intended for logs and operator-facing
            surfaces.
        meta:
          type: object
          additionalProperties: true
          description: >-
            Optional structured details about this specific error. The shape of
            `meta` varies by `code` — for example, the create-user `Conflict`
            code returns `{ conflicting_aliases: { [alias_label]: alias_id } }`.

````