HubSpot workflows can call an external URL and use the answer in later actions, which is all a verification step needs. The webhook action is part of Data Hub Professional and Enterprise; on other tiers, the same result comes from a Zap or a Make scenario that triggers on a new contact. No HubSpot app is required in either case, and Spaw does not ask for access to your portal. The same kind of workflow validates the contact's phone number, as the phone section below shows.
Verify new contacts with a workflow webhook
- Create a secret API key on the API keys page of your Spaw dashboard.
- Create three contact properties to hold the answer: a single-line text property for the verdict, one for the reason, and a number property for the risk score. Internal names such as
spaw_verdict,spaw_reasonandspaw_risk_scorekeep them easy to find. - Create a contact-based workflow whose enrollment trigger is a contact whose email is known, re-enrolling when the email changes.
- Add the webhook action. Set the method to POST and the URL to
https://spaw.co/api/v1/email. - Choose API-key authentication for the request. The header name is
Authorizationand the value isBearer sk_live_…; HubSpot stores the value as a secret so it never appears in the workflow itself. - Customize the request body so it contains only the contact's email under the key
email:
{
"email": "[email protected]"
}
- Turn on the option that includes the response as data. After the action runs once in a test, the response fields become available to later actions under
data, for exampledata.deliverable,data.reason,data.risk_scoreanddata.did_you_mean. - Add a property-setting action that copies
data.deliverableinto your verdict property, and two more for the reason and the score. - Add a branch on the verdict property. Test the workflow by enrolling a contact whose email is
[email protected]; it answers a canonical result, costs nothing and never appears in your Spaw history.
The full list of fields the webhook receives is on the single-address endpoint page. Everything in it can be written to a property the same way.
Other tiers: Zapier or Make
Without the webhook action, use a new-contact trigger from HubSpot in Zapier or Make, a Spaw verification step (Webhooks by Zapier or Make's HTTP module today, the Spaw apps once they are listed), and an update-contact action that writes the three properties. The Zapier page has the exact request. The workflow branches described below then run on the properties as usual.
Existing contacts
For the contacts already in the portal, export the emails, run them through a bulk verification on the Spaw dashboard or the API, and import the result CSV back into HubSpot with the verdict column mapped to the property. The list cleaning checklist covers what to do with each verdict on an old list.
What to do with the verdict
Branch the workflow on the verdict property. deliverable contacts go on to marketing emails and sequences. For risky contacts, look at the reason: catch_all means the domain accepts everything and the mailbox is unconfirmed, role means a shared inbox such as info@; both are usually worth keeping out of cold sequences but fine for transactional mail. undeliverable contacts should be set to not marketing-eligible or handed to a review list, and when data.did_you_mean is filled, an internal notification with the suggested address is the fastest way to recover the lead.
Phone numbers
A second contact-based workflow validates the phone number with the same webhook action. Its enrollment trigger is a contact whose phone number is known, re-enrolling when the number changes, so an edited number is checked again.
- Create four single-line text contact properties for the answer, for example
spaw_phone_e164,spaw_line_type,spaw_ok_to_sendandspaw_blocked_by. - Add the webhook action with the method POST, the URL
https://spaw.co/api/v1/phoneand the same API-key authentication as the email step. - Customize the request body so it carries the contact's Phone Number under
phoneand its Country/Region Code undercountry. Nothing else about the contact is needed.
{
"phone": "(202) 555-0100",
"country": "US"
}
- Turn on the option that includes the response as data, and add property-setting actions that copy
data.e164,data.line_type,data.ok_to_sendanddata.blocked_byinto the four properties.data.e164is the form to store and dedupe by; it is also kept for an invalid number in a block nobody holds, so read it together withspaw_ok_to_send, which is false for every invalid number. - Branch on
spaw_ok_to_sendbefore any step that texts the contact. Contacts where it is false go to a review list withspaw_blocked_byas the reason:invalidfor a number that is not valid,disposablefor one published on an SMS-receiving website, and so on. - Test the workflow with +1 202 555 0100 and +1 202 555 0103, two documented test numbers that cost nothing: the first answers a valid mobile with
ok_to_sendtrue, the secondok_to_sendfalse withblocked_bydisposable, under the default SMS policy.
Map Country/Region Code, not Country/Region. HubSpot describes Country/Region Code as "the two letter country code where the contact is located (e.g., US)" (HubSpot's list of default contact properties, read 27 September 2026), which is the kind of code the API expects: ISO 3166-1 alpha-2. HubSpot describes Country/Region only as the contact's country of residence, and it can hold a name such as "United States"; a name, or UK (the United Kingdom's code is GB), is refused with a 422 and the error code VALIDATION_FAILED. An empty country is read as none. A number stored with its + and calling code needs no country at all; a national number sent without one answers valid: false with the reason missing_country, free.
ok_to_send is your account's SMS policy applied to the 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, set once on the account so every workflow, 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. line_type comes from the numbering plan or, for a North American number, from the holder of its block in the regulator's table; it describes how the range was allocated, never the network that serves the number after a port, and an ordinary US number answers fixed_line_or_mobile unless its block holder settles the type (why). Leave the complaint counts (complaints_90d, complaints_last_at) off contact records: they count the complaints consumers sent the FTC naming a number as the caller, which is not the Do Not Call Registry and says nothing about whether you may call or text the number, and the reports are unverified, with caller ID often spoofed. Every field is on the phone endpoint page.
On tiers without the webhook action, run the phone check as a second Zap or scenario on the same new-contact trigger: a filter that continues only when the phone number is filled (an empty phone is refused with a 422), a step that posts the same body to https://spaw.co/api/v1/phone, and an update-contact action of its own that writes the four properties. Kept apart from the email flow, a contact without a phone number still gets its email verdict. The Zapier page covers the request.
Cost
Each enrollment that answers deliverable or risky spends 1 credit; unverified answers and repeats of the same address within seven days are free, and undeliverable answers are free within a fair-use allowance. A re-enrollment after an email edit is a new address and bills normally. A phone lookup costs 1 credit when the number is valid; invalid numbers, unassigned blocks and repeats of the same number within seven days are free. Email lookups are limited to 5 requests per second and phone lookups to 50, in separate buckets; HubSpot spreads workflow actions out enough that this rarely matters, but a bulk enrollment of thousands of contacts should be done through a bulk run instead.