A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Braze API is how an app or AI agent works with a Braze workspace: tracking users and their events, sending or scheduling messages, triggering a campaign or Canvas, managing catalogs and email templates, and exporting users by identifier or segment. Access is granted through a REST API key, and each key is created with a chosen set of granular permission scopes that set which endpoints a call can reach. Braze does not version its API, and rather than calling an app back, it pushes event data out through a separate export stream.
How an app or AI agent connects to Braze determines what it can reach. There is the REST API for sending and exporting data, and a hosted server that exposes Braze tools to agents, and each is governed by the REST API key behind it and the permissions chosen for that key.
The REST API takes JSON request bodies and returns JSON. Its host depends on the workspace's provisioned instance, like https://rest.iad-01.braze.com for US-01 or https://rest.fra-01.braze.eu for EU-01. A call authenticates with a REST API key sent as a Bearer token in the Authorization header.
Braze publishes a first-party Model Context Protocol server, in beta, that connects AI tools to non-PII Braze data. It reads aggregated data like campaign and Canvas analytics, custom attributes, and segments, and supports specific writes like creating media library assets, email templates, and content blocks. The current build runs locally from the braze-mcp-server package and authenticates with a REST API key; Braze has said a remote, hosted server is in early access. Claude and Cursor are the officially supported clients.
Currents is Braze's near real-time event export stream. Rather than calling an app back through inbound webhooks, Braze pushes message engagement and user behavior events server-to-server to a connected data store or warehouse, so an integration receives activity without polling. It is configured in the dashboard, not through the REST API.
Braze authenticates every REST API request with a REST API key passed as a Bearer token in the Authorization header. A key is created in the dashboard with a chosen set of granular permission scopes, like users.track, messages.send, or campaigns.trigger.send, so it can call only the endpoints it was granted. A key can also be restricted to specific IP addresses. A request with no key or a key missing the needed scope is rejected.
The Braze API is split into areas an agent can act on, like user data, messaging, subscription groups, catalogs, email lists, templates, and segments. Each area has its own methods, and writes in some areas send live messages or change subscriber records.
Methods for recording, identifying, exporting, and deleting user profiles.
Methods for sending, triggering, and scheduling messages, campaigns, and Canvases.
Methods for reading and setting a user's subscription state across groups.
Methods for managing catalogs and the items inside them.
Methods for querying and changing email bounce, spam, and subscription records.
Methods for managing reusable email templates and content blocks.
Methods for listing segments and reading their analytics.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
User dataMethods for recording, identifying, exporting, and deleting user profiles.9 | ||||||
| POST | /users/track | Record user attributes, custom events, and purchases on user profiles. | write | users.track | Current | |
A single request may carry up to 75 combined attribute, event, and purchase objects. Acts onuser Permission (capability) users.trackVersionAvailable since the API’s base version Webhook eventNone Rate limit3,000 requests per 3 seconds SourceOfficial documentation ↗ | ||||||
| POST | /users/identify | Associate an anonymous, alias-only profile with an identified user by external ID. | write | users.identify | Current | |
Shares a 20,000 requests per minute pool with delete, alias, and merge. Acts onuser Permission (capability) users.identifyVersionAvailable since the API’s base version Webhook eventNone Rate limit20,000 requests per minute, shared SourceOfficial documentation ↗ | ||||||
| POST | /users/alias/new | Create a new user alias for an existing identified user. | write | users.alias.new | Current | |
Shares a 20,000 requests per minute pool with identify, delete, and merge. Acts onuser_alias Permission (capability) users.alias.newVersionAvailable since the API’s base version Webhook eventNone Rate limit20,000 requests per minute, shared SourceOfficial documentation ↗ | ||||||
| POST | /users/merge | Merge two user profiles into one, combining their data. | write | users.merge | Current | |
Shares a 20,000 requests per minute pool with identify, alias, and delete. Acts onuser Permission (capability) users.mergeVersionAvailable since the API’s base version Webhook eventNone Rate limit20,000 requests per minute, shared SourceOfficial documentation ↗ | ||||||
| POST | /users/delete | Delete user profiles by external ID, Braze ID, or user alias. | write | users.delete | Current | |
Irreversible; shares a 20,000 requests per minute pool with identify, alias, and merge. Acts onuser Permission (capability) users.deleteVersionAvailable since the API’s base version Webhook eventNone Rate limit20,000 requests per minute, shared SourceOfficial documentation ↗ | ||||||
| POST | /users/export/ids | Export user profiles by identifier (external ID, Braze ID, email, or alias). | read | users.export.ids | Current | |
Returns profile data; 250 requests per minute for workspaces onboarded after 22 August 2024, 2,500 per minute before. Acts onuser Permission (capability) users.export.idsVersionAvailable since the API’s base version Webhook eventNone Rate limit250 requests per minute SourceOfficial documentation ↗ | ||||||
| POST | /users/export/segment | Export all user profiles within a named segment to a connected data store. | read | users.export.segment | Current | |
Exports an entire segment's membership; shares the 250,000 per hour pool. Acts onuser Permission (capability) users.export.segmentVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| POST | /users/external_ids/rename | Rename a user's deprecated external ID to a new external ID. | write | users.external_ids.rename | Current | |
A core write to a user's primary identifier. Acts onexternal_id Permission (capability) users.external_ids.renameVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /users/external_ids/remove | Remove deprecated external IDs once a rename migration is complete. | write | users.external_ids.remove | Current | |
Irreversible removal of the old identifier. Acts onexternal_id Permission (capability) users.external_ids.removeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
MessagingMethods for sending, triggering, and scheduling messages, campaigns, and Canvases.8 | ||||||
| POST | /messages/send | Send messages immediately to a set of users via the API. | write | messages.send | Current | |
Sends live messages; broadcast sends are limited to 250 per minute across all audiences and 10 per minute per audience. Acts onmessage Permission (capability) messages.sendVersionAvailable since the API’s base version Webhook eventNone Rate limit250 requests per minute (broadcast) SourceOfficial documentation ↗ | ||||||
| POST | /messages/send/create | Create a send ID to track and report on a message send. | write | messages.send_id.create | Current | |
Creates an identifier; no message is sent by this call alone. Acts onsend_id Permission (capability) messages.send_id.createVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /campaigns/trigger/send | Trigger an API-triggered campaign send to specified recipients. | write | campaigns.trigger.send | Current | |
Sends a live campaign; broadcast sends share the 250 per minute broadcast limit. Acts oncampaign Permission (capability) campaigns.trigger.sendVersionAvailable since the API’s base version Webhook eventNone Rate limit250 requests per minute (broadcast) SourceOfficial documentation ↗ | ||||||
| POST | /canvas/trigger/send | Trigger an API-triggered Canvas send to specified recipients. | write | canvas.trigger.send | Current | |
Sends a live Canvas; broadcast sends share the 250 per minute broadcast limit. Acts oncanvas Permission (capability) canvas.trigger.sendVersionAvailable since the API’s base version Webhook eventNone Rate limit250 requests per minute (broadcast) SourceOfficial documentation ↗ | ||||||
| POST | /messages/schedule/create | Schedule messages, campaigns, or Canvases to send at a future time. | write | messages.schedule.create | Current | |
Queues a future send; non-broadcast calls share the 250,000 per hour pool. Acts onscheduled_message Permission (capability) messages.schedule.createVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| POST | /messages/schedule/update | Update an already scheduled message before it sends. | write | messages.schedule.update | Current | |
Changes a queued send. Acts onscheduled_message Permission (capability) messages.schedule.updateVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /messages/schedule/delete | Cancel a scheduled message before it sends. | write | messages.schedule.delete | Current | |
Cancels a queued send. Acts onscheduled_message Permission (capability) messages.schedule.deleteVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /messages/scheduled_broadcasts | List upcoming scheduled campaigns and Canvases broadcast to entire segments. | read | messages.schedule_broadcasts | Current | |
Read-only. Acts onscheduled_message Permission (capability) messages.schedule_broadcastsVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
Subscription groupsMethods for reading and setting a user's subscription state across groups.3 | ||||||
| GET | /subscription/status/get | List a user's subscription status across their subscription groups. | read | subscription.status.get | Current | |
Read-only; reveals a person's opt-in or opt-out state. Acts onsubscription_group Permission (capability) subscription.status.getVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| GET | /subscription/user/status | List the subscription groups a user belongs to, with their status. | read | subscription.groups.get | Current | |
Read-only. Acts onsubscription_group Permission (capability) subscription.groups.getVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| POST | /subscription/status/set | Set a user's subscription status within one or more subscription groups. | write | subscription.status.set | Current | |
Changes a real person's opt-in or opt-out state. Acts onsubscription_group Permission (capability) subscription.status.setVersionAvailable since the API’s base version Webhook eventNone Rate limit5,000 requests per minute SourceOfficial documentation ↗ | ||||||
CatalogsMethods for managing catalogs and the items inside them.7 | ||||||
| GET | /catalogs | List all catalogs in the workspace. | read | catalogs.get | Current | |
Read-only. Acts oncatalog Permission (capability) catalogs.getVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| POST | /catalogs | Create a new catalog with a defined set of fields. | write | catalogs.create | Current | |
Defines a new catalog schema. Acts oncatalog Permission (capability) catalogs.createVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /catalogs/{catalog_name} | Delete a catalog and all of its items. | write | catalogs.delete | Current | |
Irreversible; removes the catalog and every item in it. Acts oncatalog Permission (capability) catalogs.deleteVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /catalogs/{catalog_name}/items | Add new items to a catalog. | write | catalogs.add_items | Current | |
A core catalog write. Acts oncatalog_item Permission (capability) catalogs.add_itemsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /catalogs/{catalog_name}/items/{item_id} | Edit an existing catalog item. | write | catalogs.update_items | Current | |
Updates fields on an existing item. Acts oncatalog_item Permission (capability) catalogs.update_itemsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /catalogs/{catalog_name}/items | List the items in a catalog. | read | catalogs.get_items | Current | |
Read-only. Acts oncatalog_item Permission (capability) catalogs.get_itemsVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| DELETE | /catalogs/{catalog_name}/items/{item_id} | Delete a single item from a catalog. | write | catalogs.delete_items | Current | |
Removes an item from the catalog. Acts oncatalog_item Permission (capability) catalogs.delete_itemsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Email listsMethods for querying and changing email bounce, spam, and subscription records.5 | ||||||
| POST | /email/status | Change the subscription status of an email address. | write | email.status | Current | |
Changes a real email address's subscription state. Acts onemail Permission (capability) email.statusVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| GET | /email/hard_bounces | Query the list of email addresses that have hard bounced. | read | email.hard_bounces | Current | |
Read-only. Acts onemail Permission (capability) email.hard_bouncesVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| GET | /email/unsubscribes | Query the list of email addresses that have unsubscribed. | read | email.unsubscribes | Current | |
Read-only. Acts onemail Permission (capability) email.unsubscribesVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| POST | /email/bounce/remove | Remove email addresses from the hard bounce list. | write | email.bounce.remove | Current | |
Re-enables sending to a previously bounced address. Acts onemail Permission (capability) email.bounce.removeVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| POST | /email/blocklist | Add email addresses to the blocklist so Braze stops sending to them. | write | email.blocklist | Current | |
Stops all sends to the listed addresses and unsubscribes them. Acts onemail Permission (capability) email.blocklistVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
Templates & content blocksMethods for managing reusable email templates and content blocks.6 | ||||||
| POST | /templates/email/create | Create a reusable email template. | write | templates.email.create | Current | |
A core content write. Acts onemail_template Permission (capability) templates.email.createVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| POST | /templates/email/update | Update an existing email template. | write | templates.email.update | Current | |
Changes a template other messages may reference. Acts onemail_template Permission (capability) templates.email.updateVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| GET | /templates/email/list | List available email templates. | read | templates.email.list | Current | |
Read-only. Acts onemail_template Permission (capability) templates.email.listVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| GET | /templates/email/info | See the details and body of a specific email template. | read | templates.email.info | Current | |
Read-only. Acts onemail_template Permission (capability) templates.email.infoVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| POST | /content_blocks/create | Create a reusable content block for use across messages. | write | content_blocks.create | Current | |
A core content write. Acts oncontent_block Permission (capability) content_blocks.createVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| GET | /content_blocks/list | List available content blocks. | read | content_blocks.list | Current | |
Read-only. Acts oncontent_block Permission (capability) content_blocks.listVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
SegmentsMethods for listing segments and reading their analytics.3 | ||||||
| GET | /segments/list | List the segments in the workspace, with their names and analytics-tracking flag. | read | segments.list | Current | |
Read-only. Acts onsegment Permission (capability) segments.listVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| GET | /segments/details | See the details of a segment, like its creation time and filters. | read | segments.details | Current | |
Read-only. Acts onsegment Permission (capability) segments.detailsVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
| GET | /segments/data_series | See a daily series of the estimated size of a segment over time. | read | segments.data_series | Current | |
Read-only; requires analytics tracking enabled on the segment. Acts onsegment Permission (capability) segments.data_seriesVersionAvailable since the API’s base version Webhook eventNone Rate limit250,000 requests per hour, shared SourceOfficial documentation ↗ | ||||||
Braze does not call an app back through inbound webhooks. Instead, its Currents stream exports event data server-to-server in near real time to a connected data store, so an integration receives activity without polling the REST API.
| Event | What it signals | Triggered by |
|---|
Braze limits how fast an app can call, with a default ceiling that most endpoints share and tighter per-endpoint ceilings on the highest-volume methods, measured in requests per hour, minute, or a few seconds.
Braze meters requests per time window, not by a per-method cost or point weighting. Most endpoints share a default ceiling of 250,000 requests per hour, while the highest-volume methods carry their own tighter limits: /users/track allows 3,000 requests per 3 seconds (with up to 75 combined attribute, event, and purchase objects per request), the identify, delete, alias, and merge endpoints share 20,000 requests per minute, and broadcast sends across messages, campaigns, and Canvases are capped at 250 per minute across all audiences and 10 per minute per audience. Going over returns HTTP 429, and every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers describing the current window.
List and export endpoints page with a cursor or an offset depending on the endpoint. The user export by identifier endpoint accepts up to 50 identifiers per request, and segment exports stream the full segment to a connected store. Each endpoint's reference page documents its own paging fields.
A /users/track request may carry up to 75 combined attribute, event, and purchase objects, and the user data endpoints enforce a 4 MB payload limit per request. The user export by identifier endpoint accepts up to 50 identifiers at a time.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | Bad Request | The request was malformed, such as invalid JSON or a missing required field. | Fix the request body against the endpoint's documented parameters and resend. |
| 401 | Unauthorized | No valid REST API key was provided. | Send a valid REST API key as a Bearer token in the Authorization header. |
| 403 | Forbidden | The API key is valid but lacks the permission scope this endpoint requires. | Grant the endpoint's scope on the key, or use a key that already carries it. |
| 404 | Not Found | The endpoint or referenced object does not exist, often a wrong REST host for the instance. | Confirm the path and use the REST endpoint that matches the workspace's instance. |
| 429 | Rate Limited | The request exceeded the endpoint's rate limit. | Back off using the X-RateLimit-Reset header, then retry with exponential backoff. |
| 500 | Internal Server Error | An error occurred on Braze's side. It is rare. | Retry with backoff, and contact Braze support if it persists. |
Braze does not version its REST API by date or path. There is one continuously updated API, and notable changes ship through dated release notes.
Braze does not version its REST API by date or path. There is one continuously updated API, and notable additions, changes, and deprecations ship through dated release notes rather than a new version string. The entries below are recent dated changes relevant to the REST API and integrations.
Braze launched a new data center, JP-01, adding another regional REST host for provisioned workspaces.
Per-channel rate limits and new Currents export fields shipped.
Deprecated API methods were removed and native SDK version bindings updated.
Connected Content gained stored token-authentication credentials.
There is no version to pin; track the release notes for additions and deprecations.
Braze release notes ↗Bollard AI sits between a team's AI agents and Braze. Grant each agent exactly the access it needs, read or write, area by area, and every call is checked and logged.