Hooks API
Web HookSendEvent1
Receive customer events such as points updates, tier changes, and achievements for integration with external systems.
| Kind | Mutation Hook |
|---|---|
| Method | POST |
| URL | The webhook URL you specify, with :name replaced by SendEvent1 |
| Authentication | JWT HS256 Bearer token |
The SendEvent1 hook allows your system to receive real-time notifications about customer loyalty events. These events are queued and sent asynchronously via webhooks, with built-in retry logic for transient failures.
Common Use Cases
- Sync loyalty data to marketing automation platforms (Klaviyo, Mailchimp, etc.)
- Trigger personalized campaigns based on tier achievements
- Update external CRM systems with customer loyalty status
- Send transactional notifications for points earned or redeemed
- Track customer engagement metrics in analytics platforms
Event Processing
Events are processed asynchronously through a queue system. When an event occurs in Bubblehouse: 1) The event is added to a queue for each configured integration. 2) A background job periodically processes the queue. 3) Your webhook endpoint is called with the event data. 4) Based on your response, the event is either marked complete or failed.
Retry Behavior
The outcome field in your response controls how Bubblehouse handles the event: Success outcomes (removed from queue): sent, skipped. Permanent failures (removed from queue): invalid_data, unsubscribed. Temporary failures (hold the queue and to retry): failure or HTTP errors, these are assumed to be not specific to a particular event, and thus hold the entire queue.
Important Notes
- Events are sent in near real-time but delivery is best-effort and not guaranteed to be immediate
- Your endpoint should respond quickly (within 30 seconds) to avoid timeouts
- Events will be delivered in order during retries (which necessitates stopping the queue when sending fails)
- Network errors and retries might cause the same event to be sent more than once; use the bhid (Bubblehouse ID) field to detect duplicate events
- Customer properties include all loyalty-related data prefixed with "BH_"
Input
-
Unique Bubblehouse event identifier that can be used for deduplication.
-
Timestamp when the event occurred.
-
namestring requiredHuman-readable event name.
Common event names include:
"Points Updated" - Customer's point balance changed
"Points Earned" - Points were added to customer's balance
"Points Redeemed" - Points were spent on a reward
"Points Expired" - Points expired based on expiration rules
"Tier Reached" - Customer achieved a new tier
"Asset Unlocked" - Achievement was unlocked
"Vendible Redeemed" - Customer redeemed a vendible reward
"Referral Approved (Sender)", "Referral Approved (Receiver)" - Referral was successfully completed
"Birthday" - Customer's birthday event
"Anniversary" - Customer's membership anniversary
-
customerCustomerIdentityWithName1 requiredCustomer identification and name information.
Contains the following fields:
bhid- Bubblehouse customer IDshopid- Your ecommerce platform's customer IDemail- Customer email addressfirst_name- Customer's first namelast_name- Customer's last namefull_name- Customer's full name -
customer_propsmap optionalCustomer loyalty properties and attributes.
Contains comprehensive customer data including:
BH_Points_Balance- Current point balanceBH_Points_NextExpiration_AmountandBH_Points_NextExpiration_Date- Points expiring soonBH_Tier- Current tier nameBH_MagicLink- Magic login link if enabledand many others
plus custom attributes configured for your tenant
-
segment_propsmap optionalEvent-specific segmentation properties.
Contains data specific to the event type, which can be used for indexing and segmentation. For example:
For
Points Earnedevent:BH_SourceFor
Tier Reachedevent:BH_Tier(new tier name)For
Achievement Unlockedevent:BH_Achievement(achievement name)For
Referred (Receiver)event:BH_Channel,BH_HasCoupon -
extra_propsmap optionalAdditional event-specific properties.
Contains data specific to the event type that should not be indexed (e.g. names, coupon codes, URLs), for example:
For
Points Earnedevent:BH_PointsFor
Tier Reachedevent:BH_Reward_CouponFor
Referred (Receiver)event:BH_Sender_FirstName,BH_Sender_Email,BH_LinkMany services don't distinguish between segmented and non-segmented event properties; if you don't care about the difference, treat this as an extension of
segment_props. -
new_userboolean optionalTrue if this is expected to be a new customer (i.e. is a referral event send to the person being referred).
-
referred_userboolean optionalTrue if this is one of referral events sent to the customer being referred.
Unlike
new_user, this one is also true for referral approval events, by which time the customer should no longer be new. -
customer_onlyboolean optionalTrue if this event only updates customer properties without representing an actual event.
When true, treat this as a customer profile update rather than an activity event. Useful for syncing customer data without triggering event-based automations. You can ignore the event name.
Output
-
outcomeSendEventOutcome requiredResult of processing the event, controlling retry behavior.
Must be one of the following values:
"sent"- Event successfully processed and sent to destination"skipped"- Event intentionally not processed (e.g., filtered by rules)"invalid_data"- Event contains invalid data that cannot be processed"unsubscribed"- Customer has opted out of receiving events"failure"- Temporary failure, event should be retriedThe outcome determines whether the event is removed from the queue (sent, skipped, invalid_data, unsubscribed) or kept for retry (failure).
Usage Examples
Webhook Handler Implementation
Here's an example Express.js webhook handler that processes SendEvent1 notifications:
Request
{
"bhid": "24a5be6c83010001",
"customer": {
"bhid": "24760933ea010001",
"email": "customer@example.com",
"first_name": "Jane",
"last_name": "Doe",
"shopid": "12345"
},
"customer_props": {
"BH_Points_Balance": 500,
"BH_Tier": "Gold"
},
"extra_props": {
"BH_Points": 50,
"order_id": "ORDER-789"
},
"name": "Points Updated",
"segment_props": {
"BH_Source": "order"
},
"time": "2024-12-26T18:05:42.915Z"
}
Implementation
// Example webhook handler
app.post('/webhook/SendEvent1', async (req, res) => {
const event = req.body;
// Validate event data
if (!event.customer.email && !event.customer.shopid) {
// Missing required customer identifier
return res.json({ outcome: 'invalid_data' });
}
// Check if customer is subscribed
const isSubscribed = await checkSubscriptionStatus(event.customer.email);
if (!isSubscribed) {
return res.json({ outcome: 'unsubscribed' });
}
// Process based on event type
switch (event.name) {
case 'Points Updated':
await updateCustomerPoints(event.customer, event.segment_props, event.extra_props);
res.json({ outcome: 'sent' });
break;
case 'Tier Reached':
await triggerTierCampaign(event.customer, event.segment_props, event.extra_props);
res.json({ outcome: 'sent' });
break;
default:
return res.json({ outcome: 'skipped' });
}
});
Response
{
"outcome": "sent"
}
The handler validates the incoming data, checks subscription status, and processes different event types. It returns appropriate outcome codes based on the processing result.