Wraps Logo
Guide

Custom Events

Emit events from your application to trigger workflows, track contact activity, and resume waiting automation steps.

5 min read

Overview

Custom events let you send signals from your application to the Wraps platform. When an event is received, three things happen:

Stored

The event is recorded on the contact's timeline with a 2-year TTL.

Workflows triggered

Any enabled workflow with an event.received trigger matching this event name starts a new execution.

Waiting steps resumed

Any workflow execution waiting for this event on this contact resumes down the “yes” branch.

Sending an Event

Use client.track() from the @wraps.dev/client SDK to send events with full type safety.

TypeScriptsend-event.ts
import { createPlatformClient } from '@wraps.dev/client';const client = createPlatformClient({  apiKey: process.env.WRAPS_API_KEY,});const result = await client.track('purchase.completed', {  contactEmail: 'alice@example.com',  properties: {    orderId: 'ord_12345',    amount: 99.00,    plan: 'pro',  },});// { success: true, contactCreated: false, workflowsTriggered: 1, executionsResumed: 0 }

Track Options

FieldTypeRequiredDescription
namestringYesFirst argument to track(). Event name, e.g. purchase.completed. Max 255 chars.
contactIdstringOne of contactId or contactEmailContact ID to associate the event with.
contactEmailstringAlternative to contactIdLook up the contact by email address.
contactNamestringNoSets firstName when createIfMissing creates a new contact.
createIfMissingbooleanNoIf true and the contact doesn't exist, create one from contactEmail. Defaults to false.
propertiesobjectNoArbitrary key-value data attached to the event. Passed to workflows as event data.

Auto-Creating Contacts

Set createIfMissing: true to create a new contact when one doesn't exist. Requires contactEmail. The response includes contactCreated: true when a contact was created.

TypeScriptcreate-if-missing.ts
await client.track('signup.completed', {  contactEmail: 'new-user@example.com',  contactName: 'Alice',  createIfMissing: true,  properties: {    source: 'website',    referrer: 'producthunt',  },});

Tip: This is useful for signup flows where the contact may not exist in Wraps yet. The event fires, the contact is created, and any matching workflows start immediately.

Batch Events

Send multiple events in a single request with client.trackBatch(). Contact resolution, workflow matching, and execution resumption are all batched for efficiency.

TypeScriptbatch-events.ts
const result = await client.trackBatch([  {    name: 'page.viewed',    contactEmail: 'alice@example.com',    properties: { page: '/pricing' },  },  {    name: 'page.viewed',    contactEmail: 'bob@example.com',    properties: { page: '/docs' },  },  {    name: 'feature.used',    contactId: 'con_abc123',    properties: { feature: 'api-keys' },  },]);// { success: true, processed: 3, workflowsTriggered: 0, executionsResumed: 0, errors: [] }

Note: Batch does not support createIfMissing. Contacts must already exist when using the batch endpoint.

How Events Connect to Workflows

Events integrate with workflows in two ways:

1. Trigger new workflows

Create a workflow with the event.received trigger type and set the event name to match. When the event fires for a contact, a new workflow execution begins.

The event's properties are passed as event data and available in workflow step conditions.

2. Resume waiting steps

Workflows can include a “Wait for Event” step that pauses execution until a specific event is received for that contact. When the matching event arrives, execution resumes down the “yes” branch. If the timeout expires first, it takes the “no” branch.

Event Limits

Tracked events are metered per organization per month with a 25% grace period.

PlanMonthly limitHard cap (125%)
Starter50,00062,500
Growth250,000312,500
Scale1,000,0001,250,000
EnterpriseUnlimited

Examples

Next.js checkout handler

Emit an event after processing a payment to kick off a post-purchase workflow.

TypeScriptapp/api/checkout/route.ts
// app/api/checkout/route.tsimport { createPlatformClient } from '@wraps.dev/client';import { NextResponse } from 'next/server';const client = createPlatformClient({  apiKey: process.env.WRAPS_API_KEY,});export async function POST(request: Request) {  const { email, plan, orderId } = await request.json();  // ... process payment ...  // Emit event to trigger post-purchase workflow  await client.track('purchase.completed', {    contactEmail: email,    createIfMissing: true,    properties: { plan, orderId },  });  return NextResponse.json({ success: true });}

Stripe webhook handler

Forward Stripe subscription events to Wraps for lifecycle automation.

TypeScriptapp/api/stripe-webhook/route.ts
// app/api/stripe-webhook/route.tsimport { createPlatformClient } from '@wraps.dev/client';import { NextResponse } from 'next/server';const client = createPlatformClient({  apiKey: process.env.WRAPS_API_KEY,});export async function POST(request: Request) {  const event = await request.json();  switch (event.type) {    case 'customer.subscription.created':      await client.track('subscription.created', {        contactEmail: event.data.object.customer_email,        createIfMissing: true,        properties: {          plan: event.data.object.items.data[0].price.id,          stripeCustomerId: event.data.object.customer,        },      });      break;    case 'customer.subscription.deleted':      await client.track('subscription.cancelled', {        contactEmail: event.data.object.customer_email,        properties: {          cancelReason: event.data.object.cancellation_details?.reason,        },      });      break;  }  return NextResponse.json({ received: true });}

Event Naming Conventions

Use dot-separated resource.action names. Keep them lowercase and consistent across your application.

EventUse case
signup.completedUser finished onboarding
purchase.completedOrder placed successfully
subscription.cancelledUser cancelled their plan
feature.usedSpecific feature was activated
trial.expiringTrial ends within 3 days
invoice.paidPayment processed successfully

Next Steps

Building Workflows

Create automation workflows that trigger on your custom events.

Workflow guide
Webhooks

Receive real-time delivery events at your HTTPS endpoint.

Webhooks guide