Overview
A food delivery service sent promotions into areas where kitchens and drivers were already constrained, leading to offers customers could not redeem. Capacity lived in the dispatch system, while targeting and cadence lived in Braze, so marketers guessed at blackout zones and pulled campaigns at the last minute. We integrated the dispatch capacity API with Braze, added a geography-aware eligibility service, and enforced dynamic suppressions in Canvas at send time. Promotions aligned to real availability, support heard from fewer disappointed customers, and marketers scheduled with confidence instead of working from spreadsheets.
Client Profile
- Industry: On?demand food delivery
- Company size (range): Multi?city consumer marketplace with peak?driven demand
- Stage: Scaling lifecycle and promotional programs with tighter operations alignment
- Department owner: Marketing & Customer Engagement (CRM/Lifecycle)
- Other stakeholders: Dispatch & Operations, Kitchen/Restaurant Partnerships, Product, Data & Analytics, Customer Support, Legal & Privacy, IT/Integrations
The Challenge
Promotions needed to reflect reality on the ground: inventory by kitchen, driver availability by zone, and cut?offs by time window. In practice, capacity lived in the dispatch system; customer location and segments lived in CRM and Braze. Marketing teams exported ad hoc reports, eyeballed heat maps, and trimmed lists manually. Zones shifted as weather and demand changed, but promotions were already scheduled. The result was predictable: customers received discounts they could not use, support issued apologies and credits, and operations pushed to throttle messaging near peak periods.
Coordination became a bottleneck. Dispatch created blackout spreadsheets, lifecycle managers adjusted segments for affected postcodes, and QA tried to predict where availability would collapse. The same pain recurred whenever a new restaurant cluster launched or a city changed its delivery boundaries. Leadership wanted to keep Braze for orchestration and the existing dispatch platform, and add a governed way to evaluate eligibility by geography and time without ripping out tools.
Why It Was Happening
Signals and keys were fragmented. Dispatch defined service zones in polygons and postcodes, while marketing relied on profile addresses or last?known coordinates. Capacity changed on a different cadence than campaign builds. There was no shared eligibility service that both understood geography and enforced a decision at send time. Identity stitching for address, geocode, and account was inconsistent, so suppressions were applied unevenly.
Governance arrived late. Blackouts were encoded in sheets, not in an API. Braze Canvases evaluated static segments rather than live capacity. There was no auditable reason code explaining why a particular household received or did not receive an offer, and no dashboard to show where suppressions should have occurred.
The Solution
We implemented a capacity?aware eligibility layer that sat between dispatch and messaging. The dispatch system exposed a capacity API by zone and time window. Customer addresses were geocoded and stitched to unified profiles. Braze Canvases called a suppression API via webhook with campaign metadata and user location; the API evaluated dispatch capacity and geography rules and returned allow, defer, or suppress. When capacity was tight, Braze either held the message or pivoted to a waitlist or alternate promotion. Nothing was replatformed: dispatch remained the source for capacity, Braze remained the messaging engine, and the new layer standardized geography, timing, and governance.
- Address normalization and geocoding to link profiles to service zones using the Google Maps Geocoding API
- Unified profiles and traits in a Customer Data Platform (CDP) for address, coordinates, and historical eligibility (mParticle)
- Capacity and blackout evaluation exposed as a suppression API behind a gateway with scopes and rate limits (for example, Apigee)
- Braze Canvas webhook steps to request allow/defer/suppress decisions and branch flows accordingly (Braze Canvas, Braze Webhooks)
- Optional template logic using Braze Connected Content to adjust copy for waitlists or nearby availability
- Conformed zone and postcode mappings stored in a warehouse with snapshots and lineage (Snowflake)
- Monitoring and decision logs in dashboards for constraint hits, suppressions, and anomaly detection (Looker)
- Role?based permissions for rule edits and overrides (for example, Okta Groups)
- Human?in?the?loop review for ambiguous geocodes, new zones, and special events with high demand
- Privacy safeguards to minimize and mask PII in location payloads while preserving zone eligibility
Implementation
- Discovery: Mapped dispatch capacity endpoints, blackout logic, and zone definitions. Cataloged how addresses and coordinates were captured in app and web. Reviewed recent promotion misfires with Support and Operations to identify failure patterns by city, time window, and restaurant cluster.
- Design: Authored the eligibility model keyed by zone, postcode, and time buckets. Defined the suppression API contract, reason codes, and fallbacks. Designed geocoding and identity stitching rules, including how to handle last?known location versus address. Planned Braze Canvas branches and template variants for allow, defer, and waitlist responses. Scoped monitoring, audit fields, and role?based overrides.
- Build: Implemented address normalization and geocoding; stitched coordinates and postcodes to CDP profiles; built the suppression API behind an API gateway; integrated Braze Canvas webhooks and Connected Content variants; created zone mapping tables and snapshots in Snowflake; and stood up Looker dashboards for decision logs, constraint hits, and anomalies.
- Testing and QA: Replayed historical promotions against archived capacity to validate that allow/suppress decisions matched human judgment. Simulated edge cases such as rapid zone changes, partial kitchen outages, and user movement across boundaries. Verified webhook timeouts, fallbacks, and privacy masking. Confirmed dashboards displayed reason codes and lineage from dispatch signals to Canvas outcomes.
- Rollout: Ran the suppression service in shadow mode, logging would suppress decisions while campaigns sent as usual. After teams validated behavior, enabled enforcement for high?impact cities and dayparts, then expanded. Kept a manual override lane for special events with rationale and expiry.
- Training and hand?off: Delivered guides for Lifecycle on tagging Canvases and reading suppression dashboards, for Operations on overrides and blackout policies, and for Support on understanding eligibility decisions. Established change control for zone mappings, rule updates, and API scopes.
- Human?in?the?loop review: Routed ambiguous geocodes, new delivery zones, and event?driven exceptions to reviewers in Operations and Marketing. Approved decisions updated mappings and rules to reduce repeat exceptions.
Results
Promotions reflected live capacity. When zones tightened, the suppression service held or swapped messages automatically, and customers in constrained areas saw accurate alternatives or waitlists. Support heard from fewer users about unusable offers, and campaign retros looked at creative and pacing rather than avoidable targeting errors.
Operationally, marketers scheduled without wrestling spreadsheets. Dispatch and Marketing worked from the same zone definitions and reason codes, overrides carried approvals and expiry, and dashboards showed where constraints clustered by time and city. The organization trusted that promotions respected local capacity, and coordination meetings shifted from firefighting to planning.
What Changed for the Team
- Before: Blackouts were shared in spreadsheets and applied manually. After: A suppression API evaluated live capacity and geography at send time.
- Before: Segments were static by postcode. After: Profiles carried normalized addresses and geocodes linked to service zones.
- Before: Messages went out during peak constraints. After: Braze branched on allow/defer/suppress with clear reason codes.
- Before: Overrides were informal. After: Role?based approvals and expiry controlled exceptions and documented rationale.
- Before: Root causes were hard to trace. After: Dashboards tied each decision to dispatch signals, zones, and campaign metadata.
Key Takeaways
- Evaluate eligibility at send time; capacity?aware suppressions prevent mismatched offers when conditions shift.
- Unify geography; normalize addresses and stitch geocodes to service zones so rules apply consistently.
- Coordinate via policy, not spreadsheets; a suppression API and reason codes align Operations and Marketing.
- Instrument outcomes; decision logs and dashboards make tuning straightforward and audits simple.
- Keep the stackdispatch, Braze, CDPand layer orchestration and governance around them rather than replatforming.
FAQ
What tools did this integrate with?
Customer addresses were normalized and geocoded with the Google Maps Geocoding API, then stitched to unified profiles in a CDP such as mParticle. Braze handled orchestration with Canvas and webhook steps (Braze Canvas, Braze Webhooks), and optional Connected Content adjusted copy. Eligibility was served by a suppression API behind an API gateway like Apigee. Zone mappings and decision logs lived in Snowflake and were visualized in Looker.
How did you handle quality control and governance?
We standardized zone and postcode mappings with snapshots and lineage, enforced address normalization and geocoding rules, and required reason codes for every allow/defer/suppress decision. Role?based overrides carried approvals and expiry, and the suppression API applied rate limits and scopes. Dashboards tracked constraint hits, suppression rates, and anomalies, and audit logs tied outcomes to dispatch signals and campaign metadata. Location payloads were minimized and masked to protect PII.
How did you roll this out without disruption?
The suppression service ran in shadow mode at first, logging would suppress outcomes while campaigns ran as planned. After teams compared logs to observed constraints and tuned mappings and rules, we enabled enforcement for selected cities and dayparts, then expanded. A manual override lane remained for special events with documented rationale and expiry.
How did you translate capacity to geography?
Dispatch zones were modeled as polygons and mapped to postcodes and coordinates. Customer addresses were normalized and geocoded, then stitched to the closest eligible zone under defined rules. Where ambiguity existedsuch as addresses near boundaries or recent movesrecords routed to a reviewer and the mapping table captured the decision for future runs.
What happens when capacity changes mid?campaign?
Braze Canvases invoked the suppression API at decision points rather than relying on static segments. If capacity tightened, the next step evaluated the change and deferred or swapped the message automatically. For long?running promotions, a periodic recheck ensured eligibility stayed current, and dashboards highlighted zones with persistent constraints so Marketing could adjust plans.
Department/Function: IT & InfrastructureMarketing & Customer EngagementProcurementSupply Chain & Logistics
Capability: AI Integration & Workflow Automation
Get a FREE
Proof of Concept
& Consultation
No Cost, No Commitment!


