---
openapi: 3.0.3
info:
  title: Braze REST API – 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
  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: |
        ## 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/).
      operationId: post_canvas_trigger_send_post_send_triggered_canvases
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendTriggeredCanvasesRequest'
            examples:
              external_user_id:
                summary: Send to an external user ID with a connected audience
                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:
                    - external_user_id: user_identifier
                      send_to_existing_only: true
                      attributes:
                        first_name: Alex
              user_alias:
                summary: Send to a user alias
                value:
                  canvas_id: canvas_identifier
                  recipients:
                    - user_alias:
                        alias_name: example_name
                        alias_label: example_label
      responses:
        "201":
          description: |
            The request was accepted and the Canvas message was sent. The response includes a `dispatch_id`. No action needed.

            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.

            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."
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SendTriggeredCanvasesResponse'
              examples:
                paused:
                  summary: Example success response
                  value:
                    notice: The Canvas is paused. Resume the Canvas to ensure trigger requests will take effect.
                    dispatch_id: example_dispatch_id
                    message: success
        "400":
          description: |
            Bad request. To resolve it:

            - **The `canvas_id` is missing or isn't a string:** Pass a valid `canvas_id` string. Find it with the [Export Canvas list endpoint]({{site.baseurl}}/api/endpoints/export/canvas/get_canvases/).
            - **The Canvas can't be triggered by the API:** Set the Canvas entry to **API-triggered** delivery, then retry.
            - **The `recipients` value isn't an array of objects that each include a user identifier:** Pass `recipients` as an array of objects, each with an `external_user_id`, `user_alias`, or `braze_id`.
            - **The `external_user_ids` value isn't an array:** Pass `external_user_ids` as an array of strings.
            - **A `braze_id` in `recipients` isn't a valid identifier:** Pass each `braze_id` as a valid Braze user ID.
            - **A recipient's `attributes` value isn't an object:** Pass each recipient's `attributes` as an object.
            - **The `recipients` array is empty:** Include at least one recipient, or use `broadcast`.
            - **The `recipients` array exceeds the maximum allowed length:** Send fewer recipients per request (up to the API-triggered recipient limit).
            - **The `broadcast` value isn't a boolean:** Pass `broadcast` as `true` or `false`.
            - **`broadcast` is `true` but `recipients` or `external_user_ids` were also provided:** Set `broadcast` to `true` only when sending to a segment or connected audience, without explicit recipients.
            - **No recipients were provided and `broadcast` isn't `true`:** Include `recipients`, or set `broadcast` to `true`.
            - **The `context` value isn't an object:** Pass `context` as an object.
            - **The `context` payload is too large:** Reduce the size of `context` below your workspace's API trigger properties limit.
            - **The `segment_id` isn't a valid segment identifier:** Pass a valid `segment_id`, or use a different audience.
            - **`segment_id` was combined with explicit recipients:** Use `segment_id` only for broadcast sends, without explicit recipients.
            - **The specified segment is archived:** Use an active segment.

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

            If your request encounters a fatal error, refer to [Errors and responses]({{site.baseurl}}/api/errors/#fatal-errors) for the error code and description.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalid_canvas_id:
                  summary: The canvas_id is missing or isn't a string
                  value:
                    message: canvas_id must be a string of the Canvas api identifier
                canvas_not_api_triggered:
                  summary: The Canvas can't be triggered by the API
                  value:
                    message: Canvas must be triggerable by API
                malformed_recipients:
                  summary: The recipients value is malformed
                  value:
                    message: "'recipients' must be an array of objects, each containing a user identifier and optional 'context'"
                malformed_external_user_ids:
                  summary: The external_user_ids value isn't an array
                  value:
                    message: external_user_ids must be an array of user ids
                invalid_braze_id:
                  summary: A braze_id isn't a valid identifier
                  value:
                    message: "Invalid 'braze_id' value"
                attributes_not_object:
                  summary: A recipient's attributes value isn't an object
                  value:
                    message: "'attributes' must be a hash"
                empty_recipients:
                  summary: The recipients array is empty
                  value:
                    message: when including recipients, there must be at least one recipient specified
                too_many_recipients:
                  summary: Too many recipients
                  value:
                    message: Max input length exceeded.
                broadcast_not_boolean:
                  summary: The broadcast value isn't a boolean
                  value:
                    message: Broadcast must be a boolean
                broadcast_with_recipients:
                  summary: Broadcast with explicit recipients
                  value:
                    message: Cannot send messages to recipients with the broadcast parameter set to true. Broadcast is only available when sending to a Segment or Connected Audience
                missing_recipients:
                  summary: No recipients and broadcast isn't true
                  value:
                    message: Must provide recipients unless the broadcast parameter is true
                context_not_object:
                  summary: The context value isn't an object
                  value:
                    message: "'context' must be an object"
                context_too_large:
                  summary: The context payload is too large
                  value:
                    message: "'context' is too large"
                invalid_segment_id:
                  summary: The segment_id isn't valid
                  value:
                    message: Invalid segment_id
                segment_id_with_recipients:
                  summary: segment_id combined with recipients
                  value:
                    message: "'segment_id' cannot be combined with recipients. It is only available for broadcast sends"
                segment_archived:
                  summary: The segment is archived
                  value:
                    message: this segment has been archived, not sending
        "401":
          description: |
            Unauthorized. The REST API key is missing, malformed, or sent to the wrong REST endpoint. 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).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalid_api_key:
                  summary: Invalid API key
                  value:
                    message: 'Invalid API key: YOUR_REST_API_KEY'
        "403":
          description: Access denied. The REST API key doesn't have the required permission. Use a REST API key that has the `canvas.trigger.send` permission.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                access_denied:
                  summary: Missing permission
                  value:
                    message: Access Denied
        "429":
          description: |
            Rate limited. You exceeded the rate limit for this endpoint. Slow your request rate and retry with exponential backoff. See [API rate limits]({{site.baseurl}}/api/api_limits/).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        5XX:
          description: |
            Internal server error. An unexpected error occurred on the Braze server. Retry with exponential backoff. If the error persists, contact [Support]({{site.baseurl}}/braze_support/).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: REST API key
      description: |
        REST API keys are created in the Braze dashboard at **Settings → APIs and
        Identifiers → API Keys**. The key must include the `canvas.trigger.send` permission.
        Pass the key as `Authorization: Bearer YOUR_REST_API_KEY`.
  schemas:
    UserAlias:
      title: User alias
      type: object
      required: [alias_name, alias_label]
      description: See [user alias object]({{site.baseurl}}/api/objects_filters/user_alias_object).
      properties:
        alias_name:
          type: string
          example: example_name
        alias_label:
          type: string
          example: example_label
    CanvasRecipient:
      title: Recipient
      type: object
      description: |
        Either `external_user_id` or `user_alias` or `email` is required. Requests must specify only one.
      properties:
        user_alias:
          allOf:
            - $ref: '#/components/schemas/UserAlias'
          description: User alias of user to receive message.
        external_user_id:
          type: string
          description: External identifier of user to receive message.
          example: user_identifier
        email:
          type: string
          description: Email address of user to receive message.
          example: jane.doe@example.com
        prioritization:
          type: array
          items:
            type: string
          description: Prioritization array; required when using email. See [`prioritization`]({{site.baseurl}}/api/endpoints/user_data/post_user_identify#identifying-users-by-email-addresses-and-phone-numbers).
          example:
            - identified
            - most_recently_updated
        context:
          type: object
          additionalProperties: true
          description: Canvas context properties for this user; key-value pairs override any keys that conflict with the parent `context`.
        send_to_existing_only:
          type: boolean
          default: true
          description: Defaults to true, can't be used with user aliases; if set to `false`, an `attributes` object must also be included.
          example: true
        attributes:
          type: object
          additionalProperties: true
          description: 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.
          example:
            first_name: Alex
    SendTriggeredCanvasesRequest:
      title: Send API-triggered Canvas request
      type: object
      required: [canvas_id]
      properties:
        canvas_id:
          type: string
          description: See [Canvas identifier]({{site.baseurl}}/api/identifier_types/).
          example: canvas_identifier
        context:
          type: object
          additionalProperties: true
          description: |
            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.

            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`.
          example:
            product_name: shoes
            product_price: 79.99
        broadcast:
          type: boolean
          default: false
          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.
          example: false
        audience:
          title: Connected audience object
          type: object
          additionalProperties: true
          description: 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:
          type: array
          items:
            $ref: '#/components/schemas/CanvasRecipient'
          description: |
            See [Recipients object]({{site.baseurl}}/api/objects_filters/recipient_object/).

            If `send_to_existing_only` is `false`, an `attributes` object must be included on the recipient.

            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/).

            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. 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).

            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.
    SendTriggeredCanvasesResponse:
      title: Send API-triggered Canvas response
      type: object
      properties:
        notice:
          type: string
          description: Included when the Canvas is archived or paused.
          example: The Canvas is paused. Resume the Canvas to ensure trigger requests will take effect.
        dispatch_id:
          type: string
          description: |
            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: example_dispatch_id
        message:
          type: string
          example: success
    ErrorResponse:
      title: Error
      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.
