---
openapi: 3.0.3
info:
  title: Braze REST API – Send Canvas messages using API-triggered delivery
  description: 'Use this endpoint to send Canvas messages with API-triggered delivery.

    '
  version: 1.0.0
  contact:
    name: Braze Support
    url: https://www.braze.com/docs/braze_support/
  license:
    name: Braze Documentation
    url: https://www.braze.com/docs/api/home/
servers:
  - url: https://rest.iad-01.braze.com
    description: US-01
  - url: https://rest.iad-02.braze.com
    description: US-02
  - url: https://rest.iad-03.braze.com
    description: US-03
  - url: https://rest.iad-04.braze.com
    description: US-04
  - url: https://rest.iad-05.braze.com
    description: US-05
  - url: https://rest.iad-06.braze.com
    description: US-06
  - url: https://rest.iad-07.braze.com
    description: US-07
  - url: https://rest.iad-08.braze.com
    description: US-08
  - url: https://rest.us-10.braze.com
    description: US-10
  - url: https://rest.fra-01.braze.eu
    description: EU-01
  - url: https://rest.fra-02.braze.eu
    description: EU-02
  - url: https://rest.au-01.braze.com
    description: AU-01
  - url: https://rest.id-01.braze.com
    description: ID-01
  - url: https://rest.jp-01.braze.com
    description: JP-01
  - url: https://rest.kr-01.braze.com
    description: KR-01
