<span aria-hidden="true" id="create-a-new-template"></span>



# Create a new Template

Creates a reusable Template from Assembly Instructions.

`POST` `https://api2.transloadit.com/templates`

<span aria-hidden="true" id="request-example"></span>



## Request example

Run this request in a server-side shell with `curl` and a suitable [bearer token](/docs/api/token-post.md) in `TRANSLOADIT_TOKEN`. If you need a token, expand the setup below.

**Need a bearer token?**

In a trusted server-side shell with `curl` and `jq`, set `TRANSLOADIT_KEY` and `TRANSLOADIT_SECRET` to your Auth Key and Auth Secret. Keep both credentials and the resulting token secret; never run this setup in browser code.

First, create a token with this endpoint’s required scopes. Your Auth Key must already grant those scopes.

```bash
if ! TOKEN_RESPONSE="$(curl --fail-with-body -sS \
  --request POST \
  --url 'https://api2.transloadit.com/token' \
  --user "${TRANSLOADIT_KEY:?Set TRANSLOADIT_KEY}:${TRANSLOADIT_SECRET:?Set TRANSLOADIT_SECRET}" \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode 'aud=api2' \
  --data-urlencode 'scope=templates:write')"; then
  printf '%s\n' "$TOKEN_RESPONSE" >&2
  exit 1
fi
TRANSLOADIT_TOKEN="$(printf '%s' "$TOKEN_RESPONSE" |
  jq -er '.access_token | strings | select(length > 0)')" || exit 1
```

Keep this shell open and run the request below. Reuse the token while it remains valid.

```bash
curl --fail-with-body -sS --request POST \
  --url "https://api2.transloadit.com/templates" \
  --header "Authorization: Bearer ${TRANSLOADIT_TOKEN:?Set TRANSLOADIT_TOKEN}" \
  --data-urlencode 'params={"name":"resize-images","template":{"steps":{"resize":{"robot":"/image/resize","use":":original","width":320}}}}'
```

<span aria-hidden="true" id="authentication"></span>



## Authentication

This endpoint accepts signed `params` or a bearer token. See [Authentication](/docs/api/authentication.md) for setup instructions.

Required scope for the Auth Key or bearer token: `templates:write`.

Signed requests require both a `signature` and a future `params.auth.expires` timestamp. Bearer tokens do not require either.

<span aria-hidden="true" id="post-fields"></span>



## Form fields

Content type: `application/x-www-form-urlencoded`

* `params` (JSON string), required. A JSON-encoded object whose supported keys are listed below.
* `signature` (string). Required for signed requests. Omit this field when using a bearer token.

<span aria-hidden="true" id="params-fields"></span><span aria-hidden="true" id="supported-keys"></span><span aria-hidden="true" id="supported-keys-inside-the-params-field"></span>



## Supported keys inside the `params` field

Authentication fields in this list apply to signed requests. With a bearer token, you can omit `params.auth` and the separate `signature` field. Compare the authentication-specific request parameters below.

[Complete JSON Schema](/api-reference/schemas/templates-post/params-fields.json)

`params`: Only the fields listed for this object are accepted.

<span aria-hidden="true" id="params-fields-assembly_status_expiry"></span><span aria-hidden="true" id="assembly_status_expiry"></span>



### `params.assembly_status_expiry`

`"1day" | "30days" | "7days" | "90days" | "NoSave"`

Controls how long the Assembly Status is retained for Assemblies created from this Template.

<span aria-hidden="true" id="params-fields-auth"></span><span aria-hidden="true" id="auth"></span>



### `params.auth` (required for signed requests; optional with a bearer token)

[`object`](#params-fields-auth-expires)

Contains the Transloadit API key and signature-authentication metadata for a Template request.

`params.auth`: Only the fields listed for this object are accepted.

<span aria-hidden="true" id="params-fields-auth-expires"></span>



#### `params.auth.expires` (required)

`string`

ISO 8601 expiration timestamp in the future. Required when a request is signed or requires signature authentication; bearer-authenticated requests may omit it.

<span aria-hidden="true" id="params-fields-auth-key"></span>



#### `params.auth.key` (required)

`string`

Transloadit API key used to authenticate requests

<span aria-hidden="true" id="params-fields-name"></span><span aria-hidden="true" id="name"></span>



### `params.name` (required)

`string` (minimum length: 3, maximum length: 200)

Name of this Template. Use 3–200 lowercase Latin letters, numbers, or dashes. The name `tmp` and service-reserved names are unavailable.

Validation pattern (regular expression): `^(?:[a-su-z0-9-][a-z0-9-]{2,199}|t[a-ln-z0-9-][a-z0-9-]{1,198}|tm[a-oq-z0-9-][a-z0-9-]{0,197}|tmp[a-z0-9-]{1,197})$`

<span aria-hidden="true" id="params-fields-nonce"></span><span aria-hidden="true" id="params-fields-auth-nonce"></span><span aria-hidden="true" id="nonce"></span>



### `params.nonce`

`string | integer`

Unique, random value included in signed request params to make each signature unique and prevent accidental signature reuse.

<span aria-hidden="true" id="params-fields-require_signature_auth"></span><span aria-hidden="true" id="require_signature_auth"></span>



### `params.require_signature_auth`

`0 | 1` (default: 0)

Use `1` to require a valid signature when creating Assemblies from this Template with an Auth Key. Valid bearer tokens bypass this signature requirement; their scopes and audience still apply. This setting does not add authentication to Assembly status, cancellation or upload capability URLs. See [Signature Authentication](/docs/api/authentication.md).

<span aria-hidden="true" id="params-fields-template"></span><span aria-hidden="true" id="template"></span>



### `params.template` (required)

`object | string`

Assembly Instructions stored in this Template. Prefer the structured JSON object; a JSON-encoded string remains accepted for compatibility.

**Any of the following schemas may apply:**

* [`object`](#params-fields-template-anyOf-1-allow_steps_override)

  Structured Assembly Instructions stored in this Template.

  `params.template`: Only the fields listed for this object are accepted.

  * <span aria-hidden="true" id="params-fields-template-anyOf-1-allow_steps_override"></span>



    **`params.template.allow_steps_override`**

    `boolean`

    Set this to false in a stored Template to disallow overriding its Steps at runtime. The Template may then be used with `template_id`, or direct `steps` may be supplied without it, but not both. A value supplied only while creating an Assembly does not control this policy.
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-auth"></span>



    **`params.template.auth`**

    `object`

    Optional authentication and upload constraints for an Assembly. The API key may be omitted for bearer-authenticated requests or when only upload constraints are stored in a Template.

    [Additional schema details are available in the complete JSON Schema.](/api-reference/schemas/templates-post/params-fields.json)
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-emit_execution_progress"></span>



    **`params.template.emit_execution_progress`**

    `boolean`

    Set to true to publish real-time Assembly execution-progress events. This is ignored for URL Transform Assemblies.
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-exiftool_stack"></span>



    **`params.template.exiftool_stack`**

    `string`

    Ignored when stored in a Template. To select the ExifTool stack for metadata extraction, set `exiftool_stack` in the top-level Assembly request params instead.
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-ffmpeg_stack"></span>



    **`params.template.ffmpeg_stack`**

    `string`

    Ignored when stored in a Template. To select the FFmpeg stack for metadata extraction, set `ffmpeg_stack` in the top-level Assembly request params instead.
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-fields"></span>



    **`params.template.fields`**

    `object`

    An object of string keyed values (name -> value) that can be used as Assembly Variables, just like additional form fields can. You can use anything that is JSON stringifyable as a value

    [Additional schema details are available in the complete JSON Schema.](/api-reference/schemas/templates-post/params-fields.json)
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-imagemagick_stack"></span>



    **`params.template.imagemagick_stack`**

    `string`

    Ignored when stored in a Template. To select the ImageMagick stack for metadata extraction, set `imagemagick_stack` in the top-level Assembly request params instead.
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-mediainfo_stack"></span>



    **`params.template.mediainfo_stack`**

    `string`

    Ignored when stored in a Template. To select the MediaInfo stack for metadata extraction, set `mediainfo_stack` in the top-level Assembly request params instead.
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-mplayer_stack"></span>



    **`params.template.mplayer_stack`**

    `string`

    Ignored when stored in a Template. To select the MPlayer stack for metadata extraction, set `mplayer_stack` in the top-level Assembly request params instead.
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-notification_payload"></span>



    **`params.template.notification_payload`**

    `Array<"without_params" | "without_result_meta_data" | "without_results" | "without_upload_meta_data" | "without_uploads">`

    Controls the size of the payload sent in Assembly notifications. Notification replays reuse filters supplied in the original Assembly request; filters defined only in a Template are not preserved on replay. An empty array (default) sends the complete Assembly Status. Add `"without_params"` so the top-level raw Assembly instruction fields `params`, `template`, and `merged_params` are omitted. Add `"without_result_meta_data"` so `meta` is omitted from each file in `results`. Add `"without_results"` so the top-level `results` object is omitted. Add `"without_upload_meta_data"` so `meta` is omitted from each file in `uploads`. Add `"without_uploads"` so the top-level `uploads` array is omitted. Filtering is applied before serialization, so using these options reduces memory use and helps avoid oversized-payload or OOM failures on large Assemblies.
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-notify_url"></span>



    **`params.template.notify_url`**

    `null | string`

    Transloadit can send a Pingback to your server when the Assembly is completed. We’ll send the Assembly Status as a JSON string in the `transloadit` field of an `application/x-www-form-urlencoded` POST request to the URL supplied here. Use `notification_payload` to reduce the payload size (e.g. `without_uploads`, `without_results`, `without_params`). Notification replays reuse only filters supplied in the original Assembly request, not filters defined only in a Template.
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-quiet"></span>



    **`params.template.quiet`**

    `boolean`

    Set this to true to minimize the initial Assembly-creation response. A successful response includes only ok and assembly\_id; an error response retains error, http\_code, message, reason and assembly\_id when available. This is response minimization, not access control: anyone with the returned Assembly ID can still retrieve the full Assembly Status, including fields and results, without additional authentication. Treat Assembly IDs and status URLs as secret capabilities. The full Assembly Status is still sent to notify\_url when configured.
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-redirect_url"></span>



    **`params.template.redirect_url`**

    `string`

    URL to redirect a browser upload to after the upload completes. The Assembly ID and status URL are appended as query parameters while preserving any existing query parameters and fragment.
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-response_headers"></span>



    **`params.template.response_headers`**

    `object`

    Custom response headers emitted by an Assembly. CORS overrides belong in `cors`; other top-level keys are emitted as custom headers.

    [Additional schema details are available in the complete JSON Schema.](/api-reference/schemas/templates-post/params-fields.json)
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-steps"></span>



    **`params.template.steps`**

    `referenced schema`

    Contains Assembly Instructions.

    [Additional schema details are available in the complete JSON Schema.](/api-reference/schemas/templates-post/params-fields.json)
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-template_id"></span>



    **`params.template.template_id`**

    `string`

    Ignored when stored in a Template. Templates do not inherit Instructions from another Template. Put the Steps directly in this Template and select it using `template_id` in the top-level Assembly request params.
  * <span aria-hidden="true" id="params-fields-template-anyOf-1-usage_tags"></span>



    **`params.template.usage_tags`**

    `string`

    Usage tags recorded on an Assembly.
* `string`

  JSON-encoded Assembly Instructions retained for client compatibility.

  [Validation pattern (regular expression)](/api-reference/schemas/templates-post/params-fields.json)

<span aria-hidden="true" id="params-fields-transcoding_result_expiry"></span><span aria-hidden="true" id="transcoding_result_expiry"></span>



### `params.transcoding_result_expiry`

`"1day" | "NoSave"`

Controls how long transcoding results are retained for Assemblies created from this Template.

<span aria-hidden="true" id="authentication-specific-params"></span>



## Request parameters by authentication method

<span aria-hidden="true" id="signed-params"></span>



### With signed params

Include your Auth Key as `params.auth.key`. When signing the request, include a future `params.auth.expires` timestamp and send the signature in the separate `signature` field. The field definitions below use paths inside `params`.

[Complete JSON Schema](/api-reference/schemas/templates-post/signed-params.json)

`params`: Only the fields listed for this object are accepted.

<span aria-hidden="true" id="signed-params-assembly_status_expiry"></span><span aria-hidden="true" id="signed-params-auth"></span><span aria-hidden="true" id="signed-params-auth-expires"></span><span aria-hidden="true" id="signed-params-auth-key"></span><span aria-hidden="true" id="signed-params-name"></span><span aria-hidden="true" id="signed-params-nonce"></span><span aria-hidden="true" id="signed-params-auth-nonce"></span><span aria-hidden="true" id="signed-params-require_signature_auth"></span><span aria-hidden="true" id="signed-params-template"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-allow_steps_override"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-auth"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-emit_execution_progress"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-exiftool_stack"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-ffmpeg_stack"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-fields"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-imagemagick_stack"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-mediainfo_stack"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-mplayer_stack"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-notification_payload"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-notify_url"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-quiet"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-redirect_url"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-response_headers"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-steps"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-template_id"></span><span aria-hidden="true" id="signed-params-template-anyOf-1-usage_tags"></span><span aria-hidden="true" id="signed-params-transcoding_result_expiry"></span>



Uses the field definitions above: [`params.assembly_status_expiry`](#params-fields-assembly_status_expiry), [`params.auth`](#params-fields-auth), [`params.name`](#params-fields-name), [`params.nonce`](#params-fields-nonce), [`params.require_signature_auth`](#params-fields-require_signature_auth), [`params.template`](#params-fields-template), [`params.transcoding_result_expiry`](#params-fields-transcoding_result_expiry)

<span aria-hidden="true" id="bearer-params"></span>



### With a bearer token

Send the bearer token in the `Authorization` header. You can omit `params.auth` and the separate `signature` field. Other required parameters still apply. The field definitions below use paths inside `params`.

[Complete JSON Schema](/api-reference/schemas/templates-post/bearer-params.json)

`params`: Only the fields listed for this object are accepted.

<span aria-hidden="true" id="bearer-params-assembly_status_expiry"></span><span aria-hidden="true" id="bearer-params-name"></span><span aria-hidden="true" id="bearer-params-nonce"></span><span aria-hidden="true" id="bearer-params-auth-nonce"></span><span aria-hidden="true" id="bearer-params-require_signature_auth"></span><span aria-hidden="true" id="bearer-params-template"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-allow_steps_override"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-auth"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-emit_execution_progress"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-exiftool_stack"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-ffmpeg_stack"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-fields"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-imagemagick_stack"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-mediainfo_stack"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-mplayer_stack"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-notification_payload"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-notify_url"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-quiet"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-redirect_url"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-response_headers"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-steps"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-template_id"></span><span aria-hidden="true" id="bearer-params-template-anyOf-1-usage_tags"></span><span aria-hidden="true" id="bearer-params-transcoding_result_expiry"></span>



Uses the field definitions above: [`params.assembly_status_expiry`](#params-fields-assembly_status_expiry), [`params.name`](#params-fields-name), [`params.nonce`](#params-fields-nonce), [`params.require_signature_auth`](#params-fields-require_signature_auth), [`params.template`](#params-fields-template), [`params.transcoding_result_expiry`](#params-fields-transcoding_result_expiry)

<span aria-hidden="true" id="bearer-params-auth"></span>



#### `params.auth`

[`object`](#bearer-params-auth-expires)

Contains the Transloadit API key and signature-authentication metadata for a Template request.

`params.auth`: Only the fields listed for this object are accepted.

<span aria-hidden="true" id="bearer-params-auth-expires"></span>



##### `params.auth.expires`

`string`

ISO 8601 expiration timestamp in the future. Required when a request is signed or requires signature authentication; bearer-authenticated requests may omit it.

<span aria-hidden="true" id="bearer-params-auth-key"></span>



##### `params.auth.key`

`string`

Transloadit API key used to authenticate requests

<span aria-hidden="true" id="response"></span>



## Response

Here’s an example response body:

```jsonc
{
  "assembly_status_expiry": null,
  "content": {
    "steps": {
      "resize": {
        "robot": "/image/resize",
        "use": ":original",
        "width": 320
      }
    }
  },
  "id": "8fc3b9166c784afd824acf24269ebd11",
  "message": "Your Template was successfully created.",
  "name": "resize-images",
  "ok": "TEMPLATE_CREATED",
  "require_signature_auth": 0,
  "transcoding_result_expiry": null
}
```

<span aria-hidden="true" id="response-1"></span>



### 2xx success

JSON response body. `application/json` `text/plain; charset=utf-8`

<span aria-hidden="true" id="response-1-body"></span>



#### Response body schema

[Complete JSON Schema](/api-reference/schemas/templates-post/response-1-body.json)

The response contains only the fields listed for this object.

<span aria-hidden="true" id="response-1-body-assembly_status_expiry"></span>



##### `assembly_status_expiry` (required)

`null | string`

<span aria-hidden="true" id="response-1-body-content"></span>



##### `content` (required)

`object | Array<any value> | string | number | boolean | null`

**Any of the following schemas may apply:**

* `object`

  * **Additional property schema**

    `any value`
* `Array<any value>`

  * **Array item schema**

    `any value`
* `string`
* `number`
* `boolean`
* `null`

<span aria-hidden="true" id="response-1-body-id"></span>



##### `id` (required)

`string`

**Any of the following schemas may apply:**

* **Variant 1**

  `string` (maximum length: 32)

  Validation pattern (regular expression): `^[\x00-\x7F]*$`
* **Variant 2**

  `string` (maximum length: 32)

  Validation pattern (regular expression): `^builtin\/[a-z0-9-]+(?:@[0-9a-z.-]+)?$`

<span aria-hidden="true" id="response-1-body-message"></span>



##### `message` (required)

`string` (minimum length: 1)

<span aria-hidden="true" id="response-1-body-name"></span>



##### `name` (required)

`string` (minimum length: 1, maximum length: 255)

<span aria-hidden="true" id="response-1-body-ok"></span>



##### `ok` (required)

`string` (always: "TEMPLATE\_CREATED")

<span aria-hidden="true" id="response-1-body-require_signature_auth"></span>



##### `require_signature_auth` (required)

`0 | 1`

<span aria-hidden="true" id="response-1-body-transcoding_result_expiry"></span>



##### `transcoding_result_expiry` (required)

`null | string`

<span aria-hidden="true" id="response-2"></span>



### Error response

JSON response body. `application/json` `text/plain; charset=utf-8`

<span aria-hidden="true" id="response-2-body"></span>



#### Response body schema

[Complete JSON Schema](/api-reference/schemas/templates-post/response-2-body.json)

At least one of these properties is required: error, message, reason

The response may contain additional fields.

<span aria-hidden="true" id="response-2-body-allOf-1-assembly_id"></span>



##### `assembly_id`

`string`

<span aria-hidden="true" id="response-2-body-allOf-1-error"></span>



##### `error`

`string` (minimum length: 1)

<span aria-hidden="true" id="response-2-body-allOf-1-http_code"></span>



##### `http_code`

`number | string`

* `number`
* `string`

  [Validation pattern (regular expression)](/api-reference/schemas/templates-post/response-2-body.json)

<span aria-hidden="true" id="response-2-body-allOf-1-message"></span>



##### `message`

`string`

Human-readable explanation of the error. Its wording can vary; use the `error` code when handling a specific failure.

<span aria-hidden="true" id="response-2-body-allOf-1-reason"></span>



##### `reason`

`null | string | number | boolean | Array<any value> | object`

**Any of the following schemas may apply:**

* `null`
* `string`
* `number`
* `boolean`
* `Array<any value>`

  * **Array item schema**

    `any value`
* `object`

  * **Additional property schema**

    `any value`

<span aria-hidden="true" id="response-3"></span>



### HTTP 400

JSON response body. `application/json` `text/plain; charset=utf-8`

<span aria-hidden="true" id="response-3-body"></span>



#### Response body schema

[Complete JSON Schema](/api-reference/schemas/templates-post/response-3-body.json)

**Named errors and the general error format**

* **error: "TEMPLATE\_VALIDATION\_ERROR"**

  Your Template didn’t pass validation.

  The response may contain additional fields.

  * <span aria-hidden="true" id="response-3-body-anyOf-1-error"></span>



    **`error` (required)**

    `string` (always: "TEMPLATE\_VALIDATION\_ERROR")
  * <span aria-hidden="true" id="response-3-body-anyOf-1-http_code"></span>



    **`http_code`**

    `number` (always: 400)
  * <span aria-hidden="true" id="response-3-body-anyOf-1-message"></span>



    **`message`**

    `string`

    Human-readable explanation of the error. Its wording can vary; use the `error` code when handling a specific failure.
* **General error format**

  <span aria-hidden="true" id="response-3-body-anyOf-2-allOf-1-assembly_id"></span><span aria-hidden="true" id="response-3-body-anyOf-2-allOf-1-error"></span><span aria-hidden="true" id="response-3-body-anyOf-2-allOf-1-http_code"></span><span aria-hidden="true" id="response-3-body-anyOf-2-allOf-1-message"></span><span aria-hidden="true" id="response-3-body-anyOf-2-allOf-1-reason"></span>



  [See the general error response fields.](#response-2-body)
