openapi: 3.2.0 info: version: 1.0.0 title: Customer.io App Design Studio 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.}}`. 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`). [Run In Postman](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: Design Studio description: 'Use these endpoints to manage emails, translations, and components made with Design Studio. You can programmatically manage Design Studio content and migrate templates from an external service. To manage assets like images, use the [Assets API](/integrations/api/app/#tag/assets). These endpoints do not enable you to publish changes to connected workflows like campaigns, nor can you update global styles. They''re only for content management at this time. Learn more about the [best practices](/integrations/api/integrate-with-ds/) for sending HTML through these endpoints. If you''re an external tool and interested in being listed as one of our integrated partners, please reach out to [product@customer.io](mailto:product@customer.io) to chat with a Product Manager! ' paths: /v1/design_studio/folders: get: tags: - Design Studio summary: List folders operationId: listFolders description: 'Returns a paginated list of folders. This does not include files like emails, components, etc. ' parameters: - name: page in: query description: The page number of results you want to display. Use with `limit`. schema: type: integer minimum: 1 default: 1 - name: limit in: query description: Limit the number of results per page. schema: type: integer minimum: 1 maximum: 10000 default: 1000 - name: parent_folder_id in: query schema: type: string format: uuid description: 'Filter by parent folder. Must reference an existing folder. If not set, the response filters by the root level directory. To list only items in the root folder, leave `parent_folder_id` unset and only set `direct_descendants_only` to `true`. ' - name: direct_descendants_only in: query description: If true, this returns only children of the parent folder. schema: type: boolean default: false - name: sort_by in: query schema: type: string enum: - created - updated - name default: created - name: sort_order in: query schema: type: string enum: - asc - desc default: asc - name: created_before in: query schema: type: integer format: Unix timestamp description: Return records created before this time. Must be a unix timestamp. example: 1773856017 - name: created_after in: query schema: type: integer format: Unix timestamp description: Return records created after this time. Must be a unix timestamp. example: 1773856017 - name: updated_before in: query schema: type: integer format: Unix timestamp description: Return records updated before this time. Must be a unix timestamp. example: 1773856017 - name: updated_after in: query schema: type: integer format: Unix timestamp description: Return records updated after this time. Must be a unix timestamp. example: 1773856017 responses: '200': description: Successful response content: application/json: schema: type: object properties: folders: type: array items: type: object properties: id: type: string format: uuid description: ID of folder name: type: string description: The name of the folder. parent_folder_id: type: - string - 'null' format: uuid description: The ID of the parent folder. Returns `null` if there is no parent, which means the folder is in the root directory. created: type: integer format: Unix timestamp description: Timestamp of when the folder was created. updated: type: integer format: Unix timestamp description: Timestamp of last update to the folder. example: id: 123e4567-e89b-12d3-a456-426614174000 name: Product Announcements parent_folder_id: null created: 1714732800 updated: 1714732800 meta: type: object properties: pagination: type: object properties: page: type: integer description: The page number of results you're on. limit: type: integer description: The number of results per page. total: type: integer description: The total number of folders. filters: type: object description: The filters applied in your request. example: parent_folder_id: 123e4567-e89b-12d3-a456-426614174000 direct_descendants_only: true sort_by: created sort_order: desc created_before: 1714732800 created_after: null updated_before: null updated_after: null '400': description: Bad request content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: invalid query parameter status: 400 '401': description: Unauthorized - missing or invalid API key content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: unauthorized status: 401 '404': description: Resource not found content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: resource not found status: 404 x-codeSamples: - lang: Shell + Curl source: "curl --request GET \\\n --url 'https://api.customer.io/v1/design_studio/folders?page=SOME_INTEGER_VALUE&limit=SOME_INTEGER_VALUE&parent_folder_id=SOME_STRING_VALUE&direct_descendants_only=SOME_BOOLEAN_VALUE&sort_by=SOME_STRING_VALUE&sort_order=SOME_STRING_VALUE&created_before=SOME_INTEGER_VALUE&created_after=SOME_INTEGER_VALUE&updated_before=SOME_INTEGER_VALUE&updated_after=SOME_INTEGER_VALUE'" - 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/design_studio/folders?page=SOME_INTEGER_VALUE&limit=SOME_INTEGER_VALUE&parent_folder_id=SOME_STRING_VALUE&direct_descendants_only=SOME_BOOLEAN_VALUE&sort_by=SOME_STRING_VALUE&sort_order=SOME_STRING_VALUE&created_before=SOME_INTEGER_VALUE&created_after=SOME_INTEGER_VALUE&updated_before=SOME_INTEGER_VALUE&updated_after=SOME_INTEGER_VALUE\",\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/design_studio/folders?page=SOME_INTEGER_VALUE&limit=SOME_INTEGER_VALUE&parent_folder_id=SOME_STRING_VALUE&direct_descendants_only=SOME_BOOLEAN_VALUE&sort_by=SOME_STRING_VALUE&sort_order=SOME_STRING_VALUE&created_before=SOME_INTEGER_VALUE&created_after=SOME_INTEGER_VALUE&updated_before=SOME_INTEGER_VALUE&updated_after=SOME_INTEGER_VALUE") 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/design_studio/folders?page=SOME_INTEGER_VALUE&limit=SOME_INTEGER_VALUE&parent_folder_id=SOME_STRING_VALUE&direct_descendants_only=SOME_BOOLEAN_VALUE&sort_by=SOME_STRING_VALUE&sort_order=SOME_STRING_VALUE&created_before=SOME_INTEGER_VALUE&created_after=SOME_INTEGER_VALUE&updated_before=SOME_INTEGER_VALUE&updated_after=SOME_INTEGER_VALUE") 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/design_studio/folders?page=SOME_INTEGER_VALUE&limit=SOME_INTEGER_VALUE&parent_folder_id=SOME_STRING_VALUE&direct_descendants_only=SOME_BOOLEAN_VALUE&sort_by=SOME_STRING_VALUE&sort_order=SOME_STRING_VALUE&created_before=SOME_INTEGER_VALUE&created_after=SOME_INTEGER_VALUE&updated_before=SOME_INTEGER_VALUE&updated_after=SOME_INTEGER_VALUE\"\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}" post: tags: - Design Studio summary: Create a folder description: 'Create a new folder at the root level or under a parent folder. To create a child folder, you need the UUID of the parent folder, which you can retrieve with [List folders](#tag/design-studio/listFolders). ' operationId: createFolder requestBody: required: true content: application/json: schema: type: object required: - name properties: name: type: string description: 'The name of the folder. Cannot contain these characters: < > : " / \ | ? * . ' minLength: 1 maxLength: 170 example: Product Announcements parent_folder_id: type: - string - 'null' description: UUID of the parent folder. Omit or pass `null` to create at root. format: uuid responses: '200': description: Folder created content: application/json: schema: type: object properties: folder: type: object properties: id: type: string format: uuid description: ID of folder name: type: string description: The name of the folder. parent_folder_id: type: - string - 'null' format: uuid description: The ID of the parent folder. Returns `null` if there is no parent, which means the folder is in the root directory. created: type: integer format: Unix timestamp description: Timestamp of when the folder was created. updated: type: integer format: Unix timestamp description: Timestamp of last update to the folder. example: id: 123e4567-e89b-12d3-a456-426614174000 name: Product Announcements parent_folder_id: null created: 1714732800 updated: 1714732800 '400': description: Bad request content: application/json: schema: type: object properties: errors: type: array items: type: object properties: detail: description: The name is missing or invalid, the parent folder id is an empty string, or there's an unknown JSON field in the request body type: string status: description: Response code type: integer example: errors: - detail: missing or invalid name status: 400 '401': description: Unauthorized - missing or invalid API key content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: unauthorized status: 401 '404': description: Response not found content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: parent folder not found status: 404 x-codeSamples: - lang: json label: JSON source: "{\n \"name\": \"Product Announcements\"\n}" - lang: Shell + Curl source: "curl --request POST \\\n --url https://api.customer.io/v1/design_studio/folders \\\n --header 'content-type: application/json' \\\n --data '{\"name\":\"Product Announcements\",\"parent_folder_id\":\"26caaf35-00f1-4c8f-a2ac-cb04b9b9a6ec\"}'" - lang: Node + Native source: "const http = require(\"https\");\n\nconst options = {\n \"method\": \"POST\",\n \"hostname\": \"api.customer.io\",\n \"port\": null,\n \"path\": \"/v1/design_studio/folders\",\n \"headers\": {\n \"content-type\": \"application/json\"\n }\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.write(JSON.stringify({\n name: 'Product Announcements',\n parent_folder_id: '26caaf35-00f1-4c8f-a2ac-cb04b9b9a6ec'\n}));\nreq.end();" - lang: Ruby + Native source: 'require ''uri'' require ''net/http'' require ''openssl'' url = URI("https://api.customer.io/v1/design_studio/folders") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE request = Net::HTTP::Post.new(url) request["content-type"] = ''application/json'' request.body = "{\"name\":\"Product Announcements\",\"parent_folder_id\":\"26caaf35-00f1-4c8f-a2ac-cb04b9b9a6ec\"}" response = http.request(request) puts response.read_body' - lang: Python + Python3 source: 'import http.client conn = http.client.HTTPSConnection("api.customer.io") payload = "{\"name\":\"Product Announcements\",\"parent_folder_id\":\"26caaf35-00f1-4c8f-a2ac-cb04b9b9a6ec\"}" headers = { ''content-type'': "application/json" } conn.request("POST", "/v1/design_studio/folders", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8"))' - lang: Go + Native source: "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\n\turl := \"https://api.customer.io/v1/design_studio/folders\"\n\n\tpayload := strings.NewReader(\"{\\\"name\\\":\\\"Product Announcements\\\",\\\"parent_folder_id\\\":\\\"26caaf35-00f1-4c8f-a2ac-cb04b9b9a6ec\\\"}\")\n\n\treq, _ := http.NewRequest(\"POST\", url, payload)\n\n\treq.Header.Add(\"content-type\", \"application/json\")\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/design_studio/folders/{id}: get: tags: - Design Studio summary: Get a folder description: 'Get a folder by its UUID. You can retrieve the UUID of folders through [List folders](#tag/design-studio/listFolders). ' operationId: getFolder parameters: - name: id in: path required: true description: The UUID of the folder. schema: type: string format: uuid responses: '200': description: Successful response content: application/json: schema: type: object properties: folder: type: object properties: id: type: string format: uuid description: ID of folder name: type: string description: The name of the folder. parent_folder_id: type: - string - 'null' format: uuid description: The ID of the parent folder. Returns `null` if there is no parent, which means the folder is in the root directory. created: type: integer format: Unix timestamp description: Timestamp of when the folder was created. updated: type: integer format: Unix timestamp description: Timestamp of last update to the folder. example: id: 123e4567-e89b-12d3-a456-426614174000 name: Product Announcements parent_folder_id: null created: 1714732800 updated: 1714732800 '401': description: Unauthorized - missing or invalid API key content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: unauthorized status: 401 '404': description: Resource not found content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: resource not found status: 404 x-codeSamples: - lang: Shell + Curl source: "curl --request GET \\\n --url https://api.customer.io/v1/design_studio/folders/{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/design_studio/folders/%7Bid%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/design_studio/folders/%7Bid%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/design_studio/folders/%7Bid%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/design_studio/folders/%7Bid%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}" put: tags: - Design Studio summary: Update a folder description: 'Update part of a folder: the name and/or the folder it belongs to. If you move a folder, all files stay nested in the folder. ' operationId: updateFolder parameters: - name: id in: path required: true description: The UUID of the folder. schema: type: string format: uuid requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Name of the folder. Cannot contain any of these characters: < > : " / \ | ? * . ' minLength: 1 maxLength: 170 parent_folder_id: type: - string - 'null' format: uuid description: 'The UUID of the parent folder. Omit if you want no change to where the folder or file is located. Include `null` to move it to your root directory. Or add the UUID of another folder to move it there. ' responses: '204': description: Successful response, no content returned '400': description: Bad request content: application/json: schema: type: object properties: errors: type: array items: type: object properties: detail: description: 'Possible reasons for error: No fields provided, invalid name, parent_folder_id is an empty string or not a valid place to move the folder to, or unknown JSON field in request body ' type: string status: description: Response code type: integer example: errors: - detail: missing or invalid name status: 400 '401': description: Unauthorized - missing or invalid API key content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: unauthorized status: 401 '404': description: Resource not found content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: resource not found status: 404 x-codeSamples: - lang: json label: JSON source: '{}' - lang: Shell + Curl source: "curl --request PUT \\\n --url https://api.customer.io/v1/design_studio/folders/{id} \\\n --header 'content-type: application/json' \\\n --data '{\"name\":\"string\",\"parent_folder_id\":\"26caaf35-00f1-4c8f-a2ac-cb04b9b9a6ec\"}'" - lang: Node + Native source: "const http = require(\"https\");\n\nconst options = {\n \"method\": \"PUT\",\n \"hostname\": \"api.customer.io\",\n \"port\": null,\n \"path\": \"/v1/design_studio/folders/%7Bid%7D\",\n \"headers\": {\n \"content-type\": \"application/json\"\n }\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.write(JSON.stringify({name: 'string', parent_folder_id: '26caaf35-00f1-4c8f-a2ac-cb04b9b9a6ec'}));\nreq.end();" - lang: Ruby + Native source: 'require ''uri'' require ''net/http'' require ''openssl'' url = URI("https://api.customer.io/v1/design_studio/folders/%7Bid%7D") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE request = Net::HTTP::Put.new(url) request["content-type"] = ''application/json'' request.body = "{\"name\":\"string\",\"parent_folder_id\":\"26caaf35-00f1-4c8f-a2ac-cb04b9b9a6ec\"}" response = http.request(request) puts response.read_body' - lang: Python + Python3 source: 'import http.client conn = http.client.HTTPSConnection("api.customer.io") payload = "{\"name\":\"string\",\"parent_folder_id\":\"26caaf35-00f1-4c8f-a2ac-cb04b9b9a6ec\"}" headers = { ''content-type'': "application/json" } conn.request("PUT", "/v1/design_studio/folders/%7Bid%7D", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8"))' - lang: Go + Native source: "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\n\turl := \"https://api.customer.io/v1/design_studio/folders/%7Bid%7D\"\n\n\tpayload := strings.NewReader(\"{\\\"name\\\":\\\"string\\\",\\\"parent_folder_id\\\":\\\"26caaf35-00f1-4c8f-a2ac-cb04b9b9a6ec\\\"}\")\n\n\treq, _ := http.NewRequest(\"PUT\", url, payload)\n\n\treq.Header.Add(\"content-type\", \"application/json\")\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}" delete: tags: - Design Studio summary: Delete a folder description: 'Delete a folder **including subfolders and all file (components, templates, and emails)**. You cannot delete a folder with emails used in your workflows (campaigns, broadcasts, etc). However, you can delete a folder with components that are referenced in emails connected to workflows, so make sure deleting a folder with components won''t break your emails. ' operationId: deleteFolder parameters: - name: id in: path required: true description: The UUID of the folder. schema: type: string format: uuid responses: '204': description: Successful response, no content returned '401': description: Unauthorized - missing or invalid API key content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: unauthorized status: 401 '404': description: Resource not found content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: resource not found status: 404 '409': description: Conflict - linked resource or other constraint violation content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: a constraint violation prevents this operation status: 409 x-codeSamples: - lang: Shell + Curl source: "curl --request DELETE \\\n --url https://api.customer.io/v1/design_studio/folders/{id}" - lang: Node + Native source: "const http = require(\"https\");\n\nconst options = {\n \"method\": \"DELETE\",\n \"hostname\": \"api.customer.io\",\n \"port\": null,\n \"path\": \"/v1/design_studio/folders/%7Bid%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/design_studio/folders/%7Bid%7D") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE request = Net::HTTP::Delete.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("DELETE", "/v1/design_studio/folders/%7Bid%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/design_studio/folders/%7Bid%7D\"\n\n\treq, _ := http.NewRequest(\"DELETE\", 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/design_studio/emails: get: tags: - Design Studio summary: List emails description: 'Returns a paginated list of emails and a separate array of folders that the emails belong to. ' operationId: listEmails parameters: - name: page in: query description: The page number of results you want to display. Use with `limit`. schema: type: integer minimum: 1 default: 1 - name: limit in: query description: Limit the number of results per page. schema: type: integer minimum: 1 maximum: 10000 default: 1000 - name: parent_folder_id in: query schema: type: string format: uuid description: 'Filter by parent folder. Must reference an existing folder. If not set, the response filters by the root level directory. To list only items in the root folder, leave `parent_folder_id` unset and only set `direct_descendants_only` to `true`. ' - name: direct_descendants_only in: query description: If true, this returns only children of the parent folder. schema: type: boolean default: false - name: sort_by in: query schema: type: string enum: - created - updated - name default: created - name: sort_order in: query schema: type: string enum: - asc - desc default: asc - name: created_before in: query schema: type: integer format: Unix timestamp description: Return records created before this time. Must be a unix timestamp. example: 1773856017 - name: created_after in: query schema: type: integer format: Unix timestamp description: Return records created after this time. Must be a unix timestamp. example: 1773856017 - name: updated_before in: query schema: type: integer format: Unix timestamp description: Return records updated before this time. Must be a unix timestamp. example: 1773856017 - name: updated_after in: query schema: type: integer format: Unix timestamp description: Return records updated after this time. Must be a unix timestamp. example: 1773856017 - name: is_template description: Filter by whether the email is a template in: query schema: type: string enum: - 'true' - 'false' - any default: any - name: has_translations description: Filter by whether the email has translations in: query schema: type: string enum: - 'true' - 'false' - any default: any - name: is_linked description: Filter by whether the email is linked to a workflow (campaign, broadcast, etc). in: query schema: type: string enum: - 'true' - 'false' - any default: any responses: '200': description: Successful response content: application/json: schema: type: object properties: emails: type: array items: type: object properties: id: type: string format: uuid description: ID of email example: sdflkj345 name: type: string description: The name of the email is_template: type: boolean description: Whether the email is a template is_linked: type: boolean description: Whether the email is linked to a workflow (campaign, broadcast, etc) has_translations: type: boolean description: Whether the email has translations parent_folder_id: type: - string - 'null' format: uuid description: The ID of the parent folder. Returns `null` if there is no parent, which means the folder is in the root directory. example: 123e4567-e89b-12d3-a456-426614174000 created: type: integer format: Unix timestamp description: Timestamp of when the email was created. example: 1714732800 updated: type: integer format: Unix timestamp description: Timestamp of last update to the email. example: 1714732800 folders: type: array items: type: object properties: id: type: string format: uuid description: ID of folder name: type: string description: The name of the folder. parent_folder_id: type: - string - 'null' format: uuid description: The ID of the parent folder. Returns `null` if there is no parent, which means the folder is in the root directory. created: type: integer format: Unix timestamp description: Timestamp of when the folder was created. updated: type: integer format: Unix timestamp description: Timestamp of last update to the folder. example: id: 123e4567-e89b-12d3-a456-426614174000 name: Product Announcements parent_folder_id: null created: 1714732800 updated: 1714732800 meta: type: object properties: pagination: type: object properties: page: type: integer description: The page number of results you're on. limit: type: integer description: The number of results per page. total: type: integer description: The total number of folders. filters: type: object description: The filters applied in your request. example: parent_folder_id: 123e4567-e89b-12d3-a456-426614174000 direct_descendants_only: true sort_by: created sort_order: desc created_before: 1714732800 created_after: null updated_before: null updated_after: null '400': description: Bad request content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: invalid query parameter status: 400 '401': description: Unauthorized - missing or invalid API key content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: unauthorized status: 401 '404': description: Resource not found content: application/json: schema: 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: Reason for error status: type: integer description: Response code example: errors: - detail: resource not found status: 404 x-codeSamples: - lang: Shell + Curl source: "curl --request GET \\\n --url 'https://api.customer.io/v1/design_studio/emails?page=SOME_INTEGER_VALUE&limit=SOME_INTEGER_VALUE&parent_folder_id=SOME_STRING_VALUE&direct_descendants_only=SOME_BOOLEAN_VALUE&sort_by=SOME_STRING_VALUE&sort_order=SOME_STRING_VALUE&created_before=SOME_INTEGER_VALUE&created_after=SOME_INTEGER_VALUE&updated_before=SOME_INTEGER_VALUE&updated_after=SOME_INTEGER_VALUE&is_template=SOME_STRING_VALUE&has_translations=SOME_STRING_VALUE&is_linked=SOME_STRING_VALUE'" - 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/design_studio/emails?page=SOME_INTEGER_VALUE&limit=SOME_INTEGER_VALUE&parent_folder_id=SOME_STRING_VALUE&direct_descendants_only=SOME_BOOLEAN_VALUE&sort_by=SOME_STRING_VALUE&sort_order=SOME_STRING_VALUE&created_before=SOME_INTEGER_VALUE&created_after=SOME_INTEGER_VALUE&updated_before=SOME_INTEGER_VALUE&updated_after=SOME_INTEGER_VALUE&is_template=SOME_STRING_VALUE&has_translations=SOME_STRING_VALUE&is_linked=SOME_STRING_VALUE\",\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/design_studio/emails?page=SOME_INTEGER_VALUE&limit=SOME_INTEGER_VALUE&parent_folder_id=SOME_STRING_VALUE&direct_descendants_only=SOME_BOOLEAN_VALUE&sort_by=SOME_STRING_VALUE&sort_order=SOME_STRING_VALUE&created_before=SOME_INTEGER_VALUE&created_after=SOME_INTEGER_VALUE&updated_before=SOME_INTEGER_VALUE&updated_after=SOME_INTEGER_VALUE&is_template=SOME_STRING_VALUE&has_translations=SOME_STRING_VALUE&is_linked=SOME_STRING_VALUE") 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/design_studio/emails?page=SOME_INTEGER_VALUE&limit=SOME_INTEGER_VALUE&parent_folder_id=SOME_STRING_VALUE&direct_descendants_only=SOME_BOOLEAN_VALUE&sort_by=SOME_STRING_VALUE&sort_order=SOME_STRING_VALUE&created_before=SOME_INTEGER_VALUE&created_after=SOME_INTEGER_VALUE&updated_before=SOME_INTEGER_VALUE&updated_after=SOME_INTEGER_VALUE&is_template=SOME_STRING_VALUE&has_translations=SOME_STRING_VALUE&is_linked=SOME_STRING_VALUE") 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/design_studio/emails?page=SOME_INTEGER_VALUE&limit=SOME_INTEGER_VALUE&parent_folder_id=SOME_STRING_VALUE&direct_descendants_only=SOME_BOOLEAN_VALUE&sort_by=SOME_STRING_VALUE&sort_order=SOME_STRING_VALUE&created_before=SOME_INTEGER_VALUE&created_after=SOME_INTEGER_VALUE&updated_before=SOME_INTEGER_VALUE&updated_after=SOME_INTEGER_VALUE&is_template=SOME_STRING_VALUE&has_translations=SOME_STRING_VALUE&is_linked=SOME_STRING_VALUE\"\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}" post: tags: - Design Studio summary: Create an email description: Create an email. Note, you can create an email without filling out all required fields for sending. You can fill in the envelope, like a to and from address, with this method, but that's not required until you connect it to a workflow like a campaign. operationId: createEmail requestBody: required: true content: application/json: schema: type: object required: - name properties: name: type: string minLength: 1 maxLength: 255 description: Display name of the email. is_template: type: boolean default: false description: Whether the email is a reusable template. parent_folder_id: type: - string - 'null' format: uuid description: UUID of the parent folder. Omit or pass `null` to create at root. content: type: object description: The content of your email. properties: subject: type: string description: Email subject line. preheader_text: type: string description: Preview text. html: type: string description: HTML body. amp: type: string description: AMP HTML body. text: type: string description: Plain text body. envelope: type: object description: The envelope of your email, like from and to addresses. properties: from_id: type: - integer - 'null' description: 'Sender identity ID. Must reference an existing identity. You can find this in *Workspace Settings > Email* under your From Addresses. ' reply_to_id: type: - integer - 'null' format: int64 description: 'Reply-to identity ID. Must reference an existing identity from *Workspace Settings > Email* under your From Addresses. ' recipient: type: string description: 'Recipient email address. Defaults to `{{customer.email}}`` if not set. ' bcc: type: string description: BCC email address. fake_bcc: type: boolean description: Whether to use fake BCC. Defaults to true if not provided. headers: type: array items: type: object properties: name: type: string value: type: string description: 'Custom headers. Each item: { "name": "string", "value": "string" }. ' transformers: type: object description: Automate repetitive actions like removing white space and inlining CSS with [transformers](/journeys/design-studio/emails/code-editor/overview/#transformers). properties: url_parameters: type: object description: 'Appends query string parameters to all absolute URLs in `` and VML elements. Useful for adding UTM tracking or other analytics parameters. Skips `mailto:`, `tel:`, and `sms:` links. Elements marked with `data-ignore-params` are excluded. ' properties: enabled: type: boolean description: 'Enable URL parameter injection. ' default: false parameters: type: array description: 'List of parameters to append to URLs. ' default: [] items: type: object properties: key: type: string description: 'Parameter name. ' value: type: string description: 'Parameter value. May contain template variables. ' url_encode: type: boolean description: 'URL-encode the value before appending it to the URL. ' css_variables: type: object description: 'Resolves CSS custom properties (`var(--name)`) into their computed values. Required for email clients that do not support CSS custom properties (most email clients). Variables declared in one `