# Google Sheets Email Verification — Ravn

Canonical: https://askravn.com/integrations/google-sheets

Integrations · Google Sheets

# Verify emails in Google Sheets with one formula

Paste a short Apps Script into your sheet, store your key in Script Properties, and type =RW_VERIFY(A2:A200) to get a status and risk score beside every address, checked in a single batch call.
[Start free: 1,000 lookups](https://askravn.com/#start) [Read the docs](https://askravn.com/docs)

Setup
## Add the script

- / 01
### Open Apps Script
In your sheet, choose Extensions → Apps Script. Delete the sample function and paste the code below. Save.
- / 02
### Store the key out of the sheet
In the Apps Script editor open Project Settings, scroll to Script Properties and add `RAVN_API_KEY` with your `rw_live_…` key. Never put the key in a cell: anyone the sheet is shared with could read it.
- / 03
### Use the formula
Back in the sheet, in B2 type `=RW_VERIFY(A2:A200)`. It fills two columns per row: status and risk score.
- / 04
### Freeze the results
Custom functions can recalculate when the sheet reloads, which spends lookups again. Once results are in, copy the output and Paste special → Values only.
Apps Script
## Code.gs
One request covers the whole range (up to 1,000 unique addresses), so the sheet makes a single call instead of one per row.
```
const RW_URL = 'https://api.askravn.com/v1/tools/';

function rwCall_(tool, payload) {
const key = PropertiesService.getScriptProperties().getProperty('RAVN_API_KEY');
if (!key) throw new Error('Add RAVN_API_KEY under Project Settings > Script Properties');
const res = UrlFetchApp.fetch(RW_URL + tool, {
method: 'post',
contentType: 'application/json',
headers: { Authorization: 'Bearer ' + key },
payload: JSON.stringify(payload),
muteHttpExceptions: true,
});
const body = JSON.parse(res.getContentText());
if (res.getResponseCode() !== 200) {
throw new Error('Ravn ' + res.getResponseCode() + ': ' + body.error.code + ' - ' + body.error.message);
}
return body;
}

/**
* Verifies a column of emails in one batch call.
* Returns [status, risk_score] for each row.
* @param {A2:A200} range The cells holding email addresses.
* @customfunction
*/
function RW_VERIFY(range) {
const cells = Array.isArray(range) ? range : [[range]];
const rows = cells.map(function (r) { return String(r[0] || '').trim().toLowerCase(); });
const unique = rows.filter(function (e, i) { return e.indexOf('@') > 0 && rows.indexOf(e) === i; });
if (unique.length === 0) return rows.map(function () { return ['', '']; });
if (unique.length > 1000) throw new Error('Up to 1,000 unique addresses per formula. Split the range.');

const body = rwCall_('validate_emails', { emails: unique });
const byEmail = {};
(body.results || []).forEach(function (v) { byEmail[v.email] = v; });
return rows.map(function (e) {
const v = byEmail[e];
return v ? [v.status, v.risk_score] : ['', ''];
});
}
```

Recipes
## Sheets jobs it handles

- / 01
### Clean an event list
Paste the attendee export into column A, run `=RW_VERIFY`, then filter column B to `valid` before importing into your email tool.
- / 02
### Spot role and disposable addresses
Extend the returned array with `v.role_account` and `v.disposable` to flag `info@` style and throwaway addresses. Every field is listed in [the validate_email reference](https://askravn.com/docs#validate_email).
- / 03
### Very large sheets
For tens of thousands of rows, download the sheet as CSV and use [the CSV enrich command](https://askravn.com/integrations/csv), which saves progress and resumes.
FAQ
## Common questions.
[All questions →](https://askravn.com/faq)Why does Google ask for permissions the first time?The script fetches an external URL and reads its own Script Properties, so Google asks you to authorise it once. It runs under your Google account and only talks to `api.askravn.com`.The formula shows an error about running too long. What now?Google limits how long a custom function may run. Use smaller ranges, for example 200 rows per formula, and freeze each block as values before starting the next.Can people I share the sheet with see my key?Not from the cells. Script Properties are stored with the script, so editors who open Apps Script can see them. Share the sheet as view-only, or keep the script in your own copy, if that matters.Is there a Ravn Sheets add-on?No. This script is the whole integration, and you can read every line of it. Try a single address first with [the free email verifier](https://askravn.com/tools/email-verifier) if you want to see verdicts before writing code.

## More in [integrations](https://askravn.com/integrations)
Every page uses the same account, plan and tools. [See pricing →](https://askravn.com/pricing)
- [HubSpot Email Verification & EnrichmentVerify and enrich HubSpot contacts with Ravn: export a CSV, run npx ravn enrich, import the results back, or let Claude do it with both connectors..](https://askravn.com/integrations/hubspot)
- [JavaScript & Node.js Email Verification APICall Ravn from Node with built-in fetch: a small typed-free client that branches on status, waits on 429 Retry-After and throws clear error codes..](https://askravn.com/integrations/javascript)
- [Make.com Email Verification & EnrichmentCall Ravn from a Make scenario with the HTTP app’s Make a request module: JSON body, Bearer header, parsed response you can map and filter..](https://askravn.com/integrations/make)
- [n8n Email Verification & EnrichmentUse the n8n HTTP Request node with Header Auth to verify emails, find work addresses and enrich companies with Ravn inside any n8n workflow..](https://askravn.com/integrations/n8n)
- [Python Email Verification API ClientCall Ravn from Python with requests: one POST per tool, branch on status, retry 429 using Retry-After, and turn error codes into clear exceptions..](https://askravn.com/integrations/python)
- [Zapier Email Verification WebhookVerify and enrich emails in a Zap with the Webhooks by Zapier POST action and a Filter on the result, on Zapier plans that include Webhooks..](https://askravn.com/integrations/zapier)
