The Scenario
A product engineer has a legacy database export sitting in an Excel workbook — 5,000 rows of historical purchase events with distinct_id in column A, amount in column B, and timestamp in column C. The events need to land in PostHog before Tuesday's funnel analysis. The data engineer who ran the export is remote today. The funnels currently show a six-month gap, and the product lead wants it closed before the quarterly review.
The bad version:
- Write a Python script to read the Excel file via openpyxl, format each row as a PostHog capture event, and POST one at a time to the capture endpoint — discover partway through that the batch endpoint exists and handles this more efficiently
- Realize the timestamp column is formatted as MM/DD/YYYY and PostHog requires ISO 8601, so stop the script, fix 5,000 cells, restart
- Run again, watch it time out at row 3,100, restart from that row, discover distinct_ids have trailing spaces that create duplicate person profiles in PostHog
A full day of engineering work for what should be a five-minute task.
The Easy Way: One Prompt in SheetXAI
SheetXAI is an AI agent that lives inside your Excel workbook. It reads the data, understands the schema, and through its built-in PostHog integration it formats and sends the batch ingest call — no script, no API client, no timestamp normalization by hand.
For each row in this workbook, send a PostHog event named 'legacy_purchase' with distinct_id from column A, amount from column B, and timestamp from column C as event properties. Use the batch endpoint and handle any timestamp format conversion needed.
What You Get
- Each row becomes one PostHog event with the correct property mapping
- Timestamps are converted to ISO 8601 automatically before the request is sent
- Rows that fail (missing distinct_id, malformed timestamp) are flagged with an error note in column E
- A summary count of successfully ingested vs. failed rows is written below the data
What If the Data Is Not Quite Ready
Timestamps are in the wrong format
The timestamp column C is in MM/DD/YYYY HH:MM format. Convert each value to ISO 8601 before sending the PostHog batch event, using UTC timezone, and write the converted timestamp into column D so I can verify it.
Some rows are missing distinct_ids
Before sending any PostHog events from this workbook, check column A for blank or null distinct_ids. Write "SKIP - no distinct_id" in column E for those rows, then send events only for rows where column A has a value.
Events need properties from a second worksheet
Join the "Events" worksheet (distinct_id in column A, amount in column B, timestamp in column C) with the "Users" worksheet (distinct_id in column A, country in column B, plan in column C) on distinct_id, then send each matched row as a PostHog 'legacy_purchase' event with amount, timestamp, country, and plan as properties.
Full cleanup and ingest in one shot
In the "Raw Events" worksheet: strip trailing spaces from column A, convert column C timestamps from MM/DD/YYYY to ISO 8601, remove rows where column B is blank or zero, then batch-send the cleaned rows to PostHog as 'legacy_purchase' events with distinct_id from column A, amount from column B, and timestamp from column C. Write event status into column D.
Normalization and ingestion in a single prompt — no two-pass cleanup required.
Try It
Get the 7-day free trial of SheetXAI and open any Excel workbook containing a historical event log — purchase records, activation milestones, legacy session data — then ask it to ingest the rows into PostHog. Related: Bulk Add Users to a PostHog Static Cohort From an Excel workbook and the PostHog hub.