security:
- BearerAuth: []
paths:
  "/canvas/trigger/send":
    post:
      summary: Send Canvas messages using API-triggered delivery
      description: |
        ## Prerequisites

        To use this endpoint, you'll need to generate an API key with the `canvas.trigger.send` permission.

        ## Rate limit

        When you use connected audience filters in your request, this endpoint has a rate limit of 250 requests per minute. Otherwise, if you specify an `external_id`, this endpoint has a default rate limit of 250,000 requests per hour, shared between the endpoints documented in [API rate limits]({{site.baseurl}}/api/api_limits#requests-with-shared-rate-limits).

        This endpoint supports [batching API requests]({{site.baseurl}}/api/api_limits#batching-api-requests). One request can include any of the following:

        - Up to 50 `recipients` by default
        - A [connected audience]({{site.baseurl}}/api/objects_filters/connected_audience) of any size

        ## Request body

        The following headers and request body are required for this endpoint.

        ```
        Content-Type: application/json
        Authorization: Bearer YOUR_REST_API_KEY
        ```

        ```json
        {
          "canvas_id": (required, string) see Canvas identifier,
          "context": (optional, object) Canvas context properties that apply to all users in this request,
          "broadcast": (optional, boolean) see Broadcast -- defaults to false on 8/31/17, must be set to true if `recipients` is omitted,
          "audience": (optional, connected audience object) see connected audience,
          // Including 'audience' will only send to users in the audience
          "recipients": (optional, array; if not provided and broadcast is not set to 'false', message sends to the entire segment targeted by the Canvas)
            [{
              // Either "external_user_id" or "user_alias" or "email" is required. Requests must specify only one.
              "user_alias": (optional, user alias object) user alias of user to receive message,
              "external_user_id": (optional, string) external identifier of user to receive message,
              "email": (optional, string) email address of user to receive message,
              "prioritization": (optional, array) prioritization array; required when using email,
              "context": (optional, object) Canvas context properties for this user; key-value pairs override any keys that conflict with the parent `context`,
              "send_to_existing_only": (optional, boolean) defaults to true, can't be used with user aliases; if set to `false`, an `attributes` object must also be included,
              "attributes": (optional, object) fields in the attributes object create or update an attribute of that name with the given value on the specified user profile before the message is sent and existing values are overwritten
            }],
            ...
        }
        ```

        ## Request parameters

        The following table lists the request parameters for this endpoint.

        | Parameter | Required | Data Type | Description |
        | --------- | ---------| --------- | ----------- |
        |`canvas_id`| Required | String | See [Canvas identifier]({{site.baseurl}}/api/identifier_types/). |
        |`context`| Optional | Object | Canvas context properties for all recipients in this request. Personalization key-value pairs apply to every user unless a per-recipient `context` overrides a key. The `context` object can be up to 50 KB. <br><br>Every workspace also accepts `canvas_entry_properties` for these key-value pairs, at both the request level and the recipient level. If you're not sure whether your workspace supports `context`, use `canvas_entry_properties`. |
        |`broadcast`| Optional | Boolean | You must set `broadcast` to true when sending a message to the entire segment configured as the Canvas's target audience in the Braze dashboard. This parameter defaults to false (as of August 31, 2017). <br><br> If `broadcast` is set to true, a `recipients` list cannot be included. However, use caution when setting `broadcast: true`, as unintentionally setting this flag may cause you to send your message to a larger-than-expected audience. |
        |`audience`| Optional| Connected audience object | See [Connected audience]({{site.baseurl}}/api/objects_filters/connected_audience/). When you include `audience`, the message is sent only to users who match the defined filters, such as custom attributes and subscription statuses. |
        |`recipients`| Optional | Array | See [Recipients object]({{site.baseurl}}/api/objects_filters/recipient_object/). <br><br>If `send_to_existing_only` is `false`, an `attributes` object must be included on the recipient. <br><br>You can update a user's subscription group status by including `subscription_groups` in the nested `attributes` object. For more details, refer to [User attributes object]({{site.baseurl}}/api/objects_filters/user_attributes_object/).<br><br>If not provided and `broadcast` is set to `true`, the message is sent to the entire segment configured as the Canvas's target audience in the Braze dashboard.<br><br> The `recipients` array may contain up to 50 objects. Each object must include exactly one of `external_user_id`, `user_alias`, or `email`, and may include a per-recipient `context` object for Canvas context properties (per-recipient keys override the parent-level `context` when they conflict). <br><br>If `email` is the identifier, you must include [`prioritization`]({{site.baseurl}}/api/endpoints/user_data/post_user_identify#identifying-users-by-email-addresses-and-phone-numbers) in the recipients object. |

        ## Example request

        The following sample request shows an example of how to send a Canvas message using API-triggered delivery.

        ```
        curl --location --request POST 'https://rest.iad-01.braze.com/canvas/trigger/send' \
        --header 'Content-Type: application/json' \
        --header 'Authorization: Bearer YOUR_REST_API_KEY' \
        --data-raw '{
          "canvas_id": "canvas_identifier",
          "context": {"product_name" : "shoes", "product_price" : 79.99},
          "broadcast": false,
          "audience": {
            "AND": [
              {
                "custom_attribute": {
                  "custom_attribute_name": "eye_color",
                  "comparison": "equals",
                  "value": "blue"
                }
              },
              {
                "custom_attribute": {
                  "custom_attribute_name": "favorite_foods",
                  "comparison": "includes_value",
                  "value": "pizza"
                }
              },
              {
                "OR": [
                  {
                    "custom_attribute": {
                      "custom_attribute_name": "last_purchase_time",
                      "comparison": "less_than_x_days_ago",
                      "value": 2
                    }
                  },
                  {
                    "push_subscription_status": {
                      "comparison": "is",
                      "value": "opted_in"
                    }
                  }
                ]
              },
              {
                "email_subscription_status": {
                  "comparison": "is_not",
                  "value": "subscribed"
                }
              },
              {
                "last_used_app": {
                  "comparison": "after",
                  "value": "2019-07-22T13:17:55+0000"
                }
              }
            ]
          },
          "recipients": [
            {
              "user_alias": {
                "alias_name" : "example_name",
                "alias_label" : "example_label"
              },
              "external_user_id": "user_identifier",
              "send_to_existing_only": true,
              "attributes": {
                  "first_name" : "Alex"
              }
            }
          ]
        }'
        ```

        ## Response details

        Message-sending endpoint responses include the message's `dispatch_id` for reference back to the dispatch of the message. The `dispatch_id` is the ID of the message dispatch (unique ID for each "transmission" sent from the Braze platform). Check out [Dispatch ID behavior]({{site.baseurl}}/user_guide/messaging/messaging_fundamentals/dispatch_id/) for more information.

        ### Example success response

        The status code `201` could return the following response body. If the Canvas is archived, stopped, or paused, the Canvas is not sent through this endpoint.

        ```
        {
          "notice": "The Canvas is paused. Resume the Canvas to ensure trigger requests will take effect.",
          "dispatch_id": "example_dispatch_id",
          "message": "success"
        }
        ```

        If your Canvas is archived, you see this `notice` message: "The Canvas is archived. Unarchive the Canvas to ensure trigger requests will take effect." If your Canvas is not active, you see this `notice` message: "The Canvas is paused. Resume the Canvas to ensure trigger requests will take effect."

        If your request encounters a fatal error, refer to [Errors and responses]({{site.baseurl}}/api/errors/#fatal-errors) for the error code and description.

        ## Considerations

        Consider the following when making API calls to send Canvas messages using API-triggered delivery:

        - **Sending to existing users**: When `send_to_existing_only` is set to `true` (the default), the message is sent only to existing users in Braze.
        - **Creating new users**: When `send_to_existing_only` is set to `false`, you must include an `attributes` object. If a user with the specified ID does not exist, Braze creates a user with that ID and attributes before sending the message.
        - **Net-new profiles need `attributes` with `send_to_existing_only: false`.** Braze runs the pre-send create or update from the `attributes` object in the same recipient. If you set `send_to_existing_only` to `false` but omit `attributes` (or send an empty object), Braze does not hydrate profile data the same way, so you do not get the combined "create or update user, then send" behavior this pattern is meant for.
        - **Email and SMS addressing.** For most Email or SMS API-triggered sends to someone who is not already in Braze, include the delivery fields you need inside `attributes` (for example `email`, or the phone attributes your workspace uses for SMS). You can also set subscription group membership or subscription status there when opt-in state must change in the same call.
        - **Canvas eligibility.** After the profile exists or updates, that user must still match the Canvas's dashboard target audience and channel send rules (for example opted in for email) or Braze does not send the message.
        - **User alias limitation**: The `send_to_existing_only` flag cannot be used with user aliases. To send to an alias-only user, the user must already exist in Braze.
        - **Segment targeting**: The `segment_id` parameter is not supported for this endpoint. To target a segment, configure the segment in the Canvas's target audience settings in the Braze dashboard and use `broadcast: true`, or use the `audience` parameter with [Connected Audience]({{site.baseurl}}/api/objects_filters/connected_audience/) filters.
        - **Combined targeting**: When you include both the `recipients` parameter and configure a target segment in the dashboard, the message is sent only to user profiles that are specified in the API call and also match the segment's filters.
        - **Server-to-server calls**: If you're making server-to-server calls, you may need to allowlist the appropriate API URL if you're behind a firewall.

        ## Attributes object for Canvas

        Use the messaging object `attributes` to add, create, or update attributes and values for a user before sending them an API-triggered Canvas using the `canvas/trigger/send` endpoint. This API call processes the user attributes object before it processes and sends the Canvas. This helps minimize the risk of issues caused by [race conditions]({{site.baseurl}}/user_guide/messaging/ab_testing/concepts/race_conditions/).

        **Note:**
        Looking for the campaign version of this endpoint? Check out [Sending campaign messages using API-triggered delivery]({{site.baseurl}}/api/endpoints/messaging/send_messages/post_send_triggered_campaigns/).

        ## Response status codes

        The following table lists the responses for this endpoint, the error message you may receive, and how to resolve it.

        **Note:**
        If your workspace accepts `canvas_entry_properties` instead of `context`, error messages name `canvas_entry_properties` in place of `context`.

        | Status code | Meaning | Error message | How to resolve |
        | --- | --- | --- | --- |
        | `201 Created` | The request was accepted and the Canvas message was sent. The response includes a `dispatch_id`. | `success` | No action needed. |
        | `400 Bad Request` | The `canvas_id` is missing or isn't a string. | `canvas_id must be a string of the Canvas api identifier` | Pass a valid `canvas_id` string. Find it with the [Export Canvas list endpoint]({{site.baseurl}}/api/endpoints/export/canvas/get_canvases/). |
        | `400 Bad Request` | The Canvas can't be triggered by the API. | `Canvas must be triggerable by API` | Set the Canvas entry to **API-triggered** delivery, then retry. |
        | `400 Bad Request` | The `recipients` value isn't an array of objects that each include a user identifier. | `'recipients' must be an array of objects, each containing a user identifier and optional 'context'` | Pass `recipients` as an array of objects, each with an `external_user_id`, `user_alias`, or `braze_id`. |
        | `400 Bad Request` | The `external_user_ids` value isn't an array. | `external_user_ids must be an array of user ids` | Pass `external_user_ids` as an array of strings. |
        | `400 Bad Request` | A `braze_id` in `recipients` isn't a valid identifier. | `Invalid 'braze_id' value` | Pass each `braze_id` as a valid Braze user ID. |
        | `400 Bad Request` | A recipient's `attributes` value isn't an object. | `'attributes' must be a hash` | Pass each recipient's `attributes` as an object. |
        | `400 Bad Request` | The `recipients` array is empty. | `when including recipients, there must be at least one recipient specified` | Include at least one recipient, or use `broadcast`. |
        | `400 Bad Request` | The `recipients` array exceeds the maximum allowed length. | `Max input length exceeded.` | Send fewer recipients per request (up to the API-triggered recipient limit). |
        | `400 Bad Request` | The `broadcast` value isn't a boolean. | `Broadcast must be a boolean` | Pass `broadcast` as `true` or `false`. |
        | `400 Bad Request` | `broadcast` is `true` but `recipients` or `external_user_ids` were also provided. | `Cannot send messages to recipients with the broadcast parameter set to true. Broadcast is only available when sending to a Segment or Connected Audience` | Set `broadcast` to `true` only when sending to a segment or connected audience, without explicit recipients. |
        | `400 Bad Request` | No recipients were provided and `broadcast` isn't `true`. | `Must provide recipients unless the broadcast parameter is true` | Include `recipients`, or set `broadcast` to `true`. |
        | `400 Bad Request` | The `context` value isn't an object. | `'context' must be an object` | Pass `context` as an object. |
        | `400 Bad Request` | The `context` payload is too large. | `'context' is too large` | Reduce the size of `context` below your workspace's API trigger properties limit. |
        | `400 Bad Request` | The `segment_id` isn't a valid segment identifier. | `Invalid segment_id` | Pass a valid `segment_id`, or use a different audience. |
        | `400 Bad Request` | `segment_id` was combined with explicit recipients. | `'segment_id' cannot be combined with recipients. It is only available for broadcast sends` | Use `segment_id` only for broadcast sends, without explicit recipients. |
        | `400 Bad Request` | The specified segment is archived. | `this segment has been archived, not sending` | Use an active segment. |
        | `401 Unauthorized` | The REST API key is missing, malformed, or sent to the wrong REST endpoint. | `Invalid API key` | Send the key as `Authorization: Bearer YOUR_REST_API_KEY` to the correct [REST endpoint]({{site.baseurl}}/api/basics/#endpoints). For more causes, see [Errors and responses]({{site.baseurl}}/api/errors/#fatal-errors). |
        | `403 Access Denied` | The REST API key doesn't have the required permission. | `Access Denied` | Use a REST API key that has the `canvas.trigger.send` permission. |
        | `429 Rate Limited` | You exceeded the rate limit for this endpoint. | `Over rate limit` | Slow your request rate and retry with exponential backoff. See [API rate limits]({{site.baseurl}}/api/api_limits/). |
        | `5XX Internal Server Error` | An unexpected error occurred on the Braze server. | `Internal Server Error` | Retry with exponential backoff. If the error persists, contact [Support]({{site.baseurl}}/braze_support/). |
      operationId: post_canvas_trigger_send_post_send_triggered_canvases
      tags:
      - Messaging
      responses:
        '201':
          description: The request was accepted and the Canvas message was sent. The response includes a `dispatch_id`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SendTriggeredCanvasesResponse'
        '400':
          description: |-
            Bad Request. Causes include:

            - `canvas_id must be a string of the Canvas api identifier` — The `canvas_id` is missing or isn't a string.
            - `Canvas must be triggerable by API` — The Canvas can't be triggered by the API.
            - `'recipients' must be an array of objects, each containing a user identifier and optional 'context'` — The `recipients` value isn't an array of objects that each include a user identifier.
            - `external_user_ids must be an array of user ids` — The `external_user_ids` value isn't an array.
            - `Invalid 'braze_id' value` — A `braze_id` in `recipients` isn't a valid identifier.
            - `'attributes' must be a hash` — A recipient's `attributes` value isn't an object.
            - `when including recipients, there must be at least one recipient specified` — The `recipients` array is empty.
            - `Max input length exceeded.` — The `recipients` array exceeds the maximum allowed length.
            - `Broadcast must be a boolean` — The `broadcast` value isn't a boolean.
            - `Cannot send messages to recipients with the broadcast parameter set to true. Broadcast is only available when sending to a Segment or Connected Audience` — `broadcast` is `true` but `recipients` or `external_user_ids` were also provided.
            - `Must provide recipients unless the broadcast parameter is true` — No recipients were provided and `broadcast` isn't `true`.
            - `'context' must be an object` — The `context` value isn't an object.
            - `'context' is too large` — The `context` payload is too large.
            - `Invalid segment_id` — The `segment_id` isn't a valid segment identifier.
            - `'segment_id' cannot be combined with recipients. It is only available for broadcast sends` — `segment_id` was combined with explicit recipients.
            - `this segment has been archived, not sending` — The specified segment is archived.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: The REST API key is missing, malformed, or sent to the wrong REST endpoint.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: The REST API key doesn't have the required permission.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: You exceeded the rate limit for this endpoint.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '5XX':
          description: An unexpected error occurred on the Braze server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                canvas_id:
                  type: string
                  description: See Canvas identifier.
                context:
                  type: object
                  description: This includes Canvas entry properties. Personalization key-value pairs apply to all users in this request. The context object can be up to 50 KB.
                broadcast:
                  type: boolean
                  description: 'You must set `broadcast` to true when sending a message to the entire segment configured as the Canvas''s target audience in the Braze dashboard. This parameter defaults to false (as of August 31, 2017).    If `broadcast` is set to true, a `recipients` list cannot be included. However, use caution when setting `broadcast: true`, as unintentionally setting this flag may cause you to send your message to a larger-than-expected audience.'
                audience:
                  type: object
                  description: See Connected audience. When you include `audience`, the message is sent only to users who match the defined filters, such as custom attributes and subscription statuses.
                recipients:
                  type: array
                  items:
                    type: object
                  description: See Recipients object.   If not provided and `broadcast` is set to `true`, the message is sent to the entire segment configured as the Canvas's target audience in the Braze dashboard.   The `recipients` array may contain up to 50 objects, with each object containing a single `external_user_id` string and a `canvas_entry_properties` object. This call requires an `external_user_id`, `user_alias`, or `email`. Requests must specify only one.   If `email` is the identifier, you must include `prioritization` in the recipients object.
              required:
              - canvas_id
            examples:
              example_request:
                summary: Example request
                value:
                  canvas_id: canvas_identifier
                  context:
                    product_name: shoes
                    product_price: 79.99
                  broadcast: false
                  audience:
                    AND:
                    - custom_attribute:
                        custom_attribute_name: eye_color
                        comparison: equals
                        value: blue
                    - custom_attribute:
                        custom_attribute_name: favorite_foods
                        comparison: includes_value
                        value: pizza
                    - OR:
                      - custom_attribute:
                          custom_attribute_name: last_purchase_time
                          comparison: less_than_x_days_ago
                          value: 2
                      - push_subscription_status:
                          comparison: is
                          value: opted_in
                    - email_subscription_status:
                        comparison: is_not
                        value: subscribed
                    - last_used_app:
                        comparison: after
                        value: '2019-07-22T13:17:55+0000'
                  recipients:
                  - user_alias:
                      alias_name: example_name
                      alias_label: example_label
                    external_user_id: user_identifier
                    send_to_existing_only: true
                    attributes:
                      first_name: Alex
components:
  schemas:
    SendTriggeredCanvasesResponse:
      type: object
      properties:
        notice:
          type: string
        dispatch_id:
          type: string
        message:
          type: string
    ErrorResponse:
      type: object
      properties:
        message:
          type: string
          description: The error message describing why the request failed.
        errors:
          type: array
          description: Non-fatal errors encountered while processing the request. Data unaffected by these errors is still processed.
          items:
            type: object
            properties:
              type:
                type: string
                description: The error type.
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: REST API key
