How to Capture Event Sign-Ups from Forwarded Emails into Klaviyo

Forward registration confirmation emails to a Spojit Mailhook, let an Agent-mode Connector node pull out the attendee details, and create or update a Klaviyo profile plus a sign-up event so your marketing flows can react in real time.

What This Integration Does

Event registrations often arrive as confirmation emails from a ticketing platform, an Eventbrite-style tool, or a webinar provider. Those emails carry the attendee name, email address, ticket type, and event name, but that data is locked inside free-form HTML and never reaches your marketing platform. This workflow turns each forwarded confirmation into a clean Klaviyo profile and a tracked sign-up event, so you can add registrants to a list, fire a welcome flow, and segment by which event they registered for.

A Mailhook trigger gives you a unique Spojit email address. Point a forwarding rule (or the vendor's notification settings) at that address, and every matching email starts a run within seconds. A Connector node in Agent mode reads the email body and returns the attendee fields as structured JSON, then two Connector nodes call Klaviyo to upsert the profile and record the event. Runs are asynchronous and deduplicated per message, so the same forwarded email never double-counts. Re-running is safe because creating a profile for an email that already exists updates it rather than producing a duplicate.

Prerequisites

  • A Klaviyo connection added under Connections -> Add connection, with permission to create profiles and events.
  • The Klaviyo list ID you want new registrants added to (copy it from your Klaviyo account; you can also resolve it at build time with the list-lists tool).
  • A sample confirmation email so you know the real field names and layout the AI step will read.
  • A forwarding rule or vendor notification setting you can point at a new email address.

Step 1: Add a Mailhook trigger and generate the address

Create a new workflow and set the Trigger node type to Mailhook. Enter an optional Address prefix (1 to 24 characters, default mh) such as signups, then click Generate email address. Spojit produces a unique address in the form signups-<random16>@mailhook.spojit.com. Copy it and add a forwarding rule from your registration inbox, or paste it into the vendor's notification recipients. Any mail that lands on the address starts a run, whether the address is in To, Cc, or Bcc.

To keep noise out, set an optional From allowlist (for example your ticketing provider's sending domain) and an optional Subject regex like (registration|sign[- ]?up|confirmed). The trigger output is available downstream as {{ input }}, including {{ input.subject }}, {{ input.text }}, {{ input.html }}, {{ input.from }}, and {{ input.replyTo }}.

Step 2: Extract attendee details with a Connector node in Agent mode

Add a Connector node and switch it to Agent mode. Agent mode lets the agent read the email and return a forced JSON shape via a Response Schema, which is exactly what you want for reliable extraction. Set the prompt to something like:

Extract the event registration details from this confirmation email.
Subject: {{ input.subject }}
Body: {{ input.text }}

Return the attendee's email, first name, last name, the event name,
the ticket type, and the registration date. If a field is missing,
return null for it.

Define the Response Schema so the output is reliable and easy to map:

{
  "type": "object",
  "properties": {
    "email":        { "type": "string" },
    "firstName":    { "type": "string" },
    "lastName":     { "type": "string" },
    "eventName":    { "type": "string" },
    "ticketType":   { "type": "string" },
    "registeredAt": { "type": "string" }
  },
  "required": ["email", "eventName"]
}

Name the output variable attendee, so later steps can reference {{ attendee.email }}, {{ attendee.firstName }}, {{ attendee.eventName }}, and the rest.

Step 3: Skip empty extractions with a Condition node

Some forwarded mail (auto-replies, footers, marketing blasts) will not contain an attendee. Add a Condition node that checks {{ attendee.email }} is not empty and looks like an address. Wire the false branch to a stop or a Send Email node that notifies you, and continue the true branch into the Klaviyo steps. This keeps malformed profiles out of your audience and avoids wasting calls on noise.

Step 4: Create or update the Klaviyo profile

Add a Connector node in Direct mode, choose the Klaviyo connector, and select the create-profile tool. This tool upserts on email, so re-sending the same confirmation updates the existing profile instead of duplicating it. Map the single attributes field to a JSON object built from your extracted values:

{
  "email": "{{ attendee.email }}",
  "first_name": "{{ attendee.firstName }}",
  "last_name": "{{ attendee.lastName }}",
  "properties": {
    "last_event_registered": "{{ attendee.eventName }}",
    "last_ticket_type": "{{ attendee.ticketType }}"
  }
}

Name the output variable profile. The created or matched profile ID is returned in the response body, available as {{ profile.data.id }}, which you will reuse to add the registrant to a list.

Step 5: Add the registrant to an audience list

Add another Connector node in Direct mode on the Klaviyo connector and select the add-profiles-to-list tool. Set listId to your event registrants list ID and set profileIds to an array containing the new profile:

{
  "listId": "YourListId",
  "profileIds": ["{{ profile.data.id }}"]
}

Adding a profile to a list is what kicks off any list-triggered welcome flow in Klaviyo, so this step is where the registrant actually enters your marketing journey.

Step 6: Record the sign-up event in Klaviyo

Add a final Connector node in Direct mode on the Klaviyo connector and select the create-event tool. Events let you build flows and segments around the specific action ("Registered for Event") rather than just list membership. Map the single attributes field:

{
  "metric": { "name": "Registered for Event" },
  "profile": { "email": "{{ attendee.email }}" },
  "properties": {
    "event_name": "{{ attendee.eventName }}",
    "ticket_type": "{{ attendee.ticketType }}",
    "source": "email-forward"
  },
  "value": 1,
  "time": "{{ attendee.registeredAt }}",
  "unique_id": "{{ input.messageId }}"
}

Using {{ input.messageId }} as unique_id ties the event to the original message, so an accidental re-forward of the same email does not record the sign-up twice in Klaviyo.

Step 7: Acknowledge the run (optional)

Mailhook runs are always asynchronous, so the sender receives no automatic reply. If you want a confirmation back to whoever forwarded the email, add a Send Email node that sends to {{ input.replyTo }} with a short body such as "Registration for {{ attendee.eventName }} was added to Klaviyo." This uses Spojit's built-in mail service and needs no connection. Remember that external recipients must be on your org allowlist under Settings -> General -> Email recipients.

Tips

  • Read {{ input.text }} in the extraction prompt when it is present; fall back to {{ input.html }} only when the plain-text body is empty, since HTML adds markup noise for the AI step to wade through.
  • If you want to resolve the list ID dynamically rather than hard-coding it, run the list-lists tool once and pick the matching list, then reference its ID downstream.
  • Add custom profile properties like the event name and ticket type so your team can build Klaviyo segments such as "everyone who registered for the spring webinar" without extra work.
  • For high-volume forwarding, the intelligent layer can scaffold this workflow for you: ask Miraxa, "Build a workflow that watches a mailhook, extracts the attendee email and event name, and creates a Klaviyo profile and event."

Common Pitfalls

  • Skipping the empty-email Condition check creates blank or junk profiles whenever a non-registration email is forwarded. Always gate the Klaviyo steps on a valid {{ attendee.email }}.
  • Mismatched field names break the mapping. Open a real confirmation email and confirm Klaviyo expects first_name and last_name (underscored) inside attributes, not camel case.
  • Omitting unique_id on create-event lets a re-forwarded email inflate your sign-up counts. Bind it to {{ input.messageId }}.
  • Mailhook retains received emails for 30 days and deduplicates per message, but a brand-new forward of the same content is a new message. Rely on Klaviyo's email-based upsert and the event unique_id for true idempotency.

Testing

Before pointing your live registration inbox at the Mailhook, forward one real confirmation email to the generated address yourself. Open the run in execution history, inspect the attendee output to confirm every field extracted correctly, then check that create-profile, add-profiles-to-list, and create-event each returned a success body. Verify in Klaviyo that the profile exists, is on the list, and shows the "Registered for Event" metric. Once one email flows end to end, enable the From allowlist and Subject regex filters and turn on the live forwarding rule.

Learn More

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.