Integrate Drip's e-commerce email automation into Bolt.new apps using their REST API v2 with simple Bearer token authentication. Use a Next.js API route to track e-commerce events (product viewed, cart abandoned, order placed), manage subscribers with tags, and sync customer purchase data. Drip API calls work in Bolt's WebContainer preview. Drip webhooks for automation trigger notifications require a deployed Netlify URL to receive incoming connections.
Add Drip E-commerce Email Automation to Your Bolt.new App
Drip is an email marketing platform purpose-built for e-commerce. Unlike general-purpose email tools, every feature in Drip is designed around the customer purchase lifecycle: identifying potential buyers, engaging them during the consideration phase, recovering abandoned carts, confirming and cross-selling after purchase, and re-engaging lapsed customers. This focus makes Drip particularly powerful for Bolt.new apps that involve selling products or services — the automation capabilities that would require complex custom development in a generic email tool are built-in.
For Bolt developers, Drip's REST API v2 is a well-designed resource. Authentication uses a simple Bearer token — no OAuth flows, no complex signature generation. You get one API token per account from Settings → User Info → API Token. Endpoints follow standard REST conventions: subscribers are managed at `/v2/{account_id}/subscribers`, events are posted to `/v2/{account_id}/events`, and tags are applied via a dedicated endpoint. The straightforward authentication pattern means you can have a working API integration in minutes.
The most powerful pattern is event-driven automation: when a user takes a significant action in your app — views a product, adds something to their cart, or completes a purchase — you record that event in Drip. Drip's automation builder (called Workflows) can then respond to these events: trigger a cart abandonment sequence 4 hours after a cart event with no subsequent purchase event, send a post-purchase review request 7 days after an order event, or tag a user as a high-value customer after their third purchase. This event tracking approach gives you the same email automation capabilities that large e-commerce platforms invest heavily in building.
Integration method
Drip's REST API v2 uses simple Bearer token authentication and supports subscriber management, tag assignment, event tracking, and campaign analytics. All API calls go through a Next.js API route using your Drip API token from server-side environment variables. E-commerce event tracking (product views, cart adds, purchases) sends structured event data to Drip's event endpoint. Drip automation webhooks that notify your app when subscribers complete workflows require a deployed Netlify URL.
Prerequisites
- A Drip account at drip.com — the free plan supports up to 100 subscribers
- A Drip API token found in Settings (gear icon) → User Info → API Token
- Your Drip Account ID from the URL when logged in (e.g., drip.com/account/{accountId}/dashboard) or from Settings → General Settings
- A Bolt.new account with a new Next.js project open
- A Netlify account for deployment if you plan to use Drip webhook automation triggers
Step-by-step guide
Set up Drip API credentials and create the base helper
Set up Drip API credentials and create the base helper
Drip's API v2 uses a combination of a Bearer token for authentication and an Account ID for identifying which Drip account's data to access. Both are needed for every API call. The API token is found in Settings → User Info → API Token, and is a long alphanumeric string. The Account ID appears in the URL when you are in your Drip dashboard: it is the number in `app.getdrip.com/{accountId}/`. Authentication is done via an Authorization header with a Bearer scheme: `Authorization: Bearer YOUR_API_TOKEN`. This is standard and secure — your token never appears in the URL or request body. The base URL for all API calls includes the Account ID: `https://api.getdrip.com/v2/{accountId}/`. Note that the domain is `api.getdrip.com`, not `api.drip.com`. Drip's API rate limit is 3,600 requests per hour per account (1 per second average). For apps with high user activity, implement queuing or batching for non-time-critical operations. However, real-time event tracking (product views, cart adds, purchases) should always go through immediately rather than being batched — the timing of these events is critical for Drip's automation timing calculations. Store DRIP_API_TOKEN (server-side, never NEXT_PUBLIC_) and DRIP_ACCOUNT_ID (can be NEXT_PUBLIC_ since it appears in the URL, but keeping it server-side is cleaner). The API token gives full read/write access to your subscriber database, so it must remain server-side.
Set up Drip API integration. Create .env.local with DRIP_API_TOKEN=your-token and DRIP_ACCOUNT_ID=your-account-id. Create lib/drip.ts with TypeScript interfaces DripSubscriber (email, first_name, last_name, tags, custom_fields as Record<string,string>) and DripEvent (email, action, properties as Record<string,unknown>, occurred_at as optional ISO string). Export functions: upsertSubscriber(email, data), applyTag(email, tag), removeTag(email, tag), trackEvent(email, action, properties), and getSubscriber(email). All functions should use the DRIP_API_TOKEN Bearer auth and DRIP_ACCOUNT_ID in the URL.
Paste this in Bolt.new chat
1// lib/drip.ts2const API_BASE = 'https://api.getdrip.com/v2';34interface DripApiOptions {5 method?: 'GET' | 'POST' | 'PUT' | 'DELETE';6 body?: unknown;7}89async function dripRequest<T>(path: string, options: DripApiOptions = {}): Promise<T> {10 const token = process.env.DRIP_API_TOKEN;11 const accountId = process.env.DRIP_ACCOUNT_ID;12 if (!token || !accountId) throw new Error('DRIP_API_TOKEN and DRIP_ACCOUNT_ID must be set');1314 const url = `${API_BASE}/${accountId}${path}`;15 const response = await fetch(url, {16 method: options.method || 'GET',17 headers: {18 'Authorization': `Bearer ${token}`,19 'Content-Type': 'application/json',20 'User-Agent': 'Bolt.new Integration/1.0',21 },22 ...(options.body ? { body: JSON.stringify(options.body) } : {}),23 });2425 if (response.status === 204) return null as T;26 const data = await response.json();27 if (!response.ok) throw new Error(data.errors?.[0]?.message || `Drip API error: ${response.status}`);28 return data as T;29}3031export async function upsertSubscriber(32 email: string,33 data: {34 firstName?: string;35 lastName?: string;36 customFields?: Record<string, string>;37 tags?: string[];38 } = {}39): Promise<void> {40 await dripRequest('/subscribers', {41 method: 'POST',42 body: {43 subscribers: [{44 email,45 first_name: data.firstName,46 last_name: data.lastName,47 custom_fields: data.customFields,48 tags: data.tags,49 new_email: undefined,50 }],51 },52 });53}5455export async function applyTag(email: string, tag: string): Promise<void> {56 await dripRequest('/tags', {57 method: 'POST',58 body: { tags: [{ email, tag }] },59 });60}6162export async function removeTag(email: string, tag: string): Promise<void> {63 await dripRequest(`/subscribers/${encodeURIComponent(email)}/remove_tag`, {64 method: 'POST',65 body: { tag },66 });67}6869export async function trackEvent(70 email: string,71 action: string,72 properties: Record<string, unknown> = {},73 occurredAt?: string74): Promise<void> {75 await dripRequest('/events', {76 method: 'POST',77 body: {78 events: [{79 email,80 action,81 properties,82 occurred_at: occurredAt || new Date().toISOString(),83 }],84 },85 });86}8788export async function getSubscriber(email: string) {89 const data = await dripRequest<{ subscribers: Array<Record<string, unknown>> }>(90 `/subscribers/${encodeURIComponent(email)}`91 );92 return data?.subscribers?.[0] || null;93}Pro tip: Drip API calls use the domain api.getdrip.com, not api.drip.com — the company rebranded but the API domain remains the legacy domain. The correct base URL is https://api.getdrip.com/v2/{accountId}/. Using api.drip.com will result in connection errors.
Expected result: A lib/drip.ts helper with typed functions for subscriber management, tagging, and event tracking, with credentials configured in .env.local.
Build the e-commerce event tracking API routes
Build the e-commerce event tracking API routes
E-commerce event tracking is Drip's most distinctive capability. When you send structured events to Drip — 'Viewed Product', 'Added to Cart', 'Started Checkout', 'Placed Order' — Drip's automation engine can respond to these events with precisely timed email sequences. The event name becomes the trigger in Drip's visual Workflow builder, and the event properties become personalization variables available in email templates. Drip's recommended e-commerce event taxonomy follows a predictable naming pattern. Use these exact names to ensure compatibility with Drip's built-in e-commerce reporting: 'Viewed a Product', 'Added a Product to the Cart', 'Removed a Product from the Cart', 'Started Checkout', 'Completed a Purchase'. You can also use custom event names for app-specific actions: 'Completed Onboarding', 'Upgraded Plan', 'Invited Team Member'. Event properties are passed as a flat key-value object. For purchase events, include: `order_id`, `grand_total` (in dollars as a number, not cents), `currency` (ISO 4217 code like 'USD'), `total_discounts`, and an `items` array with product details. For product view events: `product_id`, `product_name`, `product_url`, and `price`. These properties populate personalization tokens in Drip email templates — a customer's cart abandonment email can reference the specific product they left behind. Error handling for event tracking should be non-blocking. If Drip is temporarily unavailable or an API call fails, you do not want the failure to cascade into a user-facing error in your app. Wrap event tracking calls in try-catch and log failures without letting them affect the user experience.
Create Drip e-commerce tracking API routes. Create app/api/drip/event/route.ts that accepts POST with: email (required), action (required — event name like 'Placed Order'), properties (optional object), occurredAt (optional ISO string). Call trackEvent from lib/drip.ts and return 200 on success, 400 for missing fields, 500 for API errors. Also create a drip tracking utility at lib/drip-ecommerce.ts that exports specific typed functions: trackProductView(email, productId, productName, price, url), trackCartAdd(email, cartId, productName, price, quantity, total), trackCartAbandonment(email, cartId, items, total), trackPurchase(email, orderId, total, currency, items[]). Each function calls trackEvent with the correct Drip event name and properly structured properties.
Paste this in Bolt.new chat
1// lib/drip-ecommerce.ts2import { trackEvent } from './drip';34interface CartItem {5 productId: string;6 productName: string;7 price: number;8 quantity: number;9}1011export async function trackProductView(12 email: string,13 productId: string,14 productName: string,15 price: number,16 url: string17): Promise<void> {18 await trackEvent(email, 'Viewed a Product', {19 product_id: productId,20 product_name: productName,21 price,22 product_url: url,23 });24}2526export async function trackCartAdd(27 email: string,28 cartId: string,29 productName: string,30 price: number,31 quantity: number,32 cartTotal: number33): Promise<void> {34 await trackEvent(email, 'Added a Product to the Cart', {35 cart_id: cartId,36 product_name: productName,37 price,38 quantity,39 cart_total: cartTotal,40 });41}4243export async function trackCartAbandonment(44 email: string,45 cartId: string,46 items: CartItem[],47 total: number48): Promise<void> {49 await trackEvent(email, 'Abandoned a Cart', {50 cart_id: cartId,51 total,52 item_count: items.reduce((sum, item) => sum + item.quantity, 0),53 items: items.map((item) => ({54 product_id: item.productId,55 product_name: item.productName,56 price: item.price,57 quantity: item.quantity,58 })),59 });60}6162export async function trackPurchase(63 email: string,64 orderId: string,65 total: number, // in dollars, not cents66 currency: string,67 items: CartItem[]68): Promise<void> {69 await trackEvent(email, 'Placed Order', {70 order_id: orderId,71 grand_total: total,72 currency,73 item_count: items.reduce((sum, item) => sum + item.quantity, 0),74 items: items.map((item) => ({75 product_id: item.productId,76 product_name: item.productName,77 price: item.price,78 quantity: item.quantity,79 })),80 });81}Pro tip: Send purchase amounts to Drip in dollars (or your currency unit), not in cents. Drip's revenue reporting displays values as-is, so passing 9999 (Stripe's cent representation of $99.99) will show as $9,999 in Drip's revenue dashboard. Divide Stripe cent amounts by 100 before passing to Drip.
Expected result: Typed e-commerce tracking functions for the main customer lifecycle events, ready to call from your Stripe webhook handler and app event handlers.
Integrate Drip tracking with Stripe checkout and user signup
Integrate Drip tracking with Stripe checkout and user signup
The two most critical integration points for e-commerce email automation are the post-purchase event (to start fulfillment sequences and cross-sell flows) and the new subscriber event (to start welcome or onboarding sequences). Both should happen as close to real-time as possible — Drip's automation timing is relative to when events are received. For Stripe integration, the cleanest approach is to add Drip event tracking to your existing Stripe webhook handler. After successfully processing a `checkout.session.completed` event (verifying the signature, updating your database), call `trackPurchase()` with the customer's email, order ID, and line item data. Drip receives the event within seconds and can start the post-purchase sequence immediately. For user signup, call `upsertSubscriber()` immediately after creating the user in Supabase. Pass the user's name and any plan information as subscriber properties and custom fields. Drip creates the subscriber record and any automations triggered by 'subscriber created' events begin running. Error handling is critical at these integration points: a failed Drip API call must never prevent a Stripe payment from being acknowledged or a new user from being created. Always wrap Drip calls in try-catch inside your Stripe webhook handler and signup route, log the error, and continue processing. An unhandled Drip error causing a 500 response from your Stripe webhook would cause Stripe to retry the payment event, potentially double-processing orders.
Integrate Drip tracking with Stripe and user signup. In my Stripe webhook handler at app/api/stripe/webhook/route.ts, after processing checkout.session.completed successfully, add a try-catch call to trackPurchase from lib/drip-ecommerce.ts using the session's customer_email, payment_intent as order_id, amount_total divided by 100 as total, and currency. Also upsertSubscriber with the email and tag 'customer'. In my Supabase signup handler (or wherever new users are created), add a try-catch call to upsertSubscriber with firstName, lastName, and a tag matching their plan tier ('free-trial', 'pro', etc.). Log Drip errors with console.error but do not rethrow — Drip failures should never break core app functionality.
Paste this in Bolt.new chat
1// Integration example: adding Drip to an existing Stripe webhook handler2// In your existing app/api/stripe/webhook/route.ts:3import { trackPurchase } from '@/lib/drip-ecommerce';4import { upsertSubscriber, applyTag } from '@/lib/drip';56// Inside your checkout.session.completed handler:7async function handleCheckoutCompleted(session: Stripe.Checkout.Session) {8 const email = session.customer_details?.email || session.customer_email;9 if (!email) return;1011 // Your existing logic: update database, fulfill order, etc.12 // ...1314 // Track purchase in Drip (non-blocking — errors do not affect Stripe processing)15 try {16 await trackPurchase(17 email,18 session.payment_intent as string || session.id,19 (session.amount_total || 0) / 100, // Convert cents to dollars20 session.currency || 'usd',21 [] // Map line items from session.line_items if available22 );23 await applyTag(email, 'customer');24 } catch (dripError) {25 console.error('Drip tracking failed (non-critical):', dripError);26 // Do not rethrow — Stripe webhook must return 20027 }28}2930// Integration example: adding Drip to user signup31async function onUserSignup(32 email: string,33 firstName: string,34 lastName: string,35 plan: 'free' | 'pro' | 'enterprise'36) {37 // Your existing logic: create Supabase user, etc.38 // ...3940 // Subscribe to Drip (non-blocking)41 try {42 await upsertSubscriber(email, {43 firstName,44 lastName,45 tags: [plan === 'free' ? 'free-trial' : 'customer'],46 customFields: { plan_tier: plan, signup_date: new Date().toISOString() },47 });48 } catch (dripError) {49 console.error('Drip subscribe failed (non-critical):', dripError);50 }51}Pro tip: In Drip's Workflow builder, you can reference event properties in email content using Liquid-style tags: {{ event.properties.product_name }}, {{ event.properties.grand_total }}. Structure your event property names to be readable and consistent across your app's events, since they become template variables in Drip email content.
Expected result: Drip event tracking wired into Stripe checkout and user signup flows, with error isolation ensuring Drip failures never break core app functionality.
Deploy to Netlify and configure Drip webhook notifications
Deploy to Netlify and configure Drip webhook notifications
Drip API calls for event tracking, subscriber management, and tagging all work in Bolt.new's WebContainer during development — these are outbound HTTP requests that the browser-based runtime supports. You can build and test all of the e-commerce tracking features in the Bolt preview before deploying. Deployment to Netlify is required for your .env.local credentials to be available in production and for any Drip webhook features you want to implement. Drip can send webhook notifications to your app when subscribers complete automation workflows, receive emails, or perform other tracked actions. To deploy: click Deploy in Bolt.new, authorize Netlify, and wait for the initial build. In the Netlify dashboard, go to Site Configuration → Environment Variables and add: DRIP_API_TOKEN and DRIP_ACCOUNT_ID. If your app uses Stripe and Supabase, also add those environment variables. Trigger a redeploy. For Drip webhooks: in Drip, go to Settings → Webhooks (or integrate through Drip's Zapier integration for simpler setup). Create a webhook pointing to your Netlify URL: https://your-app.netlify.app/api/drip/webhook. Select events to receive — subscriber.created, subscriber.subscribed_to_workflow, subscriber.unsubscribed, etc. This is a fundamental WebContainer limitation: Bolt's browser-based runtime has no persistent public URL and cannot receive incoming HTTP POST requests. Drip webhook delivery from Drip's servers to your app requires a deployed, publicly accessible endpoint.
Create a Drip webhook handler at app/api/drip/webhook/route.ts. Accept POST from Drip. The payload contains event (string) and data (object). Handle: subscriber.created (log email), subscriber.subscribed_to_workflow (log workflow name), subscriber.performed_custom_event (log event action and email), subscriber.unsubscribed (log email, TODO comment to update Supabase). Return 200 for all events. Add a note that this endpoint requires a deployed URL. Also create netlify.toml with Next.js build configuration.
Paste this in Bolt.new chat
1// app/api/drip/webhook/route.ts2// NOTE: Drip webhooks require a publicly accessible URL.3// This route cannot receive events in Bolt's WebContainer preview.4// Deploy to Netlify first, then register your URL in Drip Settings → Webhooks.5import { NextRequest, NextResponse } from 'next/server';67interface DripWebhookPayload {8 event: string;9 data: {10 account_id: string;11 subscriber?: {12 email: string;13 id: string;14 first_name: string;15 last_name: string;16 tags: string[];17 custom_fields: Record<string, string>;18 };19 workflow?: { name: string; id: string };20 occurred_at: string;21 };22}2324export async function POST(request: NextRequest) {25 let payload: DripWebhookPayload;26 try {27 payload = await request.json();28 } catch {29 return NextResponse.json({ error: 'Invalid JSON' }, { status: 400 });30 }3132 const { event, data } = payload;33 const email = data.subscriber?.email;3435 switch (event) {36 case 'subscriber.created':37 console.log(`Drip: New subscriber — ${email}`);38 break;3940 case 'subscriber.subscribed_to_workflow':41 console.log(`Drip: ${email} entered workflow '${data.workflow?.name}'`);42 break;4344 case 'subscriber.performed_custom_event':45 console.log(`Drip: Custom event for ${email}`);46 break;4748 case 'subscriber.unsubscribed':49 console.log(`Drip: Unsubscribe — ${email}`);50 // TODO: Update subscriber status in Supabase51 break;5253 default:54 console.log(`Drip unhandled webhook event: ${event}`);55 }5657 return NextResponse.json({ received: true });58}Pro tip: Drip sends all webhook events as individual POST requests — unlike some platforms that batch events, each Drip event results in a separate webhook call. If you are tracking high-volume events like product views and your automation workflows send webhooks, ensure your webhook handler is lightweight and responds quickly to avoid timeout issues.
Expected result: A deployed Netlify app with Drip event tracking working in production and a webhook handler receiving automation notifications.
Common use cases
Post-Purchase Email Automation Trigger
After a successful Stripe checkout, record the purchase event in Drip with the order value and product details. Drip's automation workflow starts a post-purchase email sequence: immediate order confirmation, 3-day delivery follow-up, 7-day review request, and 30-day re-engagement. All triggered by the single purchase event from your API.
After a successful Stripe checkout.session.completed webhook, trigger Drip post-purchase automation. In my Stripe webhook handler, after processing the payment, call a new trackDripPurchase(email, orderData) function. This function should call POST /api/drip/event with event name 'Placed Order' and properties: order_id, total (in dollars, not cents), currency, and an items array. Use DRIP_API_TOKEN and DRIP_ACCOUNT_ID env vars. Also subscribe the customer's email to Drip if they are not already subscribed, and add the tag 'customer'. Return success even if Drip fails so Stripe processing continues.
Copy this prompt to try it in Bolt.new
Cart Abandonment Recovery Flow
Track when users add items to their cart in your app but do not complete checkout. Send the cart data to Drip, which triggers a 3-email recovery sequence at 1 hour, 24 hours, and 72 hours after abandonment. When the user eventually purchases, record the order event to suppress the sequence.
Implement cart abandonment tracking. Create an API route at app/api/drip/cart/route.ts that accepts POST with email, cart_id, items (array of {name, price, quantity}), and total fields. Call Drip's event API with event name 'Added to Cart' and the cart data as properties. Also record cart_total as a subscriber property for segmentation. Create a CartTracker React component that calls this API route whenever the cart contents change (using useEffect with cart as dependency). If the user subsequently completes an order, call the API with event name 'Placed Order' to stop the abandonment sequence in Drip.
Copy this prompt to try it in Bolt.new
Subscriber Lifecycle Tagging
Automatically apply Drip tags based on user behavior and subscription tier in your app. Tag free users as 'free-trial', tag paying customers as 'customer', tag users who have been inactive for 30 days as 'at-risk', and tag churned users as 'churned'. Each tag triggers a different Drip automation: upgrade prompts for trial users, retention emails for at-risk users, win-back sequences for churned users.
Create a Drip subscriber tagging system. Build a lib/drip.ts helper with functions: applyTag(email, tag), removeTag(email, tag), subscriberExists(email), and upsertSubscriber(email, properties). Call these from my app's lifecycle events: when a user activates a paid subscription call applyTag(email, 'customer') and removeTag(email, 'free-trial'), when their subscription expires call applyTag(email, 'churned') and removeTag(email, 'customer'), when they have not logged in for 30 days call applyTag(email, 'at-risk'). Use DRIP_API_TOKEN and DRIP_ACCOUNT_ID env vars.
Copy this prompt to try it in Bolt.new
Troubleshooting
Drip API returns 401 Unauthorized — requests return empty body or authentication error
Cause: The API token is incorrect, stored in the wrong environment variable, or being passed in the wrong header format. Drip uses Bearer token authentication in the Authorization header — not Basic auth or API key query parameter.
Solution: Verify the API token is the full string from Settings → User Info → API Token. Ensure it is stored as DRIP_API_TOKEN (not NEXT_PUBLIC_DRIP_API_TOKEN). The Authorization header format must be exactly: 'Bearer YOUR_TOKEN' with a space between Bearer and the token. Also verify your Account ID is correct in DRIP_ACCOUNT_ID.
1headers: {2 'Authorization': `Bearer ${process.env.DRIP_API_TOKEN}`,3 'Content-Type': 'application/json',4}Purchase amounts appear 100x larger than expected in Drip revenue reports
Cause: Stripe amounts are in the smallest currency unit (cents for USD). Passing Stripe's amount_total directly to Drip without dividing by 100 sends the value in cents, which Drip displays as dollars.
Solution: Always divide Stripe amount_total by 100 before passing to Drip's trackPurchase function. Stripe's amount_total for a $99.99 order is 9999 (cents). Drip should receive 99.99 (dollars). The same applies to any other Stripe amount field: amount_subtotal, amount_shipping, etc.
1// Correct: divide by 1002await trackPurchase(email, orderId, session.amount_total / 100, session.currency, items);34// Wrong: passing cents directly5await trackPurchase(email, orderId, session.amount_total, session.currency, items);Events are tracked successfully but Drip automation workflows are not triggering
Cause: The event action name does not exactly match the trigger configured in the Drip Workflow. Drip's workflow triggers are case-sensitive and must match the event action string exactly. Also, the subscriber must exist in Drip before event-triggered workflows fire.
Solution: In Drip's Workflow builder, check the exact action name used as the trigger (e.g., 'Placed Order'). Ensure the event action you send via the API matches exactly — including capitalization and spacing. Also verify the subscriber exists in Drip before the event — if the subscriber was never added to Drip, events logged for their email will not trigger workflows. Call upsertSubscriber before trackEvent for new users.
Drip webhook events are not being received during Bolt.new development
Cause: Drip sends webhook POST requests to a specified URL. Bolt.new's WebContainer has no persistent public URL — it runs inside a browser tab and cannot receive incoming HTTP connections. The preview URL changes per session and cannot be registered as a webhook endpoint.
Solution: Deploy to Netlify and register your Netlify URL in Drip Settings → Webhooks. Drip webhooks cannot be tested against a Bolt.new WebContainer preview URL. This is a core WebContainer limitation. After deploying, you can also test the webhook endpoint manually by using Drip's webhook test delivery feature.
Best practices
- Always divide Stripe cent amounts by 100 before passing monetary values to Drip — Drip displays values as-is in revenue reports and using cents produces misleading numbers
- Wrap all Drip API calls in try-catch blocks and log errors without rethrowing — Drip failures should never cascade into user-facing errors or break Stripe webhook processing
- Send purchase amounts to Drip immediately when payment is confirmed — Drip's cart abandonment suppression relies on receiving 'Placed Order' events before the abandonment timer fires
- Use consistent event action names across your app — create a constants file with event name strings to avoid typos that break automation workflow triggers
- Upsert subscribers before tracking events for new users — Drip automation workflows may not trigger for events from emails not yet in your Drip account
- Test Drip event tracking in the Bolt.new WebContainer preview before deploying — outbound API calls to Drip work in the preview, letting you verify event data structure
- Set up Drip's custom fields for app-specific data (plan tier, signup date, feature usage) at subscriber creation time — this data is available for segmentation in Drip's workflow conditions
- Deploy to Netlify before configuring Drip webhooks — webhook delivery requires a publicly accessible URL that the WebContainer cannot provide
Alternatives
Klaviyo has better native Shopify integration and more advanced segmentation capabilities — better for Shopify-based stores, while Drip is easier to integrate with custom Bolt.new e-commerce apps.
ConvertKit is optimized for creator and content businesses rather than product e-commerce — better for bloggers and course creators, while Drip is purpose-built for online store customer lifecycle automation.
Mailchimp is a general-purpose email marketing platform with e-commerce features added on — Drip's e-commerce automation is more focused and the event tracking integration is cleaner for product-based apps.
AWeber focuses on reliable email delivery and simple automation without the e-commerce event tracking depth that Drip provides — better for simple newsletter sends than for purchase lifecycle automation.
Frequently asked questions
Can Drip API calls work in Bolt.new's WebContainer during development?
Yes. Drip API calls are outbound HTTP requests from your Next.js API routes — these work perfectly in Bolt's WebContainer preview. You can test subscriber creation, event tracking, and tag assignment during development. The only Drip feature requiring deployment is webhook delivery, which needs a publicly accessible URL to receive POST requests from Drip's servers.
Does Drip work well with Stripe for e-commerce tracking?
Yes — combining Drip's event tracking with Stripe's webhook events is the most common integration pattern. Process Stripe checkout.session.completed webhooks to confirm payment, then immediately call trackPurchase() to send the order event to Drip. This triggers Drip's post-purchase automation sequence. Remember to divide Stripe's cent amounts by 100 before sending to Drip.
What is the correct API domain for Drip — drip.com or getdrip.com?
The API uses api.getdrip.com — the legacy domain. Despite the company rebranding from GetDrip to Drip, the API base URL remains https://api.getdrip.com/v2/. Using api.drip.com will fail. The Drip dashboard is at app.getdrip.com. This is documented in Drip's API documentation.
How is Drip different from Klaviyo for e-commerce email automation?
Both platforms focus on e-commerce email automation with purchase event tracking and customer lifecycle sequences. Klaviyo has deeper native integration with Shopify and more granular e-commerce analytics with product-level attribution. Drip is generally easier to integrate with custom-built Bolt.new apps through its REST API, and its pricing is more straightforward for growing stores. For Shopify stores, Klaviyo is often preferred. For custom-built apps, Drip's API integration is simpler.
Can I use Drip's free plan with my Bolt.new e-commerce app?
Drip's free plan supports up to 100 subscribers. For most early-stage apps, this is sufficient for building and testing the integration. When you exceed 100 subscribers, pricing starts at around $39/month for up to 2,500 subscribers. Drip does not have a free plan with higher limits — if you need to grow beyond 100 subscribers for free, consider ConvertKit (1,000 subscribers free) or Mailchimp (500 contacts free).
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation