Import leads from Google Sheets into CleverROI in three ways: manual import (one‑time), automated via Zapier (real‑time), or live scoring with Google Apps Script (scores appear directly in your sheet).
Use this method for one‑time imports or if your sheet is already public. This uses our dedicated import page.
Open your Google Sheet, go to File → Share → Publish to web. Choose Comma-separated values (.csv) and click Publish.
The URL will look like: https://docs.google.com/spreadsheets/d/.../edit. Copy it from your browser's address bar.
In your dashboard, navigate to Google Sheet Import (under Leads). Paste the URL and click Fetch & Import.
Our system automatically maps common column names (name, email, phone, budget, message, source). Rows without email or phone are skipped.
Use this method to score leads as soon as a new row is added to your sheet. This example includes custom fields.
In Zapier, create a new Zap. Choose Google Sheets as the trigger app and New Spreadsheet Row as the event.
Select the spreadsheet and worksheet you want to monitor.
Add an action step, choose Webhooks by Zapier, and select POST. Configure as follows:
https://yourdomain.com/api/webhook.phpX-API-KEY with your API key{
"name": "{{full_name}}",
"email": "{{email}}",
"phone": "{{phone}}",
"budget": "{{budget}}",
"message": "{{message}}",
"source": "google_sheet",
"custom_fields": {
"Your role": "{{role}}",
"When do you want to start?": "{{start_time}}",
"Are you decision maker?": "{{decision_maker}}",
"Company size": "{{company_size}}",
"Primary goal": "{{primary_goal}}"
}
}
Note: Replace {{...}} with the actual column names from your sheet.
Run a test with a sample row. If successful, the lead will appear in your CleverROI dashboard. Publish your Zap.
For advanced users who want scores written directly into their sheet as soon as a new row is added. This script calls the CleverROI API and writes 10+ scoring fields.
Column Layout (A–P for input, Q–Z for output) – set up your sheet like this:
| Column | Field | Description |
|---|---|---|
| A | Name | Lead's full name |
| B | Email address | |
| C | Phone | Phone number |
| D | Budget | Budget amount (text or number) |
| E | Message | Inquiry message |
| F | Source | Lead source (optional) |
| G | Role | Custom field: Your role |
| H | Start Time | Custom field: When to start |
| I | Decision Maker | Custom field: Are you decision maker? |
| J | Company Size | Custom field: Company size |
| K | Primary Goal | Custom field: Primary goal |
| L | (reserved) | Additional custom field |
| M | Score | Total score (0–100) |
| N | Grade | Hot / Warm / Mild / Cold |
| O | Priority Action | Recommended next step |
| P | Closing Probability | e.g., "High (70-90%)" |
| Q | AI Impact | High / Medium / Low |
| R | Contact Grade | A, B, C, D |
| S | AI Confidence | high / medium / low |
| T | AI Score | e.g., "12/20" |
| U | Reasons | Key signals (truncated) |
| V | Structured Signals | e.g., "high_urgency, decision_authority" |
In your Google Sheet, go to Extensions → Apps Script.
Delete any existing code and paste the following script. Replace YOUR_API_KEY with your actual API key and yourdomain.com with your CleverROI domain.
/**
* CLEVERROI GOOGLE SHEET → WEBHOOK INTEGRATION (ENHANCED)
* Columns A–K: input fields (including custom fields)
* Columns M–V: output scoring data
*/
function onFormSubmit(e) {
var sheet = e.range.getSheet();
var row = e.range.getRow();
processRow(row, sheet);
}
function testLatestRow() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lastRow = sheet.getLastRow();
processRow(lastRow, sheet);
}
function processAllRows() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lastRow = sheet.getLastRow();
for (var row = 2; row <= lastRow; row++) {
var existingScore = sheet.getRange(row, 13).getValue(); // Column M
if (existingScore) continue;
processRow(row, sheet);
Utilities.sleep(500);
}
Logger.log("All rows processed.");
}
function processRow(row, sheet) {
try {
// Read input columns A–K (11 columns)
var rowData = sheet.getRange(row, 1, 1, 11).getValues()[0];
// Build payload with custom_fields object
var payload = {
name: rowData[0] || "",
email: rowData[1] || "",
phone: rowData[2] || "",
budget: rowData[3] || "",
message: rowData[4] || "",
source: rowData[5] || "google_sheet",
custom_fields: {
"Your role": rowData[6] || "",
"When do you want to start?": rowData[7] || "",
"Are you decision maker?": rowData[8] || "",
"Company size": rowData[9] || "",
"Primary goal": rowData[10] || ""
}
};
var options = {
method: 'post',
contentType: 'application/json',
headers: { 'X-API-KEY': 'YOUR_API_KEY' }, // <-- REPLACE THIS
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
var response = UrlFetchApp.fetch('https://yourdomain.com/api/webhook.php', options);
var result = JSON.parse(response.getContentText());
if (result.success && result.data) {
var data = result.data;
// M – Score
sheet.getRange(row, 13).setValue(data.score || "");
// N – Grade
sheet.getRange(row, 14).setValue(data.grade || "");
// O – Priority Action
sheet.getRange(row, 15).setValue(data.priority_action || "");
// P – Closing Probability
sheet.getRange(row, 16).setValue(data.closing_probability || "");
// Q – AI Impact
var aiImpact = (data.ai && data.ai.impact) ? data.ai.impact : "";
sheet.getRange(row, 17).setValue(aiImpact);
// R – Contact Grade
sheet.getRange(row, 18).setValue(data.contact_grade || "");
// S – AI Confidence
var aiConfidence = (data.ai && data.ai.confidence) ? data.ai.confidence : "";
sheet.getRange(row, 19).setValue(aiConfidence);
// T – AI Score display
var aiScoreDisplay = (data.ai && data.ai.display) ? data.ai.display : "";
sheet.getRange(row, 20).setValue(aiScoreDisplay);
// U – Reasons (join array, truncate)
var reasons = (data.reasons || []).join("; ");
if (reasons.length > 200) reasons = reasons.substring(0,200) + "…";
sheet.getRange(row, 21).setValue(reasons);
// V – Structured Signals
var signals = [];
if (data.structured_signals) {
for (var key in data.structured_signals) {
if (data.structured_signals[key]) signals.push(key);
}
}
var signalStr = signals.join(", ");
if (signalStr.length > 200) signalStr = signalStr.substring(0,200) + "…";
sheet.getRange(row, 22).setValue(signalStr);
} else {
sheet.getRange(row, 13).setValue("API Error");
}
} catch (error) {
sheet.getRange(row, 13).setValue("Script Error");
Logger.log(error);
}
}
In the Apps Script editor, click on the clock icon (Triggers). Add a new trigger:
Save and authorize the script (it will ask for permissions to access your sheet and send external requests).
Add a new row to your sheet (or submit a form if you're using Google Forms). The script will run automatically, and you should see the score appear in columns M–V within seconds.
You can also manually run testLatestRow() from the Apps Script editor to test the last row.
If you already have many rows that you want to score, run the processAllRows() function once from the editor. It will process each row that doesn't already have a score, with a 500ms delay to avoid hitting rate limits.
Here’s a complete example of the JSON payload your webhook receives (including custom fields). Use this to test your integration.
{
"name": "Rajat Malhotra",
"email": "akash.digitalblue@gmail.com",
"phone": "+919845612345",
"budget": "15-20 lakh allocated based on phase-wise rollout",
"message": "We are optimizing our inbound qualification layer and need deterministic scoring integrated with Zoho CRM. Fraud filtering and phone validation accuracy are important for our SDR workflows.",
"source": "google_ads",
"custom_fields": {
"Your role": "VP - Revenue Operations",
"When do you want to start?": "Within 45 days",
"Are you decision maker?": "Partially involved",
"Company size": "55-75",
"Primary goal": "Improve SQL conversion rate and eliminate low-intent leads"
}
}
If you encounter any issues:
processAllRows() instead of a trigger.For further assistance, contact us at growth@cleverroi.com.