Customer.io Transactional API
Send transactional messages such as password resets, purchase receipts, and other important notifications triggered by user actions.
Send transactional messages such as password resets, purchase receipts, and other important notifications triggered by user actions.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/customer-io-transactional-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
openapi: 3.2.0
info:
version: 1.0.0
title: Customer.io App Transactional API
description: 'Our App API provides ways to trigger messages and retrieve information about people, campaigns, broadcasts, and more.
# Overview
The App API provides methods to send newsletters, transactional messages, and API-triggered broadcasts. You can create newsletters from scratch and update transactional messages and API-triggered broadcasts.
For transactional messages and API-triggered broadcasts, your payload acts as a message "trigger" and can contain `data` that you reference in your messages using liquid—`{{trigger.<data>}}`.
The other endpoints help you retrieve information about people, segments, campaigns, broadcasts, etc; it also lets you update campaign actions, messages, newsletter variants, etc. Aside from the [API-triggered broadcast](#triggerBroadcast) (1 per 10 seconds) and [Transactional](#sendEmail) (100 per second) endpoints, requests are limited to 10 per second.
# Use our Postman collection
We''ve generated a Postman collection to help you get started with our APIs.
If you fork this collection, you might want to disable the *Watch original collection* option. We automatically update our Postman collection whenever we release changes to our documentation, even if we don''t change our APIs—which happens daily! Rather than being flooded with Postman notifications, you can check out our [Release Notes](/release-notes/) for updates to our APIs.
**NOTE**: Postman endpoints default to our US APIs. If you''re in our European (EU) region, you''ll need to add `-eu` to the server variables (`track_api_url` and `app_api_url`).
[<img src="https://run.pstmn.io/button.svg" alt="Run In Postman" style="width: 128px; height: 32px;">](https://god.gw.postman.com/run-collection/23697545-2931c004-e63d-4cdc-bf4b-e685ba6da42d?action=collection%2Ffork&source=rip_markdown&collection-url=entityId%3D23697545-2931c004-e63d-4cdc-bf4b-e685ba6da42d%26entityType%3Dcollection%26workspaceId%3Db886877f-fc09-475f-84fe-6221a98f4d18#?env%5BCustomer.io%20API%20Environment%5D=W3sia2V5IjoidHJhY2tfYXBpX3VybCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiJ0cmFjay5jdXN0b21lci5pbyIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiYXBwX2FwaV91cmwiLCJ0eXBlIjoiZGVmYXVsdCIsInZhbHVlIjoiYXBpLmN1c3RvbWVyLmlvIiwiZW5hYmxlZCI6dHJ1ZX0seyJrZXkiOiJzaXRlX2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiYXBpX2tleSIsInR5cGUiOiJzZWNyZXQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiYmVhcmVyIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiYnJvYWRjYXN0X2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiaW1wb3J0X2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiZW1haWxfYWRkcmVzcyIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6InN1cHByZXNzaW9uX3R5cGUiLCJ0eXBlIjoiZGVmYXVsdCIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZX0seyJrZXkiOiJjb2xsZWN0aW9uX2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5Ijoic25pcHBldF9uYW1lIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5Ijoid2ViaG9va19pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6InNlbmRlcl9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImV4cG9ydF9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6Im1lc3NhZ2VfaWQiLCJ0eXBlIjoiZGVmYXVsdCIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZX0seyJrZXkiOiJzZWdtZW50X2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoibmV3c2xldHRlcl9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImNvbnRlbnRfaWQiLCJ0eXBlIjoiZGVmYXVsdCIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZX0seyJrZXkiOiJjYW1wYWlnbl9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImFjdGlvbl9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImN1c3RvbWVyX2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoidHJhbnNhY3Rpb25hbF9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6InRyaWdnZXJfaWQiLCJ0eXBlIjoiZGVmYXVsdCIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZX0seyJrZXkiOiJmb3JtX2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9LHsia2V5IjoiaWRlbnRpZmllciIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImRldmljZV9pZCIsInR5cGUiOiJkZWZhdWx0IiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlfSx7ImtleSI6ImRlbGl2ZXJ5X2lkIiwidHlwZSI6ImRlZmF1bHQiLCJ2YWx1ZSI6IiIsImVuYWJsZWQiOnRydWV9XQ==)
# Server addresses: US and EU
Customer.io hosts services in the United States (US) and European Union. Select the appropriate server address for your region.
| Region | Server Address |
| :-- | :-- |
| US | https://api.customer.io |
| EU | https://api-eu.customer.io |
# Authentication
All requests to the Customer.io App API use an [App API Key](#App-API-Key).
To authenticate, provide your key as a Bearer token in a HTTP Authorization header. You can create and manage your API keys—including keys with different scopes—in [your account settings page](https://fly.customer.io/settings/api_credentials?keyType=app). Each operation on this page references the authorization header it requires.
# Rate Limits
Most endpoints on this page are limited to 10 requests per second. The exceptions are:
* The [transactional email](#operation/sendEmail) endpoint is limited to 100 requests per second.
* The [API-triggered broadcast endpoint](#operation/triggerBroadcast) is limited to 1 request every 10 seconds.
**Rate limits are subject to change. We may adjust these thresholds to ensure stable performance for all customers.**
'
servers:
- url: https://api.customer.io
description: The base URL for broadcasts, transactional messages, and data-retrieval APIs. These endpoints use bearer authorization, and require a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
- url: https://api-eu.customer.io
description: The base URL for broadcasts, transactional messages, and data-retrieval APIs (EU region). These endpoints use bearer authorization, and require a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
tags:
- name: Transactional
x-displayName: Transactional Messages
description: 'Send, and return information about, transactional messages. Transactional messages are messages that your audience explicitly requests or expects, like purchase receipts or password reset requests.
The `transactional_id` in requests represents the transactional message template. Each individual send—the instance of a message sent to an individual person—is called a "delivery".
'
paths:
/v1/transactional:
servers:
- url: https://api.customer.io
description: This API uses bearer authorization, requiring a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
get:
summary: List transactional messages
operationId: listTransactional
security:
- Bearer-Auth: []
description: Returns a list of your transactional messages—the transactional IDs that you use to trigger an individual transactional delivery. This endpoint does not return information about deliveries (instances of a message sent to a person) themselves.
tags:
- Transactional
responses:
'200':
description: Returns an array of transactional messages.
content:
application/json:
schema:
type: object
properties:
messages:
type: array
items:
x-scalar-ignore: true
description: Contains information about a transactional message.
type: object
properties:
id:
type: integer
description: The identifier Customer.io assigned to the transactional message
example: 2
name:
type: string
description: The name you set for the transactional message.
example: password reset
description:
type: string
description: A description of the transactional message.
example: sends a temporary password and lets the customer reset their password.
send_to_unsubscribed:
type: boolean
description: If true, people with an `unsubscribed` attribute set to `true` can trigger the message.
link_tracking:
type: boolean
description: If true, link tracking is enabled for this message.
open_tracking:
type: boolean
description: If true, open-tracking is enabled for this message.
hide_message_body:
type: boolean
description: If true, message contents are not retained in delivery history—you cannot recall the exact contents of the message.
queue_drafts:
type: boolean
description: If true, messages do not send automatically, and queue as drafts instead. You must send drafts through the *Deliveries & Drafts* page in the user interface.
created_at:
x-scalar-ignore: true
type: integer
format: unix timestamp
description: The date time when the referenced ID was created.
example: 1552341937
readOnly: true
updated_at:
x-scalar-ignore: true
type: integer
format: unix timestamp
description: The date time when the referenced ID was last updated.
example: 1552341937
readOnly: true
'429':
description: Your request is over the 10-per-second limit.
x-codeSamples:
- lang: Shell + Curl
source: "curl --request GET \\\n --header 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n --url https://api.customer.io/v1/transactional"
- lang: Node + Native
source: "const http = require(\"https\");\n\nconst options = {\n \"method\": \"GET\",\n \"hostname\": \"api.customer.io\",\n \"port\": null,\n \"path\": \"/v1/transactional\",\n \"headers\": {}\n};\n\nconst req = http.request(options, function (res) {\n const chunks = [];\n\n res.on(\"data\", function (chunk) {\n chunks.push(chunk);\n });\n\n res.on(\"end\", function () {\n const body = Buffer.concat(chunks);\n console.log(body.toString());\n });\n});\n\nreq.end();"
- lang: Ruby + Native
source: 'require ''uri''
require ''net/http''
require ''openssl''
url = URI("https://api.customer.io/v1/transactional")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body'
- lang: Python + Python3
source: 'import http.client
conn = http.client.HTTPSConnection("api.customer.io")
conn.request("GET", "/v1/transactional")
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))'
- lang: Go + Native
source: "package main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\n\turl := \"https://api.customer.io/v1/transactional\"\n\n\treq, _ := http.NewRequest(\"GET\", url, nil)\n\n\tres, _ := http.DefaultClient.Do(req)\n\n\tdefer res.Body.Close()\n\tbody, _ := ioutil.ReadAll(res.Body)\n\n\tfmt.Println(res)\n\tfmt.Println(string(body))\n\n}"
/v1/transactional/{transactional_id}:
servers:
- url: https://api.customer.io
description: This API uses bearer authorization, requiring a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
parameters:
- name: transactional_id
description: The identifier of your transactional message. You'll find this in the UI or URL of your transactional message. For example, if this is the path of a transactional message URL - `/transactional/3/templates/139` - the `transactional_id` is 3.
in: path
required: true
schema:
type: integer
get:
operationId: getTransactional
summary: Get a transactional message
security:
- Bearer-Auth: []
description: Returns information about an individual transactional message.
tags:
- Transactional
responses:
'200':
description: Returns metadata for the transactional message ID in the path.
content:
application/json:
schema:
type: object
properties:
message:
x-scalar-ignore: true
description: Contains information about a transactional message.
type: object
properties:
id:
type: integer
description: The identifier Customer.io assigned to the transactional message
example: 2
name:
type: string
description: The name you set for the transactional message.
example: password reset
description:
type: string
description: A description of the transactional message.
example: sends a temporary password and lets the customer reset their password.
send_to_unsubscribed:
type: boolean
description: If true, people with an `unsubscribed` attribute set to `true` can trigger the message.
link_tracking:
type: boolean
description: If true, link tracking is enabled for this message.
open_tracking:
type: boolean
description: If true, open-tracking is enabled for this message.
hide_message_body:
type: boolean
description: If true, message contents are not retained in delivery history—you cannot recall the exact contents of the message.
queue_drafts:
type: boolean
description: If true, messages do not send automatically, and queue as drafts instead. You must send drafts through the *Deliveries & Drafts* page in the user interface.
created_at:
x-scalar-ignore: true
type: integer
format: unix timestamp
description: The date time when the referenced ID was created.
example: 1552341937
readOnly: true
updated_at:
x-scalar-ignore: true
type: integer
format: unix timestamp
description: The date time when the referenced ID was last updated.
example: 1552341937
readOnly: true
'404':
description: The transactional message does not exist.
'429':
description: Your request is over the 10-per-second limit.
x-codeSamples:
- lang: Shell + Curl
source: "curl --request GET \\\n --header 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n --url https://api.customer.io/v1/transactional/{transactional_id}"
- lang: Node + Native
source: "const http = require(\"https\");\n\nconst options = {\n \"method\": \"GET\",\n \"hostname\": \"api.customer.io\",\n \"port\": null,\n \"path\": \"/v1/transactional/%7Btransactional_id%7D\",\n \"headers\": {}\n};\n\nconst req = http.request(options, function (res) {\n const chunks = [];\n\n res.on(\"data\", function (chunk) {\n chunks.push(chunk);\n });\n\n res.on(\"end\", function () {\n const body = Buffer.concat(chunks);\n console.log(body.toString());\n });\n});\n\nreq.end();"
- lang: Ruby + Native
source: 'require ''uri''
require ''net/http''
require ''openssl''
url = URI("https://api.customer.io/v1/transactional/%7Btransactional_id%7D")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body'
- lang: Python + Python3
source: 'import http.client
conn = http.client.HTTPSConnection("api.customer.io")
conn.request("GET", "/v1/transactional/%7Btransactional_id%7D")
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))'
- lang: Go + Native
source: "package main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\n\turl := \"https://api.customer.io/v1/transactional/%7Btransactional_id%7D\"\n\n\treq, _ := http.NewRequest(\"GET\", url, nil)\n\n\tres, _ := http.DefaultClient.Do(req)\n\n\tdefer res.Body.Close()\n\tbody, _ := ioutil.ReadAll(res.Body)\n\n\tfmt.Println(res)\n\tfmt.Println(string(body))\n\n}"
/v1/transactional/{transactional_id}/contents:
servers:
- url: https://api.customer.io
description: This API uses bearer authorization, requiring a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
parameters:
- name: transactional_id
description: The identifier of your transactional message. You'll find this in the UI or URL of your transactional message. For example, if this is the path of a transactional message URL - `/transactional/3/templates/139` - the `transactional_id` is 3.
in: path
required: true
schema:
type: integer
get:
operationId: listTransactionalVariants
summary: List all variants of a transactional message
security:
- Bearer-Auth: []
description: Returns the content variants of a transactional message, where each variant represents a different language.
tags:
- Transactional
responses:
'200':
description: Returns each variant of the transactional message.
content:
application/json:
schema:
type: object
properties:
contents:
type: array
description: Each object represents one of the variants.
items:
x-scalar-ignore: true
allOf:
- x-scalar-ignore: true
type: object
properties:
id:
x-scalar-ignore: true
description: The identifier for an action.
type: integer
readOnly: true
example: 96
name:
type: string
description: The name of the transactional message.
readOnly: true
example: Receipt
created:
x-scalar-ignore: true
type: integer
format: unix timestamp
description: The date time when the referenced ID was created.
example: 1552341937
readOnly: true
updated:
x-scalar-ignore: true
type: integer
format: unix timestamp
description: The date time when the referenced ID was last updated.
example: 1552341937
readOnly: true
body:
type: string
description: The body of the transactional message. You cannot modify the body if you created it with our drag-and-drop editor.
language:
x-scalar-ignore: true
type: string
description: The language variant for your message. If you don't use our [localization feature](/journeys/channels/localization/getting-started), or this is the default message, this value is an empty string.
example: fr
readOnly: true
type:
type: string
description: The type of message.
enum:
- email
- push
readOnly: true
from:
x-scalar-ignore: true
type: string
description: The address that the message is from, relevant if the action `type` is `email`.
readOnly: true
example: sentFrom@example.com
from_id:
x-scalar-ignore: true
type: integer
description: The identifier of the `from` address, commonly known as the "sender". Use [List sender identities](#tag/sender-identities/listSenders) to find valid IDs.
example: 1
reply_to:
x-scalar-ignore: true
type: string
description: The address that receives replies for the message, if applicable.
readOnly: true
example: replyto@example.com
reply_to_id:
x-scalar-ignore: true
type:
- integer
- 'null'
description: The identifier for the `reply_to` address, if applicable. Use [List sender identities](#tag/sender-identities/listSenders) to find valid IDs.
example: 38
preprocessor:
x-scalar-ignore: true
type: string
description: If CSS pre-processing is enabled, this key is populated with `premailer`. Note, Juice replaced Premailer as the pre-processor, but you will only see `premailer` as the value.
enum:
- premailer
readOnly: true
recipient:
x-scalar-ignore: true
description: The recipient address for an action.
type: string
example: '{{customer.email}}'
subject:
x-scalar-ignore: true
type: string
description: The subject line for an `email` action.
example: Did you get that thing I sent you?
cc:
x-scalar-ignore: true
readOnly: true
description: The carbon-copy address(es) for this action.
type: string
bcc:
x-scalar-ignore: true
readOnly: true
description: The blind-copy address(es) for this action.
type: string
fake_bcc:
x-scalar-ignore: true
readOnly: true
type: boolean
description: 'If true, rather than sending true copies to BCC addresses, Customer.io sends a copy of the message with the subject line containing the recipient address(es).
'
preheader_text:
x-scalar-ignore: true
type: string
description: '[Also known as "preview text"](/journeys/channels/email/headers/custom-preheader-text/), this is the small block of text shown in an email inbox next to or underneath the subject line.
'
body_amp:
x-scalar-ignore: true
type: string
description: AMP-enabled content for your email. If a recipient's email client doesn't support AMP, they receive your `body` content instead. Make sure you're [set up to send AMP](/journeys/channels/email/layouts/amp-for-email/) first.
- type: object
properties:
headers:
x-scalar-ignore: true
description: A JSON string containing header objects with `name` and `value`. Names and values must be strings, with no non-ASCII characters or spaces. You can't overwrite reserved headers.
type: string
format: json
example: '[{"name":"X-Mailgun-Tag","value":"my-cool-tag"},{"name":"X-Custom-Header","value":"custom-value"}]'
'400':
description: The request was malformed.
content:
application/json:
schema:
type: object
properties:
meta:
type: object
description: Contains errors.
properties:
error:
type: string
description: Describes the error that caused your request to fail.
'404':
description: The `transactional_id` or `content_id` in your request do not exist.
x-codeSamples:
- lang: Shell + Curl
source: "curl --request GET \\\n --header 'Authorization: Bearer REPLACE_BEARER_TOKEN' \\\n --url https://api.customer.io/v1/transactional/{transactional_id}/contents"
- lang: Node + Native
source: "const http = require(\"https\");\n\nconst options = {\n \"method\": \"GET\",\n \"hostname\": \"api.customer.io\",\n \"port\": null,\n \"path\": \"/v1/transactional/%7Btransactional_id%7D/contents\",\n \"headers\": {}\n};\n\nconst req = http.request(options, function (res) {\n const chunks = [];\n\n res.on(\"data\", function (chunk) {\n chunks.push(chunk);\n });\n\n res.on(\"end\", function () {\n const body = Buffer.concat(chunks);\n console.log(body.toString());\n });\n});\n\nreq.end();"
- lang: Ruby + Native
source: 'require ''uri''
require ''net/http''
require ''openssl''
url = URI("https://api.customer.io/v1/transactional/%7Btransactional_id%7D/contents")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body'
- lang: Python + Python3
source: 'import http.client
conn = http.client.HTTPSConnection("api.customer.io")
conn.request("GET", "/v1/transactional/%7Btransactional_id%7D/contents")
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))'
- lang: Go + Native
source: "package main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\n\turl := \"https://api.customer.io/v1/transactional/%7Btransactional_id%7D/contents\"\n\n\treq, _ := http.NewRequest(\"GET\", url, nil)\n\n\tres, _ := http.DefaultClient.Do(req)\n\n\tdefer res.Body.Close()\n\tbody, _ := ioutil.ReadAll(res.Body)\n\n\tfmt.Println(res)\n\tfmt.Println(string(body))\n\n}"
/v1/transactional/{transactional_id}/content/{content_id}:
servers:
- url: https://api.customer.io
description: This API uses bearer authorization, requiring a [token that you generate in the UI](https://fly.customer.io/settings/api_credentials?keyType=app).
parameters:
- name: transactional_id
description: The identifier of your transactional message. You'll find this in the UI or URL of your transactional message. For example, if this is the path of a transactional message URL - `/transactional/3/templates/139` - the `transactional_id` is 3.
in: path
required: true
schema:
type: integer
- name: content_id
description: The content variant of your transactional message. You'll find the id in the URL of your transactional message. For example, if this is the path of a transactional message URL - `/transactional/3/templates/139` - the `content_id` is 139.
in: path
required: true
schema:
type: integer
put:
operationId: updateTransactional
summary: Update a transactional message
security:
- Bearer-Auth: []
description: "Update the body of a transactional email. This fully overwrites your existing transactional message. We'll use your updated content for any future transactional requests (`/v1/send/email`), so make sure that you test your message before you update it. \n\n**NOTE**: You cannot manage content made with Design Studio with this endpoint. Use the [Design Studio APIs](#tag/design-studio) instead.\n"
tags:
- Transactional
requestBody:
content:
application/json:
schema:
x-scalar-ignore: true
allOf:
- x-scalar-ignore: true
type: object
properties:
id:
x-scalar-ignore: true
description: The identifier for an action.
type: integer
readOnly: true
example: 96
name:
type: string
description: The name of the transactional message.
readOnly: true
example: Receipt
created:
x-scalar-ignore: true
type: integer
format: unix timestamp
description: The date time when the referenced ID was created.
example: 1552341937
readOnly: true
updated:
x-scalar-ignore: true
type: integer
format: unix timestamp
description: The date time when the referenced ID was last updated.
example: 1552341937
readOnly: true
body:
type: string
description: The body of the transactional message. You cannot modify the body if you created it with our drag-and-drop editor.
language:
x-scalar-ignore: true
type: string
description: The language variant for your message. If you don't use our [localization feature](/journeys/channels/localization/getting-started), or this is the default message, this value is an empty
# --- truncated at 32 KB (119 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/customer-io/refs/heads/main/openapi/customer-io-transactional-api-openapi.yml