Make (formerly Integromat) scenarios are a natural place for a verification step, because a router can send each address down a different branch depending on the verdict. Spaw has no special requirements: the API speaks JSON over HTTPS with a bearer token, which is exactly what Make's HTTP module sends. A dedicated Spaw app for Make is built and waiting for Make's review; until it is available, the HTTP module gives you every field the app will.
What works today: the HTTP module
- Create a secret API key on the API keys page of your Spaw dashboard. Keep it out of scenario names and notes; it starts with
sk_live_. - In your scenario, add the HTTP module and pick the action that makes a request (it is the one that lets you set the method, headers and body by hand).
- Set the URL to
https://spaw.co/api/v1/emailand the method to POST. - Add two headers:
Authorizationwith the valueBearer sk_live_…, andContent-Typewith the valueapplication/json. - Set the body type to raw, the content type to JSON, and the request content to the JSON below, mapping the address from the module before it.
- Turn on response parsing so the answer's fields become mappable in the modules that follow.
{
"email": "{{1.email}}"
}
Run the scenario once with [email protected] as the address. It answers a canonical deliverable result, costs no credits and is never logged, so you can wire the whole flow before spending anything.
The parsed response carries data with every field of a single-address lookup and meta with credits_used, credits_remaining and cache_hit. For a scenario that processes a list, use an array aggregator to collect up to 50 addresses, send them as { "emails": [...] } to https://spaw.co/api/v1/email/batch, and iterate over data.results. The batch endpoint answers in input order and counts as one request against the rate limit.
To check only a domain, for example before enriching a company record, call GET https://spaw.co/api/v1/email/domain/acme.com with the same header. The domain endpoint answers whether the domain receives mail, who runs its mail, its SPF and DMARC status and its registration age.
The Spaw app for Make
The app packages the same calls as modules with a saved connection, so nobody has to paste headers:
- A connection named Spaw API key that stores the secret key and verifies it against your account.
- Modules: Verify an Email, Verify Emails (up to 50), Get Domain Intelligence, Add to Suppression List, Look Up an IP Address, Validate a Postal Address, Verify a Business Identifier, Validate a Phone Number, Validate Phone Numbers (up to 1,000, with a shared Country and a Live carrier check parameter), Report an SMS Outcome (delivered, undelivered, abused, verified or opted out, free), and Report an IP Outcome (abuse, fraud, bot or chargeback, free).
- Errors mapped to Make's own types: a rejected key stops the scenario with an authentication error, a rate limit raises a rate-limit error Make can retry, and everything else reports the API's message.
It is not in Make's app catalogue yet. This page will link the app when Make has finished its review. Scenarios built on the HTTP module keep working unchanged either way.
IP lookups
The HTTP module looks up the address behind a signup or an order the same way: URL https://spaw.co/api/v1/ip, method POST, the same two headers, and the request content {"ip": "{{1.ip}}"} mapped from the module that recorded the visitor's address. The parsed answer's data block carries the location, the network and its operator type, tri-state flags for datacenter and cloud ranges, Tor exits, VPN exits and iCloud Private Relay with the provider named when its own list contains the address, is_anonymous, and a published risk_score with its risk_signals, so a router filter on is_anonymous or on risk_level needs no interpretation. In the Spaw app the same call is the Look Up an IP Address module, with a Privacy mode parameter that keeps nothing about the lookup on Spaw's side. 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 HTTP module validates a phone number the same way: URL https://spaw.co/api/v1/phone, method POST, the same two headers, and the request content {"phone": "{{1.phone}}"}, with a country key (an ISO 3166-1 alpha-2 code such as US) when the numbers are written without a calling code. The parsed answer's data block carries valid and a typed reason, the E.164, national, international and tel: 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, so a router filter on valid or on is_disposable needs no interpretation. Route on ok_to_send before the SMS module rather than on the evidence: 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 on the false route 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 policy is set once on the account, not in the scenario, so every scenario, 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 a Phone Number module. A phone lookup costs 1 credit when the number is valid; invalid numbers, unassigned blocks and repeats within seven days are free.
A scenario that processes a list aggregates up to 1,000 numbers and sends {"phones": [...]} to https://spaw.co/api/v1/phone/batch, with an optional country; the app's Validate Phone Numbers module is a search over the same call that iterates one bundle per number and adds a Live carrier check parameter (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 the SMS module, the HTTP module (or the app's Report an SMS Outcome module) posts {"items": [{"phone": "{{1.phone}}", "outcome": "delivered"}]} to https://spaw.co/api/v1/phone/feedback, with undelivered or abused mapped from the 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 HTTP module checks the postal address on an order the same way: URL https://spaw.co/api/v1/address, method POST, the same two headers, and the request content {"address": "{{1.address}}", "country": "GB"}, or 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 parsed answer's data block carries the components and the formatted address, postal_code_valid and postcode_status, whether the town matches the postcode, address_type with the source that settled it, match_level against the register named, the postcode centroid, companies_registered, and a published risk_score with its risk_signals. Route on ok_to_ship rather than on the evidence: it is your account's shipping policy applied to this answer, so a router with one filter on ok_to_ship true and one on false needs no interpretation, and on the false route 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) — the reason to write back to the order or hand to whoever reviews it. The policy is set once on the account, not in the scenario, so every scenario, batch and bulk run applies the same rules. In the Spaw app the same call is the Validate a Postal Address module, whose optional parameters are sent as separate fields and win over anything read out of the line. A scenario that processes a list aggregates up to 100 addresses and sends {"addresses": [...]} to https://spaw.co/api/v1/address/batch.
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 HTTP module checks a company the same way: URL https://spaw.co/api/v1/entity, method POST, the same two headers, and the request content {"identifier": "{{1.lei}}", "type": "lei"} — or {"identifier": "{{1.company_number}}", "type": "company_number", "country": "GB"}, because a company number is only unique inside its own register and the country says which one, while a Legal Entity Identifier is global by construction and ignores it. The parsed answer's data block carries the legal name, status with the register's own status_detail, the country and jurisdiction of formation, the category and legal form, registered_at and record_updated_at, 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, so a router filter on dissolved_in_national_register needs no interpretation: 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 a Business Identifier module. A scenario that processes a list aggregates up to 500 identifiers and sends {"identifiers": [...]} to https://spaw.co/api/v1/entity/batch.
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: 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. 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
Put a router after the verification module with one filter per outcome. Route deliverable answers straight on. Send risky answers through a second filter on reason: a catch_all domain or a role inbox is usually worth keeping with a note, a disposable domain usually is not. Stop undeliverable answers, or write did_you_mean back to the source when it is filled, since a corrected typo is a recovered lead rather than a lost one. If you would rather compare a single number, risk_score is 0 to 100 and its weights are documented in the risk score guide.
Cost
Every verified address that answers deliverable or risky spends 1 credit; unverified answers, invalid input and repeats within seven days are free, and undeliverable answers are free within a fair-use allowance. Make counts its own operations separately. The API accepts 5 requests per second per key, so a scenario that bursts through a large list should use the batch endpoint or a short sleep between iterations.