Case study
Sheets-to-call automation pipeline
A Google Sheet automation that turns rows into parallel voice calls and writes structured outcomes back. Built at Mindcraft Labs to absorb a support team's manual dialling work without making them leave their workbook.
Headline metric
1 support role
absorbed into automation
Stack
- Python
- Google Sheets API
- Webhooks
- ElevenLabs
- Workflow Automation
Customer records lived in Google Sheets. The automation had to start there.
The context
I built this at Mindcraft Labs for a client whose support team ran their entire customer record system from a Google Sheets workbook. Pending payments, incomplete purchases, follow-ups, post-call notes. Everything sat in one workbook the team had already shaped to fit their process. Moving it to a CRM was off the table. They wanted automation that met them where they already worked.
This was one of three voice AI platforms I built at Mindcraft, each whitelabelled and customised for a different client's internal process. The other two platforms ran on Retell AI; this one ran on ElevenLabs. Sheets-to-call was an add-on automation I layered onto the ElevenLabs platform, not a separate product. The engineering story is the orchestration around the voice agent, not the agent itself.
The problem
The team had hundreds of customers in the sheet flagged for follow-up. Pending payments. Purchases that never closed. Feedback to collect after a recent interaction. Doing this manually meant a support person opened the workbook, picked rows, dialled each number, ran a short script, and typed the outcome back into the row.
The bottleneck was not the conversation. It was the cost of one person sitting on the phone all day to keep the sheet up to date.
The approach
I built a thin Python orchestration layer that treats the sheet as both the source of truth and the destination for outcomes. A new row added to the tracked sheet triggers the flow: read the row, push the customer ID and contextual fields into the call initiation payload, hand the call off to the whitelabel voice agent, and wait for the post-call webhook.
When the call ends, the platform fires a webhook with the structured data the agent captured: confirmations, final amounts, agreed dates, anything the script asked for. My worker parses the payload, matches the customer ID back to the original row, and writes each field into the correct column. I save a short summary and the full transcript alongside for transparency and audit.
I handle failures explicitly. If the JSON breaks or the agent fumbles a field, the status column is marked and the row is held for human intervention rather than overwritten with bad data. The transcript and summary stay attached so a human can verify in seconds.
Calls run in parallel. The team adds rows, the calls happen, the sheet fills in. The workflow shifts from dialling to reviewing.

Tech decisions worth noting
- Google Sheets as the database, deliberately. Terrible at scale, perfect for a few-hundred-row campaign. Zero migration, zero retraining. The team kept their workflow and gained the automation on top of it.
- Customer ID as the join key end to end. Every call is initiated with the customer ID injected into the agent's session context. The webhook returns it. That single ID is the contract between sheet, agent, and writeback. No fuzzy matching on names or phone numbers, no rows getting crossed. This was the failure mode that mattered most, and the ID-as-contract design is what made it disappear.
- Strict structured output from the agent. Every call ends by emitting a JSON object with the fields the worker expects. The conversation is free-form. The handoff is rigid.
- Explicit failure path with human review. Bad JSON does not get retried into the sheet. It marks status, preserves the transcript, and waits for a human. Data correctness beats automation coverage.
- Whitelabel voice platform over building from scratch. ElevenLabs already gave the client what they needed at the call layer. Building the voice runtime ourselves would have been engineering effort for no client value. The interesting work was the orchestration around it.
Outcome
Calls now run in parallel as rows are added. The team's day shifted from making calls to reviewing rows the next morning. A support role's worth of dialling time was absorbed into the automation. The same orchestration pattern I built here, sheet as source plus voice agent plus structured webhook back, became a template I reused across other Mindcraft automation work for adjacent clients.
What I learned
For re-engagement calling, voice quality matters less than people expect. What actually matters is the contract between the agent and the system holding the data. Identity has to be carried end to end. Failure has to be loud and recoverable. Transparency has to be free.
The other thing the project sharpened: a lot of operational teams have a workflow that already works, just slowly. They do not want a new tool. They want the slow part replaced and the rest left alone. At Mindcraft my role was Full Stack AI Developer, previously titled Augmented Developer, and a lot of that work was exactly this shape: full-stack product when needed, but more often converting a complex manual workflow into a simple AI-driven process without making the team relearn anything. Sheets-to-call is the cleanest example of that pattern.
