Integration Guide
A step-by-step guide to automatically syncing ticket purchases from Zeffy into HubSpot using Zapier — including the edge cases that will catch you off guard.
If your organization runs events through Zeffy and manages relationships in HubSpot, you've probably wondered whether the two can talk to each other automatically. The short answer is yes — but getting there requires more thought than a typical Zapier integration. This guide walks through how we built a production-ready Zeffy-to-HubSpot integration for a nonprofit summit, what decisions we made along the way, and what to watch out for if you're attempting something similar.
Before You Start: What You'll Need
This integration requires active accounts on three platforms:
-
Zeffy — free for registered nonprofits
-
HubSpot — Starter plan is sufficient; you do not need Professional or Enterprise
-
Zapier — Professional plan required, starting at $19.99/month billed annually. This unlocks multi-step Zaps, Code by Zapier, and Looping by Zapier — all of which this integration uses
A note on task volume: each attendee in each order runs through roughly 14 Zapier action steps. For a 250-person event, that's approximately 2,500–3,550 tasks. Less if registrations are spread over a few months, as task limits reset each month. Factor this into your Zapier plan selection.
What This Integration Does
Every time someone purchases a ticket on Zeffy, the integration automatically:
-
Creates or updates a Contact in HubSpot for the buyer
-
Creates or updates a Contact in HubSpot for each attendee (one person can buy tickets for multiple people)
-
Creates an Order record in HubSpot linked to all attendee contacts
-
Populates each attendee's contact with their registration answers — country, organization, role, dietary needs, accessibility needs, and more
-
Adds each attendee to the correct HubSpot list based on their ticket type
-
Records the ticket type on each attendee's contact for segmentation across events
Everything happens automatically within seconds of purchase.
Connect Zeffy to Zapier
Before you can build anything, you need to unlock the Zeffy integration in Zapier. Zeffy isn't listed in Zapier's standard app directory — you need to use Zeffy's private invitation link to access it.
-
Go to Zeffy's Zapier invitation link — you can find it in Zeffy's support documentation
-
Log into your Zapier account or create one if you don't have one yet
-
Click Accept Invite & Build a Zap when prompted
-
When building the Zap, search for Zeffy in the trigger list and select the latest version
-
Choose Get Order as the trigger event — this fires for ticket purchases
-
Connect your Zeffy account using your Zeffy login credentials
Once done, Zeffy will appear as an available trigger in your Zapier account and you're ready to build.
Set Up HubSpot
Before building the Zap, set up the destination in HubSpot.
Create your Ticket Buyers Segment
Create one static segment for your buyers. Segements will be useful in case you want to send customized communications based on ticket type. Use a consistent naming convention:
-
[Your Organization/Event] - Ticket Buyers
Note the Legacy V1 List ID — you'll need it later in Zapier. The ticket-type lists come later in this section, after we create the property they depend on.
Create custom contact properties
These will house the answers to the custom questions asked by your registrants.
To create custom properties In HubSpot, go to Settings → Properties → Contact Properties.
The custom properties you create will depend on what your Zeffy form asks. The following are examples from our implementation — replace them with the fields that match your own registration questions.
For the Event Registrations field, add one checkbox option per ticket type per event — for example, "[Your Organization/Event] - [Ticket Type 1]." Add new options for each future event rather than replacing old ones. This field is how HubSpot automatically enrolls attendees into the right lists — more on that below.
Create Custom Order Properties
A note on HubSpot plans: Custom Objects — the feature most people reach for here — require Enterprise. We used HubSpot's native Orders object instead, which is available on Starter and achieves the same result: a structured record of each purchase linked to all the attendees in that order. If you're working with a nonprofit on a tight budget, this is a clever way to house your event registrations in a dedicated place without spending more.
Since this Object was not designed for event registrations, however, it lacks some of the fields that are necessary to make this work. The good news is that the HubSpot starter subscription also allows the creation of custom properties for this object.
Still in HubSpot Properties, switch to the Orders object and add the following Custom Properties
Set Up Active Lists for Automatic Enrollment
To route registrants and attendees to their corresponding segment/list in HubSpot, we use HubSpot active segments/lists that auto-populate based on the Event Registrations field.
For each ticket-type list, set the filter condition to:
-
Event Registrations contains [Your Organization/Event] - [Ticket Type]
When the integration writes a new value to the Event Registrations field, HubSpot automatically adds the contact to the matching list. No extra Zapier steps required, and future events only need new lists and field options — the Zap logic doesn't change.
Get the Question IDs from Zeffy
The integration maps each registration answer to the right HubSpot field using Zeffy's internal question IDs — unique identifiers assigned to each form question. You need these before writing any code.
How to get them:
-
Make a test purchase on your Zeffy form
-
In Zapier, create a new Zap with the Zeffy — New Order trigger
-
Run a test — Zapier will pull in the data from your test purchase
-
Find the field called Attendees Ticket Answers Question Id — it will contain a list of UUIDs, one per question, in the order they appear on your form
Note down each ID and which question it corresponds to.
| ⚠️ Pro tip: If you delete and recreate a question in Zeffy, it gets a new ID and the integration must be updated. Finalize your form before setting up the integration. |
Build the Zap
The Zap has 14 steps. Here's what each one does:
Step 1 — Zeffy: New Order (Trigger) Fires every time a ticket purchase is made on Zeffy. Captures order details, buyer information, ticket details, and all attendee answers.
Step 2 — HubSpot: Find or Create Buyer Contact Finds the buyer in HubSpot by billing email, or creates them if they don't exist. Sets Lifecycle Stage to lead.
Step 3 — HubSpot: Add Buyer to Ticket Buyers List Adds the buyer to your event's Ticket Buyers list immediately — separate from the attendee enrollment flow.
Step 4 — Code by Zapier: Parse Ticket Summary A short JavaScript step that reads the ticket titles and quantities from the order and builds a clean summary for the Order record — for example, "3-Day Summit Registration (2), Student Registration (1)."
This step involves JavaScript. If you're not comfortable writing code, we recommend getting help from a developer or using an AI tool like ChatGPT or Claude to write and adapt it for your specific form.
Step 5 — HubSpot: Create Order Creates an Order record in HubSpot linked to the buyer contact. Stores ticket summary, total price, payment method, discount codes, receipt URL, and billing information.
| ⚠️ Pro tip: Do not map Zeffy's Subtotal Price field. Zeffy concatenates all ticket prices into a single number for multi-ticket orders, which produces unreliable data. Leave it unmapped and use the Total Price field instead. |
Step 6 — Looping by Zapier: One Iteration Per Attendee Creates one loop iteration per attendee in the order. Every step from here runs once per attendee.
Step 7 — Code by Zapier: Parse Attendee Answers
This is the most complex step. Zeffy sends all attendee answers for an entire order as a single concatenated string — not one set per attendee. This JavaScript step splits that string, finds where each attendee's answers begin using their Full Name question ID as a boundary marker, maps each answer to the right field, and detects data integrity issues.
The step outputs: first name, last name, email, country, and any custom fields matching your Zeffy form questions. It also outputs a raw note containing all answers for reference.
This step must be customized with your specific Zeffy question IDs, your HubSpot field names, and your HubSpot list IDs. The logic is specific to your form structure — it won't work out of the box without these changes.
💻 This step involves complex JavaScript. We recommend getting help from a developer or an AI tool to write and adapt this step for your form.
| ⚠️ Pro tip: The first three questions on your Zeffy form must stay in order. The parsing code extracts name, email, and country by their position (first, second, third). These must remain the first three questions on your form. |
There's one more critical consideration with this step that affects your entire integration — see The Data Integrity Problem below.
Step 8 — HubSpot: Find or Create Attendee Contact Finds the attendee in HubSpot by email, or creates them if they don't exist. Maps all fields from Step 7.
Step 9 — HubSpot: Update Attendee Contact Writes all field values to the contact explicitly. This step is needed because HubSpot's Find or Create doesn't always update existing contacts — it sometimes just returns the existing record without writing new values. The dedicated Update step ensures fields are always written whether the contact is new or existing.
Step 10 — HubSpot: Read Event Registrations A read-only step that fetches the attendee's current Event Registrations field value. This is needed so the next step can append to it rather than overwrite it.
Step 11 — Code by Zapier: Append Event Registration
A short JavaScript step that adds the new ticket type to the existing Event Registrations value without replacing what's already there. This allows contacts who attend multiple events to accumulate a clean history over time. The step checks whether the value already exists before appending, so a contact who purchases the same ticket type twice won't end up with duplicate entries in their registration history.
💻 This step involves JavaScript. We recommend getting help from a developer or an AI tool to write and adapt it for your specific event naming.
Step 12 — HubSpot: Write Event Registrations Writes the updated Event Registrations value back to the attendee contact. Use the Record ID from Step 8 — not Step 10 — as Step 10 returns no ID for new contacts.
Step 13 — HubSpot: Create Note (optional but recommended) Creates a note on the attendee's contact record containing all their registration answers. For contacts where everything mapped correctly, it serves as a convenient reference. For flagged contacts, it provides the raw data needed for manual correction.
Step 14 — HubSpot: Link Order to Attendee Creates an association between the Order (Step 5) and the attendee Contact (Step 8). Runs once per loop iteration, linking every attendee to the same order.
The Data Integrity Problem — and How to Handle It
Even with a well-built integration, Zeffy's data export has one fundamental quirk worth understanding.
When an attendee skips a question, Zeffy sometimes omits that answer entirely rather than including a blank placeholder. This shifts all subsequent answers one position, causing wrong data to land in wrong fields — silently, with no error.
This is the single most important configuration decision in this entire integration.
Making all questions required in your Zeffy form — with instructions like "write N/A if not applicable" — is the only reliable fix. It's a form configuration change, not a code change, and it permanently eliminates the problem.
The integration detects this on a per-attendee basis and responds in two ways:
-
Flags affected fields with "Invalid - Check Notes" so the HubSpot user knows to review them
-
Attaches a note with the raw answers so the information is never lost
When you see "Invalid - Check Notes" on a contact, go to the Activities tab, find the note, and update the fields manually using the raw answers as reference.
Keeping the Integration Updated for Future Events
The integration is designed to be reused. Here's what needs to change for each new event:
In Zapier:
-
Update the ticket-type-to-list mapping with new list IDs and exact ticket names
-
Update the event name prefix used when writing to the Event Registrations field
-
Update the Ticket Buyers list to point to the new event's list
-
Update question ID constants if the registration form changes
In HubSpot:
-
Create new active lists for each ticket type, with the Event Registrations filter (same setup as the original event)
-
Create a new static Ticket Buyers list
-
Add new ticket type options to the Event Registrations multi-checkbox property
Important: Adding a new question to your Zeffy form does not automatically push it to HubSpot. Each new question requires a code update, a new custom property in HubSpot, and a new field mapping in the Zap.
Before You Go Live
Run through this checklist with a real test order:
-
Place a test order with each ticket type
-
Confirm Order record created with correct name, ticket type, quantity, and payment method
-
Confirm buyer contact added to Ticket Buyers list
-
Confirm each attendee contact has all fields populated correctly
-
Confirm each attendee added to the correct ticket-type list
-
Confirm Event Registrations field populated on each attendee contact
-
Confirm Order linked to all attendee contacts
-
Confirm note attached to each attendee contact
-
Delete all test contacts and orders before going live
Bonus: Organizing HubSpot for Event Data
Once the integration is running, a few quick configuration changes in HubSpot will make the data much easier to work with day-to-day.
On the Contact record, consider creating a custom card called "Events" that groups all event-related properties together — Event Registrations, Dietary Restrictions, Food Allergies, Accessibility Needs, How Did You Hear About Us, and any other fields you're capturing from Zeffy. This keeps registration data in one place rather than scattered across the default layout.
On the Orders index view, customize the columns to show only what's relevant — Order Name, Ticket Type, Ticket Quantity, Total Price, Payment Method, and Discount Codes. The default view includes a lot of fields that won't apply here.
For Contacts, create a saved view filtered to your event lists with Event Registrations visible as a column. This lets you see at a glance who is registered for what without opening individual records.
Need Help?
This integration is more involved than a typical Zapier setup — but once it's running, it requires no manual work from your team. If you're building something similar and hit a wall, feel free to reach out — we're happy to point you in the right direction.