Log every WhatsApp lead, order, or survey answer to a Google Sheet automatically. No more copy-pasting from chats: when something happens on WhatsApp, a new row appears in your spreadsheet in real time.
Before following this guide, read the External API Request step foundation guide. It covers every field in the step interface so this guide can focus on the Google Sheets specifics.
Method 1 (recommended): Apps Script webhook. Paste a short script into your sheet, deploy it as a web app, and post to its URL. No OAuth, no service account, no API key. Method 2: direct Sheets API. Use Google's official append endpoint with a service account token. More setup, but no script in your sheet. Most WhatsApp users should choose Method 1.
This method turns your Google Sheet into a webhook that accepts a POST request and appends a row. It runs under your own Google account, so there is no token exchange to manage in the automation.
function doPost(e) {{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var data = JSON.parse(e.postData.contents);
sheet.appendRow([
new Date(),
data.name,
data.phone,
data.email,
data.message
]);
return ContentService
.createTextOutput(JSON.stringify({{ status: 'ok' }}))
.setMimeType(ContentService.MimeType.JSON);
}}
// The first row of your sheet should have headers:
// Timestamp | Name | Phone | Email | MessageWhen you deploy, Google asks you to authorise the script to edit your sheet. Approve it. You may see an 'unverified app' warning because it is your own private script: click Advanced, then 'Go to (project name)', then Allow. This is normal for personal Apps Script projects.
Body:
{{
"name": "{{customer_name}}",
"phone": "{{customer_phone}}",
"email": "{{customer_email}}",
"message": "{{customer_message}}"
}}
Response: {{ "status": "ok" }}
A new row is appended to your sheet with a timestamp
and the four values. Done.The Apps Script runs as you, with your permissions, so it can write to the sheet without any API key or OAuth token in the WhatsApp automation. You only handle a plain webhook URL, exactly like any other webhook in WA.Expert.
If you prefer not to add a script to your sheet, use Google's official Sheets API. This needs a service account and an OAuth access token, which is more setup.
iam.gserviceaccount.com).Google API keys only allow reading public sheets. Writing a row requires an OAuth 2.0 access token from a service account. This token exchange is the main reason Method 1 (Apps Script) is simpler for most WhatsApp automations.
URL (note the :append suffix and valueInputOption):
POST https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID
/values/Sheet1!A:E:append?valueInputOption=USER_ENTERED
Body:
{{
"values": [
["2026-06-23", "Priya", "+919820000001",
"priya@example.com", "Interested in pricing"]
]
}}
Response:
{{
"updates": {{
"updatedRange": "Sheet1!A5:E5",
"updatedRows": 1,
"updatedColumns": 5,
"updatedCells": 5
}}
}}
Map: updates.updatedRange, updates.updatedRows (1 = success)| Part | Value | Notes |
|---|---|---|
| spreadsheetId | From the sheet URL | The string between /d/ and /edit. |
| range | Sheet1!A:E | A1 notation. The tab name plus the column range. |
| :append | URL suffix | Appends after the last row of data in the range. |
| valueInputOption | USER_ENTERED | Interprets dates and formulas. Use RAW for literal text. |
| values | [[...]] | An array of rows; each row is an array of cell values. |
Trigger: A first-time contact sends a message, or a bot captures a lead.
Captured: {{customer_name}} = Priya Sharma
{{customer_phone}} = +919820000001
{{customer_email}} = priya@example.com
{{customer_message}} = Interested in pricing
External API Request step:
POST https://script.google.com/macros/s/AKfy.../exec
Content-Type: application/json
Body: {{name, phone, email, message}}
Response: {{status: 'ok'}}
Result: a new timestamped row in your 'WhatsApp Leads' sheet.
Your team can sort, filter, and follow up from the spreadsheet —
no manual copy-pasting from chats.| WhatsApp trigger | Row logged to Sheets |
|---|---|
| New lead / first message | Timestamp, name, phone, source, first message |
| Order placed in commerce flow | Order ID, customer, items, total, address |
| Survey or feedback answer | Rating, comment, contact, date |
| Support request | Issue summary, priority, contact, timestamp |
| Appointment booked | Name, phone, slot, service requested |
Each is a WhatsApp automation that ends with an External API Request step posting a row to a Google Sheet. Sheets becomes your lightweight CRM or log.
| Symptom | Likely cause | Fix |
|---|---|---|
| Apps Script: nothing appended | Web app deployed with wrong access | Redeploy with 'Who has access' set to Anyone and 'Execute as' set to Me. Use the /exec URL, not the /dev URL. |
| Apps Script: authorisation error | Script not authorised | Run the doPost function once manually in the editor, or redeploy and approve the authorisation prompt (Advanced → Go to project → Allow). |
| Sheets API: 403 permission | Sheet not shared with service account | Share the sheet with the service account email (ends iam.gserviceaccount.com) as Editor. This is the most common Sheets API error. |
| Sheets API: 401 | Invalid or expired access token | Access tokens expire after about an hour. Refresh the token from the service account before each batch, or use Method 1 to avoid tokens entirely. |
| Wrong cell placement | Range does not match the data table | The :append endpoint finds the last row of the table in the given range. Use a range like Sheet1!A:E that covers your columns. |
| Dates stored as text | valueInputOption set to RAW | Use valueInputOption=USER_ENTERED so Google interprets dates and numbers. |
Trigger WhatsApp messages when a Google Form is submitted.
Read guide →Free trial, no credit card. If you get stuck, we answer live on WhatsApp.