Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
version: 1.0.0
title: Customer.io Journeys API Reference Assets API
description: Customer.io provides REST APIs to send real-time customer data, retrieve data from your account, and trigger messages.
servers:
- url: https://track.customer.io
description: The base URL for the Track API. Track endpoints use basic authentication with your Site ID as the user name and your secret key as the password.
- url: https://track-eu.customer.io
description: The base URL for the Track API (EU region). Track endpoints use basic authentication with your Site ID as the user name and your secret key as the password.
- 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: Assets
description: Manage file assets such as images and PDFs and organize them into folders.
paths:
/v1/assets:
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).
get:
tags:
- Assets
summary: List file assets
description: Returns a paginated list of file assets. Supports filtering by parent folder and choosing between direct children or the entire folder subtree.
operationId: listAssets
parameters:
- $ref: '#/components/parameters/AssetParentFolderID'
- $ref: '#/components/parameters/DirectDescendantsOnly'
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/Limit'
responses:
'200':
description: A paginated list of file assets with metadata.
content:
application/json:
schema:
type: object
properties:
assets:
type: array
description: The list of file assets matching the query.
items:
$ref: '#/components/schemas/AssetFile'
meta:
$ref: '#/components/schemas/List-Meta'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/assets/files:
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).
post:
tags:
- Assets
summary: Create a file asset
description: 'Creates a new file asset.
Accepted file types: `image/bmp`, `image/jpeg`, `image/jpg`, `image/png`, `image/gif`, `application/pdf`. Maximum file size: 2 MB. Maximum image dimensions: 4096px.'
operationId: createAsset
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
required:
- file
properties:
file:
type: string
format: binary
description: 'The file to upload. Must be an accepted image or PDF type. Accepted file types: `image/bmp`, `image/jpeg`, `image/jpg`, `image/png`, `image/gif`, `application/pdf`. Maximum file size: 2 MB. Maximum image dimensions: 4096px.
'
name:
type: string
description: Custom display name for the asset. If omitted, the uploaded file's original filename is used.
parent_folder_id:
type:
- integer
- 'null'
description: The ID of the parent folder. Omit or set to "0" to place the asset at the root level.
responses:
'200':
description: The newly created file asset.
content:
application/json:
schema:
type: object
properties:
asset:
$ref: '#/components/schemas/AssetFile'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/AssetConflict'
/v1/assets/files/{id}:
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).
get:
tags:
- Assets
summary: Get a file asset
description: Retrieves a single file asset by its ID. Returns 404 if the asset does not exist or is a folder.
operationId: getAsset
parameters:
- $ref: '#/components/parameters/asset-id'
responses:
'200':
description: The requested file asset.
content:
application/json:
schema:
type: object
properties:
asset:
$ref: '#/components/schemas/AssetFile'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
tags:
- Assets
summary: Update a file asset
description: Updates the name and/or parent folder of a file asset. The file itself (path, size) cannot be changed. At least one of `name` or `parent_folder_id` must be provided.
operationId: updateAsset
parameters:
- $ref: '#/components/parameters/asset-id'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
minLength: 1
description: New display name for the asset. Cannot be blank after trimming.
parent_folder_id:
type:
- integer
- 'null'
description: The ID of the new parent folder. Set to `null` to move the asset to the root level.
responses:
'204':
description: File asset updated successfully.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/AssetConflict'
delete:
tags:
- Assets
summary: Delete a file asset
description: Soft-deletes a file asset by setting its `deleted_at` timestamp. The underlying file in cloud storage is not removed. Assets that are currently in use cannot be deleted.
operationId: deleteAsset
parameters:
- $ref: '#/components/parameters/asset-id'
responses:
'204':
description: File asset deleted successfully.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/v1/assets/folders:
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).
get:
tags:
- Assets
summary: List folders
description: Returns a paginated list of asset folders. Supports filtering by parent folder and choosing between direct children or the entire folder subtree.
operationId: listAssetFolders
parameters:
- $ref: '#/components/parameters/AssetParentFolderID'
- $ref: '#/components/parameters/DirectDescendantsOnly'
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/Limit'
responses:
'200':
description: A paginated list of folders with metadata.
content:
application/json:
schema:
type: object
properties:
folders:
type: array
description: The list of folders matching the query.
items:
$ref: '#/components/schemas/Folders'
meta:
$ref: '#/components/schemas/List-Meta'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
post:
tags:
- Assets
summary: Create a folder
description: Creates a new folder for organizing file assets. Folder names must be unique within the same parent folder.
operationId: createAssetFolder
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- name
properties:
name:
type: string
minLength: 1
description: Display name for the folder. Must be unique among siblings in the same parent folder.
example: Banners
parent_folder_id:
type:
- integer
- 'null'
description: The ID of the parent folder. Omit or set to "0" to create at the root level.
responses:
'200':
description: The newly created folder.
content:
application/json:
schema:
type: object
properties:
folder:
$ref: '#/components/schemas/Folders'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/AssetConflict'
/v1/assets/folders/{id}:
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).
get:
tags:
- Assets
summary: Get a folder
description: Retrieves a single folder by its ID.
operationId: getAssetFolder
parameters:
- $ref: '#/components/parameters/asset-id'
responses:
'200':
description: The requested folder.
content:
application/json:
schema:
type: object
properties:
folder:
$ref: '#/components/schemas/Folders'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
tags:
- Assets
summary: Update a folder
description: Updates the name and/or parent folder of an existing folder. At least one of `name` or `parent_folder_id` must be provided. Moving a folder into itself or one of its descendants is not allowed (cycle detection).
operationId: updateAssetFolder
parameters:
- $ref: '#/components/parameters/asset-id'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
minLength: 1
description: New display name for the folder. Cannot be blank after trimming.
parent_folder_id:
type:
- integer
- 'null'
description: The ID of the new parent folder. Set to `null` to move the folder to the root level. Cannot be the folder itself or one of its descendants.
responses:
'204':
description: Folder updated successfully.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/AssetConflict'
delete:
tags:
- Assets
summary: Delete a folder
description: Soft-deletes an empty folder. Folders that still contain files or subfolders cannot be deleted. Assets marked as in use also prevent deletion.
operationId: deleteAssetFolder
parameters:
- $ref: '#/components/parameters/asset-id'
responses:
'204':
description: Folder deleted successfully.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
components:
parameters:
Limit:
name: limit
in: query
description: The maximum number of results per page.
schema:
type: integer
minimum: 1
maximum: 10000
default: 1000
asset-id:
name: id
in: path
required: true
description: The unique identifier of the resource.
schema:
type: integer
minimum: 1
Page:
name: page
in: query
description: The page number of results you want to display. Use with `limit`.
schema:
type: integer
minimum: 1
default: 1
DirectDescendantsOnly:
name: direct_descendants_only
in: query
description: When `true`, the response includes only the immediate children of the parent folder. When `false`, it includes the parent folder's entire subtree.
schema:
type: boolean
default: false
AssetParentFolderID:
name: parent_folder_id
in: query
description: Filter results to a specific parent folder. Use 0 or omit to target the root level.
schema:
type: integer
schemas:
Folders:
type: object
properties:
id:
type: integer
description: The unique identifier of the folder.
name:
type: string
description: The display name of the folder.
example: Banners
parent_folder_id:
type:
- integer
- 'null'
description: The ID of the parent folder, or null if the folder is at the root level.
created:
type: integer
format: int64
description: Unix timestamp when the folder was created.
example: 1773856017
updated:
type: integer
format: int64
description: Unix timestamp when the folder was last updated.
example: 1773856017
Error:
type: object
description: An error response containing one or more error details.
properties:
errors:
type: array
description: A list of errors that occurred while processing the request.
items:
type: object
properties:
detail:
type: string
description: A human-readable description of the error.
status:
type: string
description: The HTTP status code for this error, as a string.
source:
type: object
description: The request field that caused the error. Validation errors (`422`) include it.
properties:
pointer:
type: string
description: The path to the field that failed, like `/data/attributes/content`.
meta:
type: object
description: Additional detail about the error, when there is any. A failed publish uses this to list Liquid errors per language.
List-Meta:
type: object
description: Metadata about the paginated response including pagination details and applied filters.
properties:
pagination:
type: object
description: Pagination details for the current result set.
properties:
page:
type: integer
description: The current page number.
limit:
type: integer
description: The maximum number of results per page.
total:
type: integer
description: The total number of matching results across all pages.
filters:
type: object
description: The filters that were applied to the query.
properties:
parent_folder_id:
type:
- integer
- 'null'
description: The parent folder ID filter that was applied, or null if not filtering by parent.
direct_descendants_only:
type: boolean
description: Whether the results were limited to direct descendants only.
AssetFile:
type: object
properties:
id:
type: integer
description: The unique identifier of the file asset.
name:
type: string
description: The display name of the file asset.
parent_folder_id:
type:
- integer
- 'null'
description: The ID of the parent folder, or null if the asset is at the root level.
path:
type: string
description: The storage URL or path where the file is hosted.
size:
type: integer
description: The file size in bytes.
created:
type: integer
format: int64
description: Unix timestamp when the asset was created.
example: 1773856017
updated:
type: integer
format: int64
description: Unix timestamp when the asset was last updated.
example: 1773856017
responses:
AssetConflict:
description: A conflict occurred, such as a duplicate name within the same parent folder.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
BadRequest:
description: The request is invalid due to malformed parameters, missing required fields, or constraint violations.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: The requested resource was not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
errors:
- detail: resource not found
status: '404'
Unauthorized:
description: Authentication failed due to a missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
errors:
- detail: unauthorized
status: '401'
securitySchemes:
Tracking-API-Key:
type: http
scheme: basic
description: 'The Track API uses a basic authentication scheme. Your credentials are your **Site ID** and your **API key**, **Base-64 encoded** in the format `site_id:api_key`.
You can find your Site ID and API key on the [Track API Keys page](https://fly.customer.io/settings/api_credentials).
'
Bearer-Auth:
type: http
scheme: bearer
description: 'The App API uses a bearer authentication scheme.
You can generate a bearer token, known as an **App API Key**, with a defined scope in [your account settings](https://fly.customer.io/settings/api_credentials?keyType=app). [Learn more about bearer authorization in Customer.io](/accounts/settings/managing-credentials).
'
ServiceAccount-Auth:
x-scalar-ignore: true
type: http
scheme: bearer
bearerFormat: sa_live_
description: 'Transactional send endpoints (`/v1/send/email`, `/v1/send/push`, `/v1/send/sms`, `/v1/send/whatsapp`, `/v1/send/in_app`, `/v1/send/inbox_message`) also accept a service-account bearer token, prefixed with `sa_live_`. Service-account tokens work across workspaces, so you must pass the target workspace as the `X-Workspace-Id` header on each request.
Service-account tokens are intended for testing and one-off sends—for example, using the Customer.io CLI with an AI agent like Claude to verify that a transactional message renders correctly before wiring it into your production backend. **For the production integration that triggers the message from your application, use an App API Key instead**: it''s workspace-scoped, easier to rotate, and has a smaller blast radius.
Service-account tokens are server-side credentials. Treat them like any API key—keep them in environment variables or a secret manager, and never embed them in client-side code, mobile apps, or other untrusted contexts.
'
bearerAuth:
type: http
scheme: bearer
description: API key passed as a Bearer token.
x-tagGroups:
- name: Track API v2
tags:
- track_v2
- Object Schemas
- Person Schemas
- Deliveries
- name: Track API
tags:
- trackOverview
- trackJsOrBackend
- trackLimit
- trackRegion
- Track Customers
- Track Events
- Forms
- Track Segments
- Track v1 Overview
- name: App API
tags:
- appOverview
- appLimit
- appAuth
- Activities
- Automations
- Broadcasts
- Collections
- Customers
- Data Index
- ESP Suppression
- Exports
- Imports
- Info
- Live Notifications
- Messages
- Newsletters
- Opt-outs
- Reporting Webhooks
- Segments
- Sender Identities
- Snippets
- Subscription Center
- Transactional
- Workspaces
- Send Messages
- Objects
- Newsletter Variants
- Newsletter Metrics
- Assets
- name: Design Studio API
tags:
- Folders
- Components
- Emails
- Email link and publish
- Email testing
- SMS
- SMS link and publish
x-provenance:
method: harvested
publisher: Customer.io
source: https://docs.customer.io/openapi.yaml
note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
stamped by stamp-openapi-provenance.py (roadmap#793)