The Scenario
You're a growth engineer at a B2B SaaS company and your onboarding campaign launches in four hours. The campaign relies on Customer.io knowing each trial user's plan_tier — because the first email branches depending on whether they're on Free, Pro, or Enterprise. Your Google Sheet has 2,000 rows: email in column A, first name in B, company in C, plan_tier in D. None of them are in Customer.io yet.
The bad version:
- Export the sheet as a CSV, upload it through Customer.io's People importer, and spend fifteen minutes mapping "plan_tier" to whatever custom attribute Customer.io expects it to be named.
- Discover that 200 rows have a blank company field and the importer fails validation, so you clean the sheet, re-export, re-upload.
- Check the People list afterward, find that two dozen records look wrong, and manually re-enter them because the importer doesn't tell you which rows it rejected.
The campaign is riding on those attributes being accurate before the first send. There is no version of "we'll fix it after launch" that ends well here.
The Easy Way: One Prompt in SheetXAI
SheetXAI is an AI agent that lives inside your Google Sheet. It reads the data across all your tabs, understands the structure, and through its Customer.io integration it can identify users and set their attributes without a CSV importer in sight.
For every row in my Google Sheet, use Customer.io to identify the person using the email in column A and set their name, company, and plan_tier attributes from columns B, C, and D
What You Get
- Each row is sent to Customer.io's identify endpoint with the right attribute names mapped automatically.
- Column E gets written with the result: "Identified" or the specific error for any row that failed (blank email, duplicate, API rejection).
- Rows with blank emails are skipped and flagged rather than silently dropped.
- The full 2,000 records process in one operation — no upload limits, no re-mapping between runs.
What If the Data Is Not Quite Ready
The plan_tier values are inconsistent — "free," "Free," "FREE" all in the same column
For every row in my sheet, normalize the value in column D to lowercase before sending it to Customer.io as the plan_tier attribute — email in column A, name in column B, company in column C
Some rows are missing a company name and I need a fallback
Identify all users in my sheet in Customer.io using email from column A, name from column B, and plan_tier from column D. If column C is blank, use "Unknown" as the company attribute value
Users come from two tabs — "Enterprise Trials" and "SMB Trials" — and both need to be identified
Identify all users from both the "Enterprise Trials" and "SMB Trials" tabs in Customer.io, using column A for email and column D for plan_tier on each tab, and write the result status into column E on each respective tab
Clean duplicates, set attributes, and flag rows that need a follow-up in one shot
In my Google Sheet, deduplicate rows by email keeping the most recent entry (column E has the signup date), then identify each unique user in Customer.io with their plan_tier from column D, and mark column F as "Flagged" for any row where plan_tier is blank
Asking for the normalization and the action together is almost always faster than two separate passes.
Try It
Get the 7-day free trial of SheetXAI and open your trial user sheet, then ask it to identify everyone in Customer.io before your next campaign window. You can also check out exporting segment membership or the full Customer.io overview.
