Connect Braze Webhooks to Prize Draws
Connect Braze Webhooks to Prize Draws
Who this is for: Marketing ops and Braze admins who want Braze to enter a customer into a prize draw when a campaign or Canvas step fires, for example after a purchase, a sign-up or a milestone.
Time to complete: About 30 minutes (plus QA), once an Incentable prize draw and a Braze integration are set up.
Overview
When a Braze campaign or Canvas step runs, Braze sends an HTTP webhook to Incentable. Incentable finds the member (or creates them as Pending), adds the entries to the prize draw, and records the request in your integration's Activity log. If the prize draw's Entry received email is turned on, Incentable emails the entrant to confirm.
The customer never fills in a form. Their Braze profile supplies their details, and your Braze trigger decides when they qualify.
Every entry goes through the same rules as an entry added in the Admin dashboard: the prize draw must be Active and inside its entry period, per-member and per-submission entry limits apply, and excluded members are rejected.
Prerequisites
Braze
| Requirement | Notes |
|---|---|
| Webhooks enabled on your Braze package | Availability depends on your Braze contract. If Webhooks is not visible, ask your Braze account manager or customer success manager. |
| Permission to create a Webhook Campaign or Canvas webhook step | Needed to configure the call to Incentable. |
| A defined trigger | Custom event (for example, purchase completed) or Canvas entry / step criteria after the customer qualifies. |
Incentable
| Requirement | Notes |
|---|---|
| A prize draw in the program | Set to Active with an entry period that covers your campaign dates. Use Test mode during QA so test entries are kept out of live draws. |
| A Braze (or Custom API) integration | With Prize Draws: Write permission. Read is optional and only needed to look up submissions. |
| Optional: Default prize draw | If set on the integration, Braze does not need to send prizeDrawId in every payload. |
Get credentials from Incentable
- Log in to the Incentable Admin Dashboard.
- Select the program that runs the prize draw (API keys are scoped to a single program).
- Open Integrations and add (or open) a Braze integration. A Custom API integration also works if you are calling from your own system rather than Braze.
- Under Permissions & Configuration → Prize Draws, confirm Write is on. New Braze integration keys have it on by default.
- Optionally choose a Default Prize Draw on the same card and save.
- Generate the API key and store it in a secure password manager.
Find the prize draw ID
If you are not using a default prize draw, you need the prize draw's ID for the webhook body. In the Admin dashboard, open the prize draw, go to the Entries tab and click API. The Prize draw ID is shown with a copy button.
Endpoint Braze should call
| Item | Value |
|---|---|
| Method | POST |
| Path | /prizedraws/entries |
| Full URL | https://us-central1-incentable-app-37d9c.cloudfunctions.net/externalApi/api/v1/external/prizedraws/entries |
The URL is also shown on the Braze integration's settings page under Connection.
Headers
| Header | Required | Value |
|---|---|---|
Authorization | Yes | Bearer <YOUR_API_KEY> |
Content-Type | Yes | application/json |
Idempotency-Key | Recommended | Stable unique string for this entry. Body idempotencyKey takes precedence over this header; externalRef is used if neither is sent. |
Request body for the Braze webhook composer
Fields
The body uses the same fields as the Prize Draw Entries API — see that page for every field, type and limit. The ones that matter most in Braze:
member.email,member.firstname,member.lastname— required; map them from the Braze profile.prizeDrawId— required unless a Default Prize Draw is set on the integration.quantity— optional, 1–400 (default1); prize draw entry limits also apply.externalRef— required for Braze (oridempotencyKey/ anIdempotency-Keyheader); unique per prize draw.
quantity (for example "2"), and treats an empty value (a Braze attribute that is not set) as not supplied rather than an error.Recommended Braze → payload mapping
| Incentable field | Suggested Braze source |
|---|---|
member.email | {{${email_address}}} |
member.firstname | {{${first_name}}} |
member.lastname | {{${last_name}}} |
member.accountKey | {{${user_id}}} or a custom attribute holding your CRM id |
member.mobile | {{${phone_number}}} or a custom attribute |
prizeDrawId | Fixed string, or omit if a default prize draw is configured |
quantity | Fixed number, or an event property such as {{event_properties.${entries}}} |
externalRef | Must be unique per entry moment — e.g. campaign/Canvas id + user id + order or event id |
metadata | Fixed values or Liquid, e.g. {{campaign.${name}}} |
408, 429 and 5XX, and without a stable reference a retry would add a second set of entries. Requests from a Braze integration with no externalRef, idempotencyKey or Idempotency-Key header are rejected with 400 REFERENCE_REQUIRED before anything is created. Braze does not retry a 400, so a missing reference shows up in your test send rather than as duplicate entries.Choosing accountKey
Prefer, in order:
{{${user_id}}}— always present in Braze, stable, no custom attribute setup.- Custom attribute — when you already sync a CRM id into Braze and want Incentable to match on the same key.
- Omit — Incentable matches or creates by email only (works, but weaker if emails change).
Simple body (recommended for most campaigns)
One entry per qualifying event, fixed prize draw:
{
"prizeDrawId": "YOUR_PRIZE_DRAW_ID",
"member": {
"email": "{{${email_address}}}",
"firstname": "{{${first_name}}}",
"lastname": "{{${last_name}}}",
"accountKey": "{{${user_id}}}"
},
"quantity": 1,
"externalRef": "braze-{{campaign.${api_id}}}-{{${user_id}}}-{{event_properties.${order_id}}}",
"idempotencyKey": "braze-{{campaign.${api_id}}}-{{${user_id}}}-{{event_properties.${order_id}}}",
"metadata": {
"campaign": "{{campaign.${name}}}"
}
}
Advanced body (entries vary per event)
Entries from an event property, for example one entry per $50 spent calculated in Braze. Adjust property names to match your workspace:
{
"member": {
"email": "{{${email_address}}}",
"firstname": "{{${first_name}}}",
"lastname": "{{${last_name}}}",
"accountKey": "{{custom_attribute.${account_key}}}"
},
"quantity": "{{event_properties.${entries}}}",
"externalRef": "braze-{{campaign.${api_id}}}-{{${user_id}}}-{{event_properties.${order_id}}}",
"idempotencyKey": "braze-{{campaign.${api_id}}}-{{${user_id}}}-{{event_properties.${order_id}}}",
"metadata": {
"orderId": "{{event_properties.${order_id}}}",
"store": "{{event_properties.${store}}}"
}
}
This example omits prizeDrawId, so it uses the Default Prize Draw set on the integration.
Static JSON sample (for smoke tests)
{
"prizeDrawId": "YOUR_PRIZE_DRAW_ID",
"member": {
"email": "jane.doe@example.com",
"firstname": "Jane",
"lastname": "Doe",
"accountKey": "CRM-100245"
},
"quantity": 2,
"externalRef": "braze-qa-2026-10-20-001",
"idempotencyKey": "braze-qa-2026-10-20-001",
"metadata": { "source": "qa" }
}
Braze setup steps
Aligns with Braze's Create a webhook flow. Exact UI labels can vary by Braze version.
- Create a Webhook Campaign, or add a Webhook component in a Canvas.
- Webhook URL: paste the prize draw entry endpoint from above.
- HTTP method:
POST. - Request headers:
Authorization:Bearer <YOUR_API_KEY>Content-Type:application/json- Optional but recommended:
Idempotency-Keywith the same Liquid expression asexternalRef.
- Request body: choose JSON / raw body and paste the simple body (or the advanced body if entries vary).
- Compose / personalization: preview with a test user so email, name, quantity and
externalReflook correct. - Delivery / trigger:
- Campaign: action-based on a custom event (for example, purchase completed), or
- Canvas: place the webhook step after the qualification path.
- Optional multichannel: add a Braze email or push in the same campaign/Canvas, for example "You're in the draw!". Turn off the prize draw's Entry received email in Incentable if you don't want the entrant to get two confirmations.
- Save, run a test send, then launch.
How Braze retries interact with prize draw responses
Braze retries only for certain HTTP responses (for example 408, 429, 5XX). Most other responses, including 401 and other 4XX, are not retried. See Braze's Response codes and retry logic.
| Incentable response | Braze typically… | What you should do |
|---|---|---|
201 Created | Success, no retry | Done — entries were added. |
200 OK (idempotent replay) | Success, no retry | Safe — the earlier submission is returned and no entries are added. |
400 / 401 / 403 / 404 / 409 / 422 | Usually not retried | Fix config or payload; check Braze webhook / Message Activity logs and the Incentable integration's Activity log. |
408 / 429 / 5XX | May retry | You must use a stable externalRef (and/or Idempotency-Key) so retries do not add duplicate entries. |
Success response
A successful request returns 201 with the submissionId, the number of entries added, the member's total entries and a test flag. A replay of the same idempotency key returns 200 with the original payload and adds nothing. Field-by-field details are on the Prize Draw Entries API page.
Idempotency & duplicates
| Concept | Rule |
|---|---|
externalRef uniqueness | Unique per prize draw. The same externalRef can be used in a different prize draw. |
| Choosing a Braze-side key | Use something that will not change on retry, e.g. braze-{campaign_or_canvas_id}-{user_id}-{order_or_event_id}. Avoid timestamps or random values. |
Idempotency-Key / idempotencyKey | Prefer the same stable value as externalRef. The API resolves: body idempotencyKey → Idempotency-Key header → externalRef. Braze integrations must send at least one; Custom API callers without one get no duplicate protection. |
201 vs 200 | 201 = new entries. 200 = safe replay of a completed submission with the same idempotency key. |
409 | DUPLICATE_EXTERNAL_REF — entries with this externalRef already exist in this prize draw. The response details.submissionId gives the original submission. Braze typically does not retry 409. |
Look up a submission (optional)
Braze does not need this, but it is useful for support and reconciliation. It requires Prize Draws: Read on the integration — see Look up a submission.
Troubleshooting
Start in Braze Message Activity / webhook error logs, then check the Incentable integration's Activity log. Every request, including rejected ones, is recorded there. The Prize Draw Entries API page lists every error code.
| Status / code | Plain language | What to fix |
|---|---|---|
400 validation | Missing member fields, or quantity not a whole number. | Check Liquid (empty email or names), and that quantity renders as a whole number. |
400 REFERENCE_REQUIRED | A Braze request had no externalRef, idempotencyKey or Idempotency-Key header. | Add a stable externalRef to the webhook body. Check the Liquid isn't rendering it empty. |
400 NO_PRIZE_DRAW_SPECIFIED | No prizeDrawId in the body and no default on the integration. | Add prizeDrawId, or set a Default Prize Draw on the integration. |
401 | Invalid or missing API key. | Fix Authorization: Bearer …. Braze will not keep retrying most 401s. |
403 PERMISSION_DENIED | The key lacks Prize Draws Write (or Read for lookups). | Ask Incentable to enable the permission on the integration. |
404 | Prize draw not found in this program. | Confirm the prizeDrawId (or default) belongs to the same program as the API key. |
409 DUPLICATE_EXTERNAL_REF | That externalRef was already used in this prize draw. | Expected on a true duplicate. Use a new externalRef only when you intend a new submission. |
422 PROMOTION_NOT_ACTIVE | The prize draw is Draft, Closed or otherwise not Active. | Set the prize draw to Active. |
422 PROMOTION_NOT_OPEN / PROMOTION_CLOSED | The request arrived before the entry period opened or after it closed. | Check the prize draw's open and close dates against your campaign schedule. |
422 ENTRANT_EXCLUDED | The member has been excluded from this prize draw. | Expected — excluded members cannot enter. Review exclusions in the Admin dashboard if unexpected. |
422 LIMIT_EXCEEDED | Over the per-member or per-submission entry limit. details.limitBreaches lists which. | Lower quantity, or review the prize draw's entry limits. |
429 | Rate limit reached for the key. | Braze retries with backoff. If it persists, ask Incentable about the key's rate-limit tier. |
| Braze defers the host | Many failures caused Braze to pause sends to Incentable. | Fix the root cause, wait for the cooldown, then retest. |
Test plan
- Put the prize draw in Test mode and make sure it is Active and inside its entry period.
- In Braze, send a test webhook for a QA user with a unique
externalRef(for examplebraze-qa-<date>-001). - Confirm:
- Braze shows a successful webhook delivery (
201). - The entries appear on the prize draw's Entries tab with source API.
- The request shows as allocated in the integration's Activity log.
- The QA inbox receives the entry confirmation (if the Entry received email is on).
- Braze shows a successful webhook delivery (
- Retry simulation: send again with the same
externalRefand idempotency key. Expect200or409, and no new entries. - Send with a bad API key. Expect
401, and confirm Braze does not keep retrying. - Send once with
externalRefremoved. Expect400 REFERENCE_REQUIREDand no entries. - Before launch, turn Test mode off on the prize draw. Test entries are not included in live draws.
Pre-launch checklist
- Braze package includes Webhooks
- Webhook Campaign or Canvas webhook step created
- Trigger / Canvas path matches the moment a customer should be entered
- Braze integration created in Incentable with Prize Draws: Write
- API key stored securely; used only in the
Authorizationheader - Prize draw Active, entry period covers the campaign, entry limits reviewed
- Default Prize Draw set or
prizeDrawIdincluded in the Braze body - Liquid maps email, first name and last name correctly
- Stable unique
externalRef(and matchingidempotencyKey/Idempotency-Key) on every send - Test send:
201, entries visible in Incentable, Activity log shows allocated - Same-key resend:
200or409, no extra entries - Bad-auth test:
401, no Braze retry loop - Decided which confirmation the entrant gets: Incentable email, Braze message, or both
- Prize draw Test mode turned off for go-live
Related
- Connect Braze Webhooks to RewardStar — issue gift cards from the same Braze integration
- Prize Draw Entries API — the same endpoint from your own system via a Custom API integration
- API Overview — base URL, auth, getting your API key
- Braze — Create a webhook
- Braze — Response codes and retry logic
