---
name: azion-create-a-custom-template
description: >-
  Choose the variables each Data Stream log line carries with a custom template, then use it in a stream, in Azion Console or with the Azion API.
---

# Create a custom template

You can create a custom template for [Data Stream](/en/documentation/platform/data-stream/) from Azion Console or with the Azion API, and use it in any stream on your account. To change how a Standard HTTP/HTTPS POST endpoint joins the log lines, refer to [Customize the HTTP POST payload](/en/documentation/guides/platform/observability/data-stream-set-payload/) instead.

A preset template sends every variable it carries, and you cannot change its variables. A custom template sends only the entries of its **Data Set**, a JSON object whose keys you name and whose values are variables of the stream's data source. For the format, refer to [Custom templates](/en/documentation/platform/data-stream/templates-and-payload/#custom-templates).

The examples build `status-analysis`, a template with five *Applications* variables for an analysis of response status. Replace them with the variables you need.

---

Choose the interface you work in. The prerequisites and the three tasks follow that choice.

## Prerequisites

- The **Edit Data Stream** permission. With **View Data Stream** only, you can see templates and streams but not create or change them. For details, refer to [Stream settings](/en/documentation/platform/data-stream/stream-settings/#permissions).
- The variables you want in each log line, from the data source of the stream that uses the template. For every variable and the presets that carry it, refer to [Data sources and variables](/en/documentation/platform/data-stream/data-sources-and-variables/).
- To use the template, a stream on your account. To create one, refer to the [Data Stream quickstart](/en/documentation/platform/data-stream/quickstart/).

**Console**

- Access to Azion Console. To sign in, refer to [How to access Azion Console](/en/documentation/guides/platform/account-and-billing/how-to-access-azion-console/).
- An account with fewer than 3,000 workloads. At 3,000 workloads or more, the Console blocks the stream forms, which hold the template drawer, and you manage templates through the API only.

**API**

- A personal token. To create one, refer to [How to manage a personal token](/en/documentation/guides/platform/account-and-billing/personal-tokens/).
- `curl`.

---

## Create the template

The Console creates templates in a drawer of the stream form, not on a page of their own. The template belongs to the account, so every stream can use it.

**Console**

To create the template in Azion Console:

1. **Open Data Stream**

   Access [Azion Console](https://console.azion.com/) > **Data Stream**.

2. **Open a stream form**

   Select **+ Stream**, or select the row of an existing stream.

3. **Open the template drawer**

   In the **Render Template** section, open **Template** and select **Create Custom Template**. The **Create Custom Template** drawer opens.

4. **Name the template**

   In the **General** section, in **Name**, enter `status-analysis`.

5. **Enter the data set**

   In the **Data Set** section, enter the JSON object:

   ```json
   {
     "time": "$time",
     "host": "$host",
     "status": "$status",
     "request_uri": "$request_uri",
     "upstream_status": "$upstream_status"
   }
   ```

6. **Select Save**

The Console shows `Your custom template has been created`. **Template** lists `status-analysis` under *Custom Templates*, apart from the presets under *Azion's Templates*.

To start from a preset instead, select the preset in **Template**, then select **Duplicate Template** on the **Data Set** field. The **Create Custom Template** drawer opens with the preset's data set. Delete the entries you do not need, name the template, and select **Save**.

**API**

To create the template with the API, send a `POST` request with `name` and `data_set`. The `data_set` value is the JSON object as a string, with its quotes escaped:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/stream/templates \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "status-analysis",
  "data_set": "{\"time\": \"$time\", \"host\": \"$host\", \"status\": \"$status\", \"request_uri\": \"$request_uri\", \"upstream_status\": \"$upstream_status\"}"
}'
```

The API answers `201` with the stored template:

```json
{
  "state": "executed",
  "data": {
    "id": 1234,
    "name": "status-analysis",
    "last_editor": "user@example.com",
    "created_at": "2026-01-01T12:00:00.000000Z",
    "last_modified": "2026-01-01T12:00:00.000000Z",
    "custom": true,
    "active": true,
    "data_set": "{\"time\": \"$time\", \"host\": \"$host\", \"status\": \"$status\", \"request_uri\": \"$request_uri\", \"upstream_status\": \"$upstream_status\"}"
  }
}
```

The template exists with `custom: true`. Keep the value of `id`, which a stream uses to name the template. A `GET` request to `/v4/workspace/stream/templates` lists it beside the presets.

> **Caution**
>
> The API stores any string as the data set and does not check that it is JSON: a `data_set` of `not json` is accepted with `201`. Check that the data set is a valid JSON object before you send it.

---

## Use the template in a stream

A stream names one template. Selecting the custom template replaces the preset or template the stream used before.

**Console**

To use the template in a stream in Azion Console:

1. **Open the stream**

   Access [Azion Console](https://console.azion.com/) > **Data Stream**, then select the row of the stream. For a stream you are creating, stay in its form.

2. **Select the template**

   In the **Render Template** section, in **Template**, select `status-analysis` under *Custom Templates*. The read-only **Data Set** field shows its entries.

3. **Select Save**

4. **Confirm the sampling warning**

   If **Sampling** is on, the **Attention** dialog opens with `After activating and saving these settings, all other Data Streams will be disabled.` Select **Confirm**.

The Console shows `Your data stream has been updated`, or `Your data stream has been created` for a stream you are creating.

**API**

To use the template in a stream with the API, set `transform[render_template].attributes.template` to the template's `id`. Send the whole `transform` array: the `render_template` item, and the `filter_workloads` or `sampling` item the stream already has. Without either of those two items, the request fails with `32002`. Replace `<stream-id>` with the ID of your stream and `<workload-id>` with a workload of the stream:

```bash
curl --request PATCH \
  --url https://api.azion.com/v4/workspace/stream/streams/<stream-id> \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "transform": [
    { "type": "filter_workloads", "attributes": { "workloads": [<workload-id>] } },
    { "type": "render_template", "attributes": { "template": 1234 } }
  ]
}'
```

The stored stream names template `1234` in `transform[render_template].attributes.template`. To use the template in a stream you create, put the same `render_template` item in the create body. For the full body, refer to [Stream settings](/en/documentation/platform/data-stream/stream-settings/#stream-object).

A stream with a workload filter, as in the API example, leaves the other streams running. Saving an active stream that uses sampling deactivates every other stream on the account.

The log lines the stream sends after the change carry only the keys of the data set, such as `{"time": …, "host": …, "status": …, "request_uri": …, "upstream_status": …}`. To check the delivery, read one log line at the endpoint. Each send is also recorded, with the status code the endpoint returned, in [Real-Time Events](/en/documentation/platform/real-time-events/data-sources/#data-stream).

---

## Edit the template

To add or remove a variable on a running stream, change the data set of its custom template. A preset cannot be edited: duplicate it, then use the copy.

**Console**

To edit the template in Azion Console:

1. **Open the stream**

   Access [Azion Console](https://console.azion.com/) > **Data Stream**, then select the row of a stream that uses the template.

2. **Open the edit drawer**

   In the **Render Template** section, select **Edit Template** on the **Data Set** field. The **Edit Custom Template** drawer opens.

3. **Change the data set**

   In **Data Set**, add or delete entries. To also record the error status code of a request whose origin returned no response, add `"proxy_status": "$proxy_status"`.

4. **Select Save**

The Console shows `Your custom template has been updated`. To delete a custom template, the same drawer holds **Delete template** in its **Danger area**.

**API**

To edit the template with the API, send a `PATCH` request with only the keys you change. This example renames the template. Replace `<template-id>` with the template's `id`:

```bash
curl --request PATCH \
  --url https://api.azion.com/v4/workspace/stream/templates/<template-id> \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "status-analysis-2"
}'
```

The API answers `200` with the stored template:

```json
{
  "state": "executed",
  "data": {
    "id": 1234,
    "name": "status-analysis-2",
    "last_editor": "user@example.com",
    "created_at": "2026-01-01T12:00:00.000000Z",
    "last_modified": "2026-01-01T12:00:00.000000Z",
    "custom": true,
    "active": true,
    "data_set": "{\"time\": \"$time\", \"host\": \"$host\", \"status\": \"$status\", \"request_uri\": \"$request_uri\", \"upstream_status\": \"$upstream_status\"}"
  }
}
```

The response carries the changed `name` and a later `last_modified`, and `data_set` keeps its five entries. To change the variables, send `data_set` with the complete changed JSON object as an escaped string, as in the create. A `DELETE` request to the same path removes the template and answers `200` with `{"state":"executed"}`.

---

## Next steps

- [Templates and payload](/en/documentation/platform/data-stream/templates-and-payload.md#custom-templates): Look up the data set format, the preset data sets, and more custom template examples.
- [Data sources and variables](/en/documentation/platform/data-stream/data-sources-and-variables.md): Find what each variable carries before you add it to a data set.
- [Customize the HTTP POST payload](/en/documentation/guides/platform/observability/data-stream-set-payload.md): Set how a Standard HTTP/HTTPS POST endpoint receives the log lines.
- [Data Stream quickstart](/en/documentation/platform/data-stream/quickstart.md): Create a stream and confirm that its first logs reach the endpoint.
