Back to Customer.io in Google Sheets
SheetXAI logo
Customer.io logo
Customer.io · Google Sheets Guide

Bulk Track Offline Events in Customer.io From a Google Sheet

2026-05-14
5 min read

The Scenario

Your product analyst surfaces a problem mid-sprint: 1,500 offline conversion events from a partner integration never made it into Customer.io. Those events are supposed to trigger a re-engagement campaign for users who completed a purchase off-platform — but because they weren't tracked, the campaign never fired. The events are sitting in a Google Sheet: email in column A, event name in column B, timestamp in column C, order_value in column D.

The bad version:

  • Read the Customer.io API docs for the track event endpoint, grab an API key, write a script to loop through each row and POST the event payload.
  • Run the script, hit a rate limit at row 200, add a sleep, run it again.
  • Check Customer.io's activity log manually to verify that the events landed on the right profiles — two hours later.

You're not a backend engineer. You have three other analysis tickets open. This landed on your plate because you own the sheet.

The Easy Way: One Prompt in SheetXAI

SheetXAI is an AI agent that lives inside your Google Sheet. It reads your data and, through its Customer.io integration, can replay event batches against user profiles — without you touching the API or writing a line of code.

For each row in my sheet, use Customer.io to track the event in column B for the user with email in column A, passing the timestamp from column C as a property

What You Get

  • Each row in the sheet triggers a Customer.io track event call for the corresponding user profile.
  • The event name from column B and the timestamp from column C are passed as event properties.
  • Column E gets written with the outcome: "Tracked" or the specific error for any row where the user wasn't found or the payload was rejected.
  • The batch runs in one operation — no script, no rate-limit management, no manual verification in the activity log.

What If the Data Is Not Quite Ready

The event names in column B are inconsistent — some say "purchase_complete," others "Purchase Complete"

Track all events in my sheet against Customer.io using email from column A and event name from column B, but normalize the event name to snake_case before sending — timestamp from column C, order_value from column D as a property

Some rows are missing a timestamp and need to default to today

For each row in my Google Sheet, track the event in column B for the user identified by email in column A in Customer.io. If column C is blank, use today's date as the event timestamp. Pass order_value from column D as a property.

Events need to come from two different sheets — "Online" and "Offline" events tabs

Track all events from both the "Online" and "Offline" tabs in Customer.io — email in column A, event name in column B, timestamp in column C on each tab — and write the result status into column D on each tab

Deduplicate events by email and timestamp, track, and mark rows for audit in one shot

Deduplicate rows in my sheet by the combination of email (column A) and timestamp (column C), keeping the first occurrence of each pair, track each unique event in Customer.io using event name from column B and order_value from column D as a property, then mark column E as "Duplicate Skipped" for any rows that were removed

Running the deduplication and the tracking in one prompt means the re-engagement campaign fires against clean data.

Try It

Get the 7-day free trial of SheetXAI and open the sheet with your offline event log, then ask it to replay the events into Customer.io before the re-engagement window closes. You can also check out bulk-upserting user profiles or the full Customer.io overview.

Stop memorizing formulas.
Tell your spreadsheet what to do.

Join 4,000+ professionals saving hours every week with SheetXAI.

Learn more