A photo booth that writes lead data to your CRM in real time is the shortest path between a branded event and attributed pipeline. But “integrates with Salesforce” on a vendor spec sheet can mean a live API call fired the moment a guest taps submit, a webhook bounced through Zapier, or a CSV the operator downloads Monday. The six major CRMs each ingest an event lead differently, and the wiring decides whether Tuesday morning the sales team sees 216 routed leads or a half-synced list and a Salesforce admin asking why nothing reached the SDRs.
This guide maps each integration at the object level, explains what breaks when venue wifi drops, and shows how to configure the capture form so event leads land as attributed pipeline instead of orphaned rows.
The offline-to-online problem nobody solves by default
A guest hands over name, email, company, and job title at your booth. The app tries to POST to the CRM. The wifi dies mid-request. What happens next is entirely a function of the capture app’s architecture, and there are three patterns in the wild:
- Real-time push (online-only). Every tap on submit fires a direct API call. If the network is down, the call fails. Unless the app retries on its own, the lead is gone. Most webhook-based integrations work this way because they are the cheapest to build.
- Local-first with background sync. The app writes every capture to a local SQLite database on the device, then syncs to the CRM asynchronously as connectivity allows. If wifi drops, captures accumulate locally. On reconnect, the queue drains in order. This is the correct architecture for convention centers. Simple Booth’s HALO app is one implementation of this pattern: sessions queue on the iPad in offline mode and upload automatically once connectivity returns.
- Batch export. All captures live in the booth app’s local store or cloud until the operator exports a CSV post-event. Guaranteed to work because nothing is live. Guaranteed to miss the first-hour follow-up window (more on why that matters below).
Convention-center wifi is the reason this choice is load-bearing. Steel, concrete, thousands of phones fighting for signal, and organizer-provided networks that are often metered or segregated by exhibitor tier mean that live calls from your booth will fail at some point during a multi-day show. The question is not whether your connection will drop. It is whether the capture app loses the lead when it does.
The related problem is dedup on retry. If a local queue retries a failed write, the CRM has to handle the duplicate gracefully. Most platforms handle contact-level dedup fine: email is the upsert key, so the same email posted twice creates or updates one record. The risk sits in the attribution objects: Campaign Members in Salesforce, Marketing Event associations in HubSpot, Program Member records in Marketo. Those can be written twice if the retry does not carry an idempotency key. The fix is to tag each capture with a UUID at the device and pass it as the external ID on every call. All six of the platforms below accept external IDs for upsert operations.
How each CRM actually receives a booth lead
For each platform: the object the record writes to, the minimum required fields, how event attribution is preserved, how to avoid the common failure modes, and where rate limits start to matter.
Salesforce
A booth capture writes to the Lead object. The minimum required fields on create are LastName and Company. Email is not required by the API but is effectively required because dedup, workflow, and every downstream route-to-SDR rule keys on it. Relevant standard fields for booth forms: FirstName, LastName, Email, Company, Title, and LeadSource.
Event attribution is not a field on the Lead. It is a separate object called Campaign Member. Create one Salesforce Campaign per event, then write a Campaign Member record at capture time with a Status of “Captured” (add the custom status in Setup if it is not already there). Campaign Members migrate with the record when a Lead is converted to a Contact, so the event touchpoint survives the SDR’s conversion step. This matters because LeadSource = "Trade Show" alone rolls every event into one bucket and you cannot build a cost-per-event report off it.
Two API paths. Web-to-Lead caps at 500 submissions per day per org (Salesforce Developer Documentation), does not authenticate, and has no programmatic error handling. Fine for a ten-person networking event. Not fine for a trade show. REST API is the right path for booth traffic: full field control, errors you can catch, and a daily request ceiling of 1,000,000 calls on Enterprise edition (Salesforce Developer Documentation). A 240-lead show consumes a rounding error.
Two failure modes worth wiring around:
- Duplicate Management rules set to Block. If a returning attendee hits the dedup rule, Salesforce blocks the Lead creation and never writes the Campaign Member. The event touchpoint vanishes. Configure the rule to “Allow with alert” so the record still writes.
- Person Accounts. In orgs that use Person Accounts (common in healthcare, financial services, and higher education), a Lead converted without a
Companyvalue becomes a Person Account rather than a Business Account plus Contact pair, and routes differently in assignment rules. If your booth form makes Company optional, SDR routing will silently drop those records. Make Company required in the capture form, or validate it in the booth app before writing.
HubSpot
The record writes to the Contact object via POST /crm/v3/objects/contacts (HubSpot Developer Documentation). The only required field is email; it is also the default dedup key. Booth-relevant standard properties: email, firstname, lastname, jobtitle, company, phone. Lifecycle stage defaults to “Lead” on creation but you can set lifecyclestage: "marketingqualifiedlead" in the same payload if the booth counts as an MQL event.
Event attribution on HubSpot has a proper object now. The Marketing Events API (on Marketing Hub Pro and Enterprise) lets you create an event record, then attach attendance via POST /marketing/v3/marketing-events/{externalEventId}/attend, associating the Contact by email (HubSpot Developer Documentation). The event record is the durable attribution. It survives contact merges and dedups. Without it, event attribution ends up as a free-text property and your attribution report is a string-match exercise.
Rate limits are 150 requests per 10 seconds per portal, with a daily cap of 500,000 on Pro/Enterprise. No booth will hit this. The more common bottleneck is the Forms API daily limit on lower-tier accounts, which is why the Contacts API (private app token authentication) is the right call for a native booth integration rather than a forms embed.
For real-time follow-up, build a Workflow (Marketing Hub Starter and above) triggered by “Contact is created where [event property] contains [Event Name]”. That fires within seconds of the API write and sends the post-event email, updates lifecycle stage, and notifies the SDR before the guest has left the booth.
Klaviyo
Klaviyo’s data model is different enough from the others that teams migrating over (especially from Mailchimp) routinely wire it wrong. The right pattern is two calls: create or update the Profile (POST /api/profiles/), then fire an Event (POST /api/events/) against that profile (Klaviyo Developer Documentation).
The Profile holds static attributes: email (required; dedup key), first_name, last_name, organization, title, phone_number, plus any arbitrary custom properties under the properties object (no pre-registration). The Event is the event-attendance record itself. Use a metric name like Captured at Event with properties for event_name, event_date, booth_station_id, and operator_name. This creates a timeline entry on the Profile that Flows can trigger on and Segments can filter against.
The Lists-versus-Segments distinction is where migrating teams break things. A Klaviyo List is a static subscription (a person is explicitly subscribed to receive list-triggered emails). A Segment is dynamic, computed from Profile attributes and event history. For event capture, do not add the contact to a new List per event. Create a Segment filtered on “has metric Captured at Event where event_name = [X]”. The same contact can belong to multiple event segments without re-subscribing, and your post-event Flow triggers off the event itself rather than list membership.
SMS is the other trap. TCPA requires explicit, separate consent for SMS that is distinct from email consent. Klaviyo stores this under subscriptions.sms.subscribed. Your booth form needs a separate, unchecked SMS checkbox if you intend to text the guest. Bundling email and SMS into one checkbox is a TCPA violation.
Rate limit is 75 requests per second on the stable tier, 350 per second on burst (Klaviyo Developer Documentation). No real-world booth saturates this.
Mailchimp
Mailchimp treats event capture through Audience Members + Tags + Merge Fields. The upsert pattern is PUT /3.0/lists/{listId}/members/{subscriberHash}, where subscriberHash is the MD5 hash of the lowercase email address (Mailchimp Developer Documentation). PUT (not POST) makes the call idempotent: create-or-update in one request, which is exactly what you want when a local queue retries.
The structural constraint is Mailchimp’s one-audience philosophy. Free plan gets one audience. Paid plans can have multiple, but Mailchimp’s own guidance is to keep a single master audience and use Tags plus Groups to segment. In practice, event operators end up with an “Events” audience and tags per show: Event: CES 2026, Event: NRF 2026. Tags are applied via POST /3.0/lists/{listId}/members/{subscriberHash}/tags, accept free text, and create on write.
Merge fields carry the structured data: FNAME, LNAME, COMPANY, JOBTITLE as standard merge tags, plus any custom ones registered via the Merge Fields API.
Double opt-in is the decision point. Setting status: "subscribed" skips it; status: "pending" triggers a confirmation email. For EU audiences, double opt-in is the safer path (see the consent section below). There is a subtle trap here: if the booth sends the guest their photo by email, and that photo-delivery email is the same email as the opt-in confirmation, you have bundled marketing consent with a transactional service, which fails the GDPR freely-given test. Send photo and opt-in confirmation as separate emails.
Marketo
Marketo’s attribution model is the most structured of the six and the reason it stays popular with B2B RevOps teams. Three objects: Lead, Program, Program Member (Marketo Developer Documentation).
Lead upserts hit POST /rest/v1/leads.json. The endpoint deduplicates on email by default, so the same call creates a new Lead or updates an existing one. Only email is strictly required; firstName, lastName, company, title, and phone are the standard booth fields.
The attribution work happens on the Program side. Create a Program per event (“CES 2026 Photo Booth Capture”), enter the event cost (booth rental, hardware, staffing) in the Program’s cost field, then associate each captured Lead as a Program Member via POST /rest/v1/programs/{programId}/leads.json. Program Members have a custom status ladder (e.g., “Captured”, “Email Sent”, “Email Opened”, “Meeting Booked”); Smart Campaigns fire on status changes. The payoff is that Marketo can compute cost-per-program-member, cost-per-opportunity, and multi-touch attribution against the event Program without a separate BI tool.
Rate limit is 50,000 API calls per day per subscription across all REST endpoints combined, with a concurrent window of 100 calls per 20 seconds. A 240-lead show needs 480 calls (240 Lead upserts + 240 Program Member writes), trivially within limits. A 1,000-lead show is also fine, but use the batch endpoint (up to 300 records per request) if captures come in bursts.
Skip Forms 2.0 for booth work. It is a JavaScript embed with no offline story. REST API with OAuth 2.0 client credentials is the cleaner path for any tablet app that may lose connectivity.
ActiveCampaign
The record writes to Contact via POST /api/3/contacts, deduped on email, updated via PATCH (ActiveCampaign Developer Documentation). Standard booth fields: email (required), firstName, lastName, phone, orgname. Custom fields live in fieldValues and are referenced by numeric field ID, which you look up once in Settings > Custom Fields.
Three separate objects matter for event capture: Lists, Tags, Deals. List subscription is a separate call (POST /api/3/contactLists) and controls which broadcast emails the contact receives. Tags are applied via POST /api/3/contactTags and are the right trigger for event automations because tag application fires Automations synchronously, usually within seconds. Deals are optional, for B2B pipeline tracking via POST /api/3/deals.
The operational pattern: create the Contact, apply an event tag (Event: CES 2026), and let the Automation handle everything downstream (list subscription, welcome email, SDR notification). Faster than list-based automation because tag triggers are synchronous.
Rate limit is where ActiveCampaign diverges from the others, and it matters. Standard API is 5 requests per second per account (ActiveCampaign Developer Documentation). A booth processing a guest every 6 seconds is fine. A multi-station setup with simultaneous captures hits the ceiling quickly if the app writes synchronously. Local queueing with burst retry is not optional at volume. The bulk import endpoint exists but tops out at 100 requests per minute, which is its own constraint.
Site tracking is the quiet long-tail benefit. Once a captured contact opens the post-event email and clicks through to your site, the first-party tracking cookie binds their web activity to the Contact record. Behavioral triggers (visited pricing, visited product, came back three times) become available on a lead that originated as a tablet capture at a booth.
Native, middleware, or CSV: three tiers with three reliability profiles
Every integration on the market sits in one of three tiers, and the choice is mostly an arithmetic exercise at the event-volume level.
- Tier 1 (native REST API). The booth app writes directly to the CRM via its SDK or REST endpoints. Lowest latency. Cleanest error handling. Requires the booth vendor to have built the integration or given you API access to build it.
- Tier 2 (middleware: Zapier, Make, Workato). The booth fires a webhook; middleware transforms and forwards to the CRM. Works for any CRM without a native connector. Adds a dependency and a per-operation cost that compounds at volume.
- Tier 3 (CSV export). Captures accumulate locally or in the vendor’s cloud. Operator exports a CSV after the event; marketing imports Monday morning. Most reliable in the narrow sense that nothing is live. Zero chance of real-time follow-up.
Zapier’s current pricing (verified April 2026) is the clearest cost anchor. The Free tier is 100 tasks per month. Professional is $19.99 per month for 750 tasks, then $49 per month for 2,000 tasks. Business tiers start at $69 per month (Zapier pricing). A two-step Zap (booth webhook → CRM write) consumes two tasks per capture.
The decision rule that falls out of the math:
- Fewer than ~200 captures per event: Zapier is cost-effective and the simplest path. 400 tasks fits the entry paid tier.
- 200 to ~1,000 per event: Zapier still works, but task costs compound fast if you run multiple Zaps per month. Evaluate native integration if the CRM offers one.
- More than ~1,000 per event, or multi-event operators running 12+ shows per year: native REST API integration is non-negotiable. Zapier’s task costs and the rate-limit friction at peak throughput will outweigh the convenience.
Make and Workato are Tier 2 alternatives (Make is per-operation like Zapier; Workato is enterprise-priced and publishes a 99.9% uptime SLA, though that figure is vendor marketing and not independently benchmarked). The choice between middleware providers is mostly a cost-per-operation calculation; none of them beat a native integration on reliability at high event volumes.
Field mapping that actually lets sales work the lead
The minimum viable field set for a booth capture, in priority order:
email(required; the dedup key everywhere)first_name(required for any email personalization)last_name(required for the same reason and for Salesforce Lead creation)company(required for Salesforce routing, high-leverage elsewhere)job_title(the single highest-leverage B2B field, because it is the routing signal to the right SDR)marketing_consent(unchecked by default, separate from photo delivery)event_name+event_date(the attribution fields; without these the lead is orphaned)
Add one or two optional custom questions at most. Make them questions a prospect is happy to answer (product area of interest, rough timeline), not questions that feel like a sales qualifying call (budget, authority). Each field past the essentials costs conversion.
On attribution fields: do not rely on a generic LeadSource = "Event". Use a structured pattern the booth app writes consistently: Event: [Event Name] (YYYY-MM). Reports aggregate cleanly. A booth station ID (booth_station_id: "ces-2026-booth-A") helps when the same event has multiple stations and you want to know which one converted.
Why job title matters more than most operators treat it: it is the only field on a booth form that directly determines downstream routing. “VP Marketing at a 500-person SaaS” routes to the enterprise SDR queue. “Marketing Coordinator at a 10-person agency” routes to an automated nurture. Without job title, every lead ends up in the same generic queue, and the high-value captures (the reason you paid for the booth in the first place) get the same email as everyone else.
“Ticked to get my photo” is not marketing consent
The most consequential legal point in this article is also the easiest to get wrong. A guest who ticks a box to receive their digital photo is consenting to a transactional service. They are not consenting to marketing communications. Treating these as the same is a GDPR violation under Article 7.
GDPR Article 6(1)(a) establishes consent as one of six lawful bases for processing personal data (the most common basis for marketing). Article 7 sets the conditions: consent must be freely given, specific, informed, and unambiguous. Pre-ticked boxes do not meet the unambiguous threshold. The UK ICO guidance is explicit: “Consent will not be freely given if there is any element of compulsion, pressure or inability to exercise free choice” (ICO, “What is valid consent?”).
Bundling marketing consent with photo delivery fails the freely-given test. If the guest cannot get their photo without also agreeing to marketing, the consent is not free.
The fix is structural:
- Separate checkboxes on the capture form. One for photo delivery (if required at all; many booths deliver automatically to the email address captured). One for marketing opt-in, unchecked by default, with explicit language naming who is sending what.
- The booth logs the consent record: exact text shown, timestamp, session/device ID, and the specific purposes disclosed. Article 7(1) requires the controller to demonstrate that consent was given, and a Subject Access Request can be filed up to six years later (UK limitation period).
- Double opt-in is not required by GDPR but is the strongest evidentiary record. For EU and UK audiences, use it. For US-only, single opt-in is permitted.
No specific ICO enforcement action against event lead capture has been publicly recorded. The regulator has targeted bundled consent in other contexts (cookie banners, pre-ticked insurance boxes), so the principle is established. The risk profile is real even if the precedent is not yet specific to photo booths.
Dedup and attribution: the post-sync problem
CRM dedup rules usually fire on email. This is correct: the person is the same person across three events. What breaks is event touchpoint history, because the Lead/Contact record gets one LeadSource value and the first one usually wins on merge. The second and third events vanish from the record.
The fix is to preserve event attendance on a separate, multi-value object rather than a field on the Lead:
- Salesforce: Campaign Member records (one per event the Lead attended)
- HubSpot: Marketing Event associations (one per event)
- Marketo: Program Member records (one per event Program)
- ActiveCampaign: a custom “Event Attended” object, or multiple tags with unique names
- Klaviyo: multiple Event timeline entries (the data model already supports this natively)
- Mailchimp: multiple tags, one per event
These objects are one-to-many with the contact, so dedup on email does not collapse them. A returning attendee’s record shows three events, not one.
One operational asset most operators ignore: attach the photo itself to the CRM record. The photo is a cold-email opener (“Great meeting you at our CES booth, here’s the photo”) that makes a follow-up measurably warmer than a generic post-event email. Not attaching it loses a zero-cost lead-nurture asset.
Finally: routing. If the booth captures job title, use it to auto-route at write time rather than post-hoc. Configure HubSpot Workflows, Salesforce assignment rules, or Marketo Smart Campaigns to route on the title field before the guest leaves the booth. The SDR can reach out while the event is still running, which is where speed-to-lead compounds.
A concrete attribution scenario
Three-day trade show. Single-station booth. 240 captures across the show, 80 per day, a realistic estimate for a mid-size professional event with decent foot traffic (no independent industry benchmark for per-station capture volume was located in research; this is a conservative estimate relative to vendor-published ranges of 50 to 300 per day).
Outcome with a native real-time CRM integration:
- 240 captures flow into the CRM with full field data.
- Roughly 10% drop for format errors or consent-text issues, leaving 216 usable leads.
- 30% fit ICP on job title and company size: 65 SQL-ready leads.
- SDR contacts all 65 within 24 hours. Harvard Business Review research on lead response time (Oldroyd et al., March 2011) found that contacting a lead within one hour of the initial contact makes the lead nearly 7 times as likely to be qualified compared to waiting a single additional hour, and after 24 hours the odds drop by a factor of more than 60.
- 20% of qualified contacts book a meeting: 13 meetings.
- 30% of meetings convert to opportunity: 4 opportunities.
Same event, same booth, CSV-export workflow:
- The CSV reaches the marketing coordinator Monday morning. Cleanup takes until Wednesday. SDRs start dialing Thursday.
- By Thursday, the 65 ICP leads are 96 hours past the optimal contact window. Applying HBR’s decay curve, qualification rates fall sharply. A realistic outcome is 3 to 5 meetings instead of 13.
- Equivalent opportunity count: 1 to 2 instead of 4.
The integration premium (native connector vs. CSV, or a paid Zapier tier at this volume) costs a few hundred dollars per show. The pipeline value of those extra opportunities is an order of magnitude larger. This is also the arithmetic reason the Center for Exhibition Industry Research’s 2015 study found 80% of trade show leads go unfulfilled (CEIR / Jefferson Davis, 2015): a lead sitting in a CSV on a marketing coordinator’s desktop on Monday is already past the point where most follow-up succeeds, and many never get worked at all.
Plug your own numbers in. The shape of the answer holds: capture-rate and ICP-fit set the pool, contact-time decay sets what fraction of the pool converts, and the integration tier determines whether your contact-time is minutes or days.
Troubleshooting checklist
Operator-grade, pre- and post-event:
- Pre-event: one-lead sync test. Fire a test capture with a fake email. Confirm it lands in the right object (Lead, Contact, Profile) with the right fields, the right event attribution (Campaign Member, Marketing Event, Program Member), and fires the expected workflow.
- Pre-event: offline-queue test. Put the booth in airplane mode. Capture three leads. Turn wifi back on. Confirm all three sync, in order, with no duplicates in the CRM, and the attribution records write once.
- Pre-event: consent-text review. Read the exact language shown to the guest. If it bundles marketing consent with photo delivery, rewrite it before the event.
- During event: CRM-side monitor. Keep a dashboard open filtered to today’s event tag. Spot-check hourly. A long gap in writes usually means wifi is down and the queue is filling.
- Post-event: count reconciliation. Booth-side capture count vs. CRM-side new records with this event’s source tag. A gap greater than 5% means something broke and you need to find the failed queue entries before the next event.
- Post-event: consent-record spot-check. Pull three records at random. Confirm the consent timestamp, exact text shown, and device ID are all on the record. If they are not, the record-keeping requirement under Article 7(1) is not being met.
- Post-event: unsubscribe test. Click the unsubscribe link in the welcome email. Confirm it resolves, processes, and updates the marketing opt-in status in the CRM. A broken unsubscribe is a compounding legal problem at every subsequent event.
Run the checklist at every event. The failure modes repeat, and the ones that do not get caught at event N show up compounded at event N+1.
Sources
- ActiveCampaign Developer Documentation. “Create a new contact.” https://developers.activecampaign.com/reference/create-a-new-contact
- Center for Exhibition Industry Research (CEIR) / Davis, Jefferson (2015). “Industry Insight Report: How Exhibitors Can Improve Lead Quality and Sales Conversion.” https://globalpetexpo.org/hubfs/CEIR-Industry-Insight-Report-How-Exhibitors-Can-Improve-Lead-Quality-and-Sales-Conversion.pdf
- HubSpot Developer Documentation. “CRM API — Contacts.” https://developers.hubspot.com/docs/api/crm/contacts
- HubSpot Developer Documentation. “Marketing Events API.” https://developers.hubspot.com/docs/api/marketing/marketing-events
- Klaviyo Developer Documentation. “Create Profile.” https://developers.klaviyo.com/en/reference/create_profile
- Klaviyo Developer Documentation. “Create Event.” https://developers.klaviyo.com/en/reference/create_event
- Mailchimp Developer Documentation. “Marketing API — List Members.” https://mailchimp.com/developer/marketing/api/list-members/
- Marketo Developer Documentation. “REST API Overview.” https://developers.marketo.com/rest-api/
- Oldroyd, James B., Kristina McFarland, and Elizabeth Braverman (March 2011). “The Short Life of Online Sales Leads.” Harvard Business Review. https://hbr.org/2011/03/the-short-life-of-online-sales-leads
- Salesforce Developer Documentation. “Lead (Standard Object).” https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_lead.htm
- Salesforce Developer Documentation. “App Limits Cheatsheet.” https://developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/
- UK Information Commissioner’s Office (ICO). “What is valid consent?” https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/lawful-basis/consent/what-is-valid-consent/
- Zapier (2026). “Pricing.” https://zapier.com/pricing