> For the complete documentation index, see [llms.txt](https://docs.flowretail.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flowretail.com/docs/developers/api-documentation/templates/create-transaction-template.md).

# Create transaction template

Create transaction template

The type and the language together identify the text being written, and a tenant holds at most one template per type and language. A service template type the tenant created may be given a name, which every language of the type shares and which is shown in place of its key. Leave the language out to write the language-neutral template for the type — the one a recipient falls back to when nothing is written in a language closer to them. That is the platform's own types only: a service template type always carries a language, a write without one is refused for it, and the tenant's own language is the floor version the type must have before a rule or a send may name it.

The variables used in the body are validated against the variables the type offers; a template using a variable the type does not have is refused. The variables available to service message templates are listed on the service order template variables endpoint. A text of a type a variable is required in — requiredIn on that endpoint — whose body does not use it is refused with a 400 and writes nothing: SMS\_SERVICE\_ORDER\_UPDATED and EMAIL\_SERVICE\_ORDER\_UPDATED must use .serviceNote, the message staff write. On a service template type, a body that is empty or holds nothing but whitespace is refused with a 400 and writes nothing, whichever language it is written in: a text with nothing in it is no text, and a message is never composed from one.

Service message templates are not limited to platform-defined types: creating a template with a new type registers that type for the tenant, so a tenant with many statuses can author as many distinct messages as their workflow needs. A tenant-created type accepts every variable of the service catalog on save, and which ones the editor offers is templateTypes and ownTypeChannels on the service order template variables endpoint; platform-defined types keep the variable lists the metadata catalog gives them. A service template type must begin with SMS\_ or EMAIL\_, naming the channel it is for: the prefix decides how the body is read, and it is what the channel is checked against, both on a status rule and on a message sent by hand.

TEMPLATE reaches every template. SERVICE\_CONFIG reaches the templates of a service template type only — a type the platform's own catalog on the `/metadata/templates` endpoint does not list, which is what templateOrigin SERVICE lists, the seven types the service module sends under fixed names and every other type the tenant has created alike — because a service message text is service configuration. The type in the request decides: a new type is a service template type, so a caller holding SERVICE\_CONFIG may register one. A caller holding SERVICE\_CONFIG and not TEMPLATE is refused with a 403 when the type is a platform type, and nothing is written. A tenant-wide ADMIN grant counts as every permission.

Required permissions: TEMPLATE, SERVICE\_CONFIG

```json
{"openapi":"3.0.2","info":{"title":"Flow Retail API version 2","version":"2.0.0"},"tags":[{"name":"Notifications","description":"Notifications"},{"name":"Templates","description":"Templates"}],"servers":[{"description":"Flow Retail Production","url":"https://api.flowretail.com/v2"},{"description":"Flow Retail Stage","url":"https://api.stage.flowretail.com/v2"}],"security":[{"authToken":[]},{"accessToken":[]},{"integrationToken":[]}],"components":{"securitySchemes":{"authToken":{"description":"Token received from the auth service","scheme":"bearer","type":"http"},"accessToken":{"description":"Access token recevied after user login with a deviceToken","scheme":"bearer","type":"http"},"integrationToken":{"scheme":"bearer","type":"http"}},"responses":{"TransactionTemplateResponse":{"description":"TransactionTemplateResponse","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionTemplateResponseSchema"}}}}},"schemas":{"TransactionTemplateResponseSchema":{"title":"TransactionTemplateResponseSchema","description":"A template the tenant has written for one type of message, in one language.\nA tenant holds at most one template per type and language. A template whose language is empty is the language-neutral one for its type, and it is what a template written before languages existed is. Only the platform's own types carry a language-neutral template: a service template type the tenant created always carries a language, and the tenant's own language is the floor version such a type must have.\nWhich text a message is composed from is resolved when it is sent: the template for the language the recipient prefers, otherwise the one for the tenant's own language, otherwise the language-neutral one. The fallback applies at every level, so a tenant that writes one text still reaches every recipient, and a tenant that writes a second only needs it for the recipients who read that language. For a service template type the chain ends at the tenant's own language, because no neutral version exists for it. A text of such a type whose body is empty or holds nothing but whitespace counts as not written, and the chain moves on past it as it does past a missing one.","type":"object","required":["type","name","template","subject","mimeType","templateUid","language","createdAt","createdBy","lastModifiedAt","lastModifiedBy"],"properties":{"type":{"type":"string"},"name":{"type":"string","description":"What the type is called, in words. A platform type carries the platform's name for it, in the signed-in user's language. A service template type the tenant created carries the name the tenant gave it, and its key when it has been given none. Every template of one type carries the same name."},"template":{"type":"string","description":"The template body, read the way the type's channel says: mimeType states which."},"subject":{"type":"string","description":"The template subject, used for emails"},"mimeType":{"$ref":"#/components/schemas/TemplateMimeType"},"templateUid":{"$ref":"#/components/schemas/OptionalUID"},"language":{"description":"The language this text is written in. An empty string on the language-neutral template for its type — the one a recipient falls back to when nothing is written in a language closer to them. Never empty on a service template type, which always carries a language.","type":"string"},"createdAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"},"lastModifiedAt":{"type":"string","format":"date-time"},"lastModifiedBy":{"type":"string"}}},"TemplateMimeType":{"title":"TemplateMimeType","enum":["HTML","TEXT"],"description":"How the template body is read when the message is composed."},"OptionalUID":{"title":"OptionalUID","type":"string","pattern":"^[A-Za-z0-9-_]*"},"TransactionTemplateRequestSchema":{"title":"TransactionTemplateRequestSchema","type":"object","description":"A new template: the text for one type of message, in one language.\nThe type and the language together identify what is being written, and neither can be changed afterwards — writing the same message in another language is another template. A tenant holds at most one template per type and language.\nThe variables in the body are validated against the variables the type offers; a template using a variable the type does not have is refused.","required":["type","template"],"properties":{"type":{"type":"string","description":"The type of message the text is for — one of the types listed on /metadata/templates, or a service template type of the tenant's own: writing a template whose type the catalog does not list registers that type for the tenant. A tenant-created type accepts every variable of the service catalog on save, and which ones the editor offers is templateTypes and ownTypeChannels on the service order template variables endpoint; a platform-defined type keeps the variable list the catalog gives it. A service template type must begin with SMS_ or EMAIL_, naming the channel the text is written for; a service type that names neither is refused with a 400. The prefix is compared exactly and in upper case, while the rest of the name is the tenant's own. It is what decides how the body is read, so a message that goes out on both channels is written twice, once under each type."},"template":{"type":"string","description":"The message body. For a service template type the channel its type names decides how it is read: an EMAIL_ type's body is HTML and the values written into it are HTML-escaped, so a customer name or a note carrying a character with meaning in HTML cannot break the message; an SMS_ type's body is plain text."},"subject":{"type":"string","description":"The subject line, for a type that goes out by e-mail. An EMAIL_ service template type demands one and its variables are validated against the type's catalog exactly as the body's are; an SMS_ service template type has no subject, and one sent for it is refused with a 400."},"name":{"type":"string","maxLength":100,"description":"What staff call a service template type the tenant created, shown in place of its key wherever the type is listed or picked. One name serves the whole type, whichever language a text is written in: a name sent with any of the type's templates names every one of them. Surrounding spaces are trimmed, and the length limit applies to the name as sent. Left out, the type keeps the name it has; a name that is empty once trimmed removes it, and the type is shown by its key again. Two types may carry the same name. Deleting one language of the type keeps the name while another remains; deleting the type's last template removes the name with it. Only a service template type the tenant created takes a name — a platform type is named by the platform, and a name sent for one, an empty one included, is refused with a 400."},"language":{"description":"The language the text is written in. Leave it out, or send an empty string, to write the language-neutral template for this type — the one every recipient falls back to when nothing is written closer to their own language. A service template type always carries a language: a write without one is refused for it.","type":"string"},"templateUid":{"$ref":"#/components/schemas/UID"}}},"UID":{"title":"UID","type":"string","pattern":"^[A-Za-z0-9-_]+"}},"requestBodies":{"TransactionTemplateRequest":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionTemplateRequestSchema"}}}}}},"paths":{"/tenants/{tenantUid}/templates":{"post":{"summary":"Create transaction template","tags":["Templates","Notifications"],"responses":{"201":{"$ref":"#/components/responses/TransactionTemplateResponse"}},"operationId":"create-tenant-template","description":"Create transaction template\n\nThe type and the language together identify the text being written, and a tenant holds at most one template per type and language. A service template type the tenant created may be given a name, which every language of the type shares and which is shown in place of its key. Leave the language out to write the language-neutral template for the type — the one a recipient falls back to when nothing is written in a language closer to them. That is the platform's own types only: a service template type always carries a language, a write without one is refused for it, and the tenant's own language is the floor version the type must have before a rule or a send may name it.\n\nThe variables used in the body are validated against the variables the type offers; a template using a variable the type does not have is refused. The variables available to service message templates are listed on the service order template variables endpoint. A text of a type a variable is required in — requiredIn on that endpoint — whose body does not use it is refused with a 400 and writes nothing: SMS_SERVICE_ORDER_UPDATED and EMAIL_SERVICE_ORDER_UPDATED must use .serviceNote, the message staff write. On a service template type, a body that is empty or holds nothing but whitespace is refused with a 400 and writes nothing, whichever language it is written in: a text with nothing in it is no text, and a message is never composed from one.\n\nService message templates are not limited to platform-defined types: creating a template with a new type registers that type for the tenant, so a tenant with many statuses can author as many distinct messages as their workflow needs. A tenant-created type accepts every variable of the service catalog on save, and which ones the editor offers is templateTypes and ownTypeChannels on the service order template variables endpoint; platform-defined types keep the variable lists the metadata catalog gives them. A service template type must begin with SMS_ or EMAIL_, naming the channel it is for: the prefix decides how the body is read, and it is what the channel is checked against, both on a status rule and on a message sent by hand.\n\nTEMPLATE reaches every template. SERVICE_CONFIG reaches the templates of a service template type only — a type the platform's own catalog on the `/metadata/templates` endpoint does not list, which is what templateOrigin SERVICE lists, the seven types the service module sends under fixed names and every other type the tenant has created alike — because a service message text is service configuration. The type in the request decides: a new type is a service template type, so a caller holding SERVICE_CONFIG may register one. A caller holding SERVICE_CONFIG and not TEMPLATE is refused with a 403 when the type is a platform type, and nothing is written. A tenant-wide ADMIN grant counts as every permission.\n\nRequired permissions: TEMPLATE, SERVICE_CONFIG","requestBody":{"$ref":"#/components/requestBodies/TransactionTemplateRequest"}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.flowretail.com/docs/developers/api-documentation/templates/create-transaction-template.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
