Hogsend
Compare

Migration Guide

How to move your lifecycle email automation to Hogsend from Customer.io, Loops, Brevo, ActiveCampaign, or a custom setup.

Moving to Hogsend from another platform is more of a "rewrite the good parts" exercise than a traditional migration. Because Hogsend is code-first, you're translating your existing automation logic into TypeScript rather than importing configuration files. The upside is that your journeys usually come out cleaner and more maintainable on the other side.

What migrates

Contacts. Export your contact list from your current platform as CSV or JSON. Hogsend's bulk import endpoint (POST /v1/admin/contacts/import) accepts both formats. Map your fields to Hogsend's contact schema: externalId, email, properties (a JSON object for everything else). Most platforms export in a format that maps cleanly.

Email templates. You'll rewrite these as React Email components, not import them. This sounds like more work than it is -- React Email templates are typically shorter and more maintainable than the markup most platforms export. The templates live in packages/email/ as .tsx files with typed props, which means your editor catches mistakes before they reach a user's inbox.

Journey logic. This is the core of the migration. Each visual workflow or automation rule in your current platform becomes a defineJourney() call in TypeScript. The translation is usually straightforward: "wait 2 days" becomes ctx.sleep({ duration: days(2) }), "check if user did X" becomes ctx.history.hasEvent(), and branching logic becomes if/else statements.

What doesn't migrate

Historical email analytics. Open rates, click rates, delivery stats, and engagement history from your previous platform stay there. Hogsend starts tracking from the first email it sends. If you need historical data for reference, keep read access to your old platform for a while.

Platform-specific integrations. If your current platform has deep integrations with tools that Hogsend doesn't connect to yet (e.g., a CRM sync, a landing page builder, SMS delivery), you'll need to either create a Hogsend plugin for that service or handle it outside Hogsend.

Visual workflow exports. There's no way to import a Customer.io or ActiveCampaign workflow file directly. The migration is a manual translation -- but it's also a good opportunity to simplify flows that have accumulated cruft over time.

From Customer.io

Customer.io is the most common platform teams migrate from, usually because of pricing.

1. Export contacts

Use Customer.io's People export to download your contacts as CSV. Map the fields:

Customer.io fieldHogsend field
id or cio_idexternalId
emailemail
Custom attributesproperties (JSON object)

Import via the bulk endpoint:

curl -X POST https://your-hogsend.example.com/v1/admin/contacts/import \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d @contacts.json

2. Translate workflows

Each Customer.io campaign or workflow becomes a journey file. The mapping is usually direct:

Customer.io conceptHogsend equivalent
Trigger (event-based)trigger: { event: "your_event" }
Filter / segment conditiontrigger.where conditions
Wait stepctx.sleep({ duration: days(n) })
Branch (if/else)TypeScript if/else
Send email actionsendEmail({ ... })
Goal / conversionexitOn: [{ event: "goal_event" }]
Frequency capentryLimit + suppress

3. Map events

If you're already on PostHog, your events are already flowing. Point your PostHog webhook at Hogsend's ingest endpoint and the events Customer.io was receiving will now route to Hogsend journeys.

If Customer.io was receiving events directly from your app (not via PostHog), update your app's event calls to either send to PostHog (recommended) or directly to Hogsend's ingest endpoint.

From Loops, Brevo, or ActiveCampaign

The process is the same pattern regardless of the source platform:

1. Export contacts

Every platform has a contact export feature. Download as CSV, map to Hogsend's schema (externalId, email, properties), and import via the bulk endpoint.

2. Rewrite journeys

Open each automation or flow in your current platform and translate it to a defineJourney() call. Focus on the logic, not the UI representation. A 20-node visual workflow often collapses into 30--50 lines of TypeScript because most of the "nodes" are just wait steps and conditionals.

3. Rebuild templates

Create React Email templates in packages/email/. The existing templates in the codebase show the pattern -- a .tsx file that exports a component with typed props. Register it in the template map and reference it by key in your journey's sendEmail() calls.

4. Connect events

Point your event source (PostHog webhook, Stripe webhook, custom API calls) at Hogsend's ingest endpoint. If you're coming from a platform that was receiving events directly from your app, consider routing through PostHog first so you get both analytics and automation from a single event stream.

The PostHog advantage

If you're already on PostHog, the hardest part of setting up lifecycle automation is already done.

Event instrumentation -- deciding what to track, adding tracking calls, making sure data is clean -- is where most teams spend the majority of their setup time with any automation platform. With PostHog already in place, Hogsend just listens to events you're already capturing. The user_signed_up event that feeds your PostHog funnel is the same event that triggers your Hogsend welcome sequence. No duplicate instrumentation, no keeping two event schemas in sync.

PostHog person properties are also available in Hogsend via the @hogsend/plugin-posthog package, with Redis caching. Your journeys can branch based on the same properties you see in PostHog -- plan type, feature usage, company size, whatever you're tracking.

Or build on top

Hogsend is a platform, not a product. The two built-in plugins -- @hogsend/plugin-posthog and @hogsend/plugin-resend -- show the pattern for extending it.

Need Slack notifications when a high-value user enters a churn flow? Create @hogsend/plugin-slack. Want to send SMS via Twilio when a payment fails? Create @hogsend/plugin-twilio. Need to sync contacts to your CRM? Create a plugin that pushes updates on contact changes.

Each plugin is a self-contained package with a client, a service, and typed exports. The Creating Plugins guide walks through the full process. Your plugins live in your repo, deploy with your code, and can be used directly in any journey as a standalone import.

The migration doesn't have to be a one-time event. Start with email, get your core journeys running, then extend into other channels and integrations as you need them. The codebase is yours to grow.

On this page