Zapier is where most teams first wire a verification step between a form, a CRM and a mailing list. Spaw fits in two ways: today, any Zap can call the REST API through Zapier's own Webhooks app; soon, a Spaw app built by us will offer the same lookups as ordinary actions with a saved connection. This page covers both, in that order.
What works today: Webhooks by Zapier
Webhooks by Zapier is a premium app, so it needs a paid Zapier plan. Everything else is a plain HTTPS call.
- Create a secret API key on the API keys page of your Spaw dashboard. It starts with
sk_live_. Publishablepk_keys are locked to browser origins and will not work from Zapier. - Open the Zap that receives the address, for example a new form entry or a new CRM contact, and add an action step using Webhooks by Zapier.
- Choose the POST event. Set the URL to
https://spaw.co/api/v1/emailand the payload type to JSON. - Under the data fields, add one key named
emailand map it to the address from the trigger step. - Under headers, add
Authorizationwith the valueBearer sk_live_…using your key. - Test the step. A good first test address is
[email protected], which answers a canonical result, costs nothing and never appears in your history.
The request Zapier sends looks like this:
{
"email": "[email protected]"
}
The answer is the full verification result. Zapier flattens nested JSON, so the verdict shows up in later steps as the data field deliverable (the raw key is data__deliverable), the reason as reason, the risk score as risk_score, and the typo suggestion as did_you_mean. Every field of the single-address response is available for mapping.
For a Zap that handles a list rather than one address at a time, point the same step at https://spaw.co/api/v1/email/batch and send { "emails": [...] } with up to 50 addresses. The batch endpoint answers in input order and counts as one request against the rate limit.
The Spaw app for Zapier
A Spaw app for Zapier is built and is going through Zapier's publishing process; it is not in the Zapier app directory yet. When it is, this page will carry the link. It replaces the manual webhook step with these pieces:
- A connection that takes your secret API key once and labels itself with your account email.
- Actions: Verify Email, Verify Emails (up to 50 addresses, one per line), Check Domain, Add to Suppression List, Look Up IP Address, Report IP Outcome (abuse, fraud, bot or chargeback, free; it scores your own later lookups of the address), Validate Phone Number, Validate Phone Numbers (up to 1,000, with a shared Country and a Live carrier check input), Report SMS Outcome (delivered, undelivered, abused, verified or opted out, free), Validate Postal Address, and Verify Business Identifier (a Legal Entity Identifier or a company number, read against the registers Spaw syncs).
- A search step, Find Email Verdict, so a lookup can sit in a path or a filter the way Zapier expects lookups to.
- Errors that name the API code, so an empty balance reads
INSUFFICIENT_CREDITSin the Zap history rather than a generic failure, and rate limits are retried automatically.
Nothing about the data changes between the two paths. The app calls the same endpoints with the same fields, so a Zap built on Webhooks by Zapier today can be moved over field by field later.
IP lookups
The same webhook step also looks up the address a signup or order came from. Point it at https://spaw.co/api/v1/ip with the body { "ip": "203.0.113.9" }, mapping the address your form tool or CRM records for the submission. The answer places the address on the map, names the network and its operator type, and carries tri-state flags for datacenter and cloud ranges, Tor exits, VPN exits and iCloud Private Relay, with the provider named when its own published list contains the address. risk_score is a published sum (Tor 70, datacenter 40, VPN 30, relay 10) and risk_signals lists the weights applied, so a Filter step on is_anonymous or on risk_level needs no interpretation. In the Spaw app the same call is the Look Up IP Address action, with a Privacy mode input that keeps nothing about the lookup on Spaw's side, not even the seven-day repeat marker. One credit covers five IP lookups that resolve a location, a network or a positive flag: the lookup that opens a block reports credits_used 1, the next four 0, and meta.ip_lookups_prepaid counts what is left. Reserved or private ranges, unallocated space, unknown addresses and repeats within seven days are free, and IP endpoints have their own limit of 50 requests per second.
Phone numbers
The same webhook step validates the phone number a form collected. Point it at https://spaw.co/api/v1/phone with the body { "phone": "+44 7911 012345" }, adding a country key (an ISO 3166-1 alpha-2 code such as US) when the numbers arrive without a calling code. The answer carries valid and a typed reason, the E.164 form to store and dedupe by, the national and international forms, the country and its facts, line_type and carrier with the source that settled them (the numbering plan, or the block allocation published by the regulator, which says who the numbers were allocated to and never who serves them after a port), block_status, the is_fictional, is_virtual and is_disposable flags, and a published risk_score with its risk_signals. A Filter on valid, or on is_disposable before an SMS step, needs no interpretation. Better still, filter on ok_to_send before the SMS step: it is your account's SMS policy applied to this answer (the countries and line types you send to, the signals you refuse, a ceiling on the score and, by default, the numbers your suppression list holds as opted out), and when it is false blocked_by names the rule that decided it (invalid, opted_out, country, line_type, a signal such as disposable, or risk_score; suppressed for a number on your suppression list, which batch, bulk and monitored runs honour and a single lookup never does, while a single lookup of a number the list holds as opted out answers opted_out unless the policy's block_opted_out is off), the reason to write on the record or send down the review path of a Paths step. The policy is set once on the account, not in the Zap, so every Zap, batch and bulk run applies the same rules. It is a fraud and deliverability decision, not consent and not a do-not-call scrub. In the Spaw app the same call is the Validate Phone Number action. A phone lookup costs 1 credit when the number is valid; invalid numbers, unassigned blocks and repeats within seven days are free.
A Zap that handles a list points the same step at https://spaw.co/api/v1/phone/batch with { "phones": [...] }, up to 1,000 numbers with an optional country; the app's Validate Phone Numbers action does the same from a line-item field and adds a Live carrier check input (the API's hlr). The live carrier-network check (hlr: true) is not enabled on the service: hlr_checked answers false and nothing extra is charged. After your SMS step, a second webhook (or the app's Report SMS Outcome action) posts { "items": [{ "phone": "...", "outcome": "delivered" }] } to https://spaw.co/api/v1/phone/feedback, mapping undelivered or abused from your SMS provider's status; the report is free and feeds only your own later lookups of that number. An undelivered item can carry the failure_class your provider's error code names (sender_side for a carrier filter or an unregistered campaign, permanent for a number that no longer exists), and only failures about the number count against it.
Postal addresses
The same webhook step checks the postal address on an order or a signup. Point it at https://spaw.co/api/v1/address with the body { "address": "10 Downing Street, London SW1A 2AA", "country": "GB" }, or send the parts separately as address_line1, building, locality, administrative_area, postal_code and the rest. The country is not optional in practice: it decides which format the address is read under, which parts that country requires and which postcode directory answers, and it is never guessed. The answer carries the components and the formatted address, whether the postcode matches the country's pattern and whether the directory still lists it, whether the town matches the postcode, what kind of delivery point it is (address_type), how close a national address register comes to it (match_level against the register named), the postcode centroid, how many companies are registered there, and a published risk_score with its risk_signals. Before a shipping step, filter on ok_to_ship rather than on the evidence: it is your account's shipping policy applied to this answer, and when it is false blocked_by names the rule that decided it (invalid, a signal such as placeholder, risk_score or unconfirmed; suppressed for an address on your suppression list, which batch, bulk and monitored runs honour and a single lookup never does), which is the reason to write on the record or send down the review path of a Paths step. The policy is set once on the account, not in the Zap, so every Zap, batch and bulk run applies the same rules. In the Spaw app the same call is the Validate Postal Address action, whose optional inputs are sent as separate fields and win over anything read out of the line. For a list, the same step points at https://spaw.co/api/v1/address/batch with { "addresses": [...] }, up to 100 per call.
The answer says how each part was confirmed (confirmation: the postcode, street, house number, town and region each mapped to the dataset that stood behind it, or unconfirmed) and what the parser set aside on the way (changes: a country line dropped, a care-of line removed, a building name separated from the street, …). An empty field means the signal was not evaluated, never "no". exists is true only on a premise match and false only under a register whose coverage is complete; a register whose coverage is partial, because it covers part of the country or cannot vouch for every address, cannot make an address's absence mean anything. is_mail_drop is a heuristic and not a postal service's own agency flag: an operator's own published branch list names the address, or so many companies are registered there that it is one in practice, and mail_drop_source says which. Two answers are licensed and not enabled — whether post actually arrives (deliverability_checked comes back false with is_deliverable, is_cmra, is_vacant and is_residential empty) and the list of addresses inside a postcode, which answers a typed 501 rather than a guess. An address lookup costs 1 credit when the address is valid; invalid addresses and repeats within seven days are free.
Business identifiers
The same webhook step checks the company behind a signup, an invoice or a supplier record. Point it at https://spaw.co/api/v1/entity with the body { "identifier": "213800QILIUD4ROSUO03", "type": "lei" }, or { "identifier": "01234567", "type": "company_number", "country": "GB" } for a number from a national register. The country names which register the number belongs to, because company numbers are only unique inside their own; a Legal Entity Identifier is global by construction and ignores it. The answer carries the legal name, whether the entity is still live (status, with the register's own wording in status_detail), the country and jurisdiction it was formed in, its category and legal form, when it was registered, and for a LEI checksum_valid, registration_status and next_renewal_at. Where a LEI names its entry in a national register Spaw also holds, agreements quotes both sides field by field and flags names what differs — including dissolved_in_national_register, the strongest signal the product carries, because a dissolved company no longer exists as a legal person and cannot enter a contract. In the Spaw app the same call is the Verify Business Identifier action, whose Identifier type input picks the register and whose Country input is required for a company number. For a list, the same step points at https://spaw.co/api/v1/entity/batch with { "identifiers": [...] }, up to 500 per call.
The one caveat, and it matters more than anything else here: the UK company file is a snapshot of the live register, so a company that is struck off is removed from the file rather than marked dissolved — the statuses that file carries are Active, Active - Proposal to Strike off, Liquidation, In Administration and similar, and never Dissolved. A UK dissolution therefore reaches you as found false with reason unknown_identifier rather than as that flag, which never fires on the only national register installed today. Check found before you trust the flag, and read status_detail for the earlier warning: Active - Proposal to Strike off folds to a status of active, because the company is still on the register. A LEI lookup of the same company is quieter still: GLEIF keeps its record, so found stays true and no flag fires. What moves is agreements, which comes back empty while other_register still names uk-companies-house — the counterpart row is gone. That pair is the signal on this path, and lei_registration_not_current follows later, when the lapsed registration is not renewed. A monitored list turns the disappearance into an alert of its own, left_register.
checksum_valid is a typing check and nothing more: it catches a mistyped or transposed character, while a perfectly formed LEI can never have been issued, which is what the register lookup answers. registration_status is about the identifier rather than the entity — a LEI must be reconfirmed each year and a great many are not, so LAPSED means the reference data has not been rechecked recently, not that the company has gone. Nothing in the answer is a registered address, and nothing will be: a registered address is very often somebody's home, and an identifier alone does not say whether a company or a sole trader stands behind it.
Both registers are bulk files synced onto the Spaw server, so no third party sits in the request path. The LEI reference data is published under a CC0 public-domain dedication and refreshed daily; the UK company data is used under the Open Government Licence v3.0 and republished monthly, so an answer can be up to five weeks behind the live register and every answer names the date of the copy in sources. Spaw is not affiliated with, endorsed by or connected to either publisher, and the answer is Spaw's rather than theirs. A business lookup costs 1 credit when a register carried the identifier; unknown, malformed and unsupported identifiers and repeats within seven days are free.
What to do with the verdict
Add a Filter or a Paths step right after the verification step and branch on deliverable. A deliverable answer continues to the CRM or mailing list as usual. A risky answer deserves a look at reason: catch_all and role addresses are often fine to keep with a lower priority, while disposable rarely is. An undeliverable answer should stop the Zap or route the record to a review list, and when did_you_mean is filled, for example [email protected] for [email protected], you can write the correction back instead of discarding the lead. Teams that prefer one number to branch on use risk_score, which is a published sum of weights rather than a black box.
Cost
Each Zap run that verifies an address spends 1 credit when the answer is deliverable or risky. Unverified answers, invalid input, and repeats of the same address within seven days cost nothing, and undeliverable answers cost nothing within a fair-use allowance. The Zapier task itself counts against your Zapier plan as any action does. A key may make 5 requests per second; a Zap that fires faster than that receives RATE_LIMITED with a Retry-After header, and Zapier's replay handles the rest.