Auto-Screen Form Submissions with n8n
Build a no-code workflow that automatically checks phone numbers from form submissions using the ScamVerify™ API.
This tutorial walks you through building an n8n workflow that automatically screens phone numbers submitted through web forms. When someone fills out your contact form, the workflow calls the ScamVerify™ API, evaluates the risk score, and routes the submission to the right team. Legitimate leads go straight through while suspicious ones get flagged for manual review.
Prerequisites
- n8n (self-hosted or n8n Cloud)
- A ScamVerify™ API key (get one at scamverify.ai/settings/api)
- A form or webhook source (Typeform, HubSpot, custom form, etc.)
What You Will Build
An automated workflow that:
- Receives form submissions via webhook
- Extracts the phone number field
- Calls the ScamVerify™ phone lookup API
- Routes submissions based on verdict (approve, review, or reject)
- Sends notifications for each outcome
Create the webhook trigger
Open n8n and create a new workflow. Add a Webhook node as the trigger.
Configure the webhook:
- HTTP Method: POST
- Path:
form-screening(this creates a URL likehttps://your-n8n.com/webhook/form-screening) - Authentication: None (or add header auth for production)
- Response Mode: Last Node (so the form gets a response after processing)
The webhook expects a JSON body like this:
{
"name": "Jane Smith",
"email": "jane@example.com",
"phone": "+15551234567",
"message": "I'd like to learn more about your services."
}Point your form's submission handler to this webhook URL. Most form builders (Typeform, Tally, JotForm) support webhook integrations natively.
Add the ScamVerify™ API call
Add an HTTP Request node after the Webhook node.
Configure it:
- Method: POST
- URL:
https://scamverify.ai/api/v1/phone/lookup - Authentication: Predefined Credential Type > Header Auth
- Name:
Authorization - Value:
Bearer sv_live_your_key_here
- Name:
- Body Content Type: JSON
- Body Parameters:
{
"phone_number": "{{ $json.phone }}"
}Alternatively, you can set up the header auth as a reusable credential in n8n:
- Go to Credentials in n8n
- Create a new Header Auth credential
- Set Name to
Authorizationand Value toBearer sv_live_your_key_here - Select this credential in the HTTP Request node
Using a reusable credential keeps your API key in one place. If you rotate the key, you only need to update the credential, not every node.
Add the routing logic
Add a Switch node after the HTTP Request node. This routes submissions to different paths based on the ScamVerify™ verdict.
Configure three outputs:
Output 1: Approve (safe or low risk)
- Condition:
{{ $json.verdict }}is equal tosafeOR{{ $json.verdict }}is equal tolow_risk
Output 2: Review (medium risk)
- Condition:
{{ $json.verdict }}is equal tomedium_risk
Output 3: Reject (high risk or scam)
- Condition:
{{ $json.verdict }}is equal tohigh_riskOR{{ $json.verdict }}is equal toscam
You can also route by numeric score instead of verdict:
- Approve:
{{ $json.risk_score }}is less than 30 - Review:
{{ $json.risk_score }}is between 30 and 69 - Reject:
{{ $json.risk_score }}is greater than or equal to 70
Handle approved submissions
Connect the Approve output to your normal lead processing flow. Here are some common options:
Option A: Send to Google Sheets
Add a Google Sheets node:
- Operation: Append Row
- Sheet: Your leads spreadsheet
- Columns: Map
name,email,phone,messagefrom the webhook data, and addrisk_scoreandverdictfrom the API response
Option B: Send to a CRM
Add an HTTP Request node to your CRM's API (HubSpot, Salesforce, etc.) with the lead data.
Option C: Send an email notification
Add a Send Email node:
- To: sales@yourcompany.com
- Subject:
New Lead: {{ $('Webhook').item.json.name }} - Body:
New lead submission (verified clean):
Name: {{ $('Webhook').item.json.name }}
Email: {{ $('Webhook').item.json.email }}
Phone: {{ $('Webhook').item.json.phone }}
Message: {{ $('Webhook').item.json.message }}
ScamVerify Score: {{ $json.risk_score }}/100 ({{ $json.verdict }})Handle flagged submissions
Connect the Review output to a notification node that alerts your team for manual review.
Add a Slack node (or email, Discord, Teams, etc.):
- Channel:
#lead-review - Message:
:warning: Flagged submission needs review:
Name: {{ $('Webhook').item.json.name }}
Phone: {{ $('Webhook').item.json.phone }}
Risk Score: {{ $json.risk_score }}/100
Verdict: {{ $json.verdict }}
Explanation: {{ $json.explanation }}
Review and approve/reject in your CRM.Handle rejected submissions
Connect the Reject output to a logging and notification flow.
Add a Google Sheets node (or database):
- Operation: Append Row
- Sheet: "Rejected Submissions" spreadsheet
- Columns:
name,email,phone,risk_score,verdict,explanation,timestamp
Optionally add a Send Email node to notify the submitter:
- To:
{{ $('Webhook').item.json.email }} - Subject:
We received your submission - Body: A polite generic response (do not reveal the fraud screening)
Never tell rejected users they were flagged for fraud. Use a neutral response like "We'll be in touch if there's a fit." This prevents scammers from learning how to bypass your screening.
Add error handling
Add an Error Trigger node to catch API failures. Connect it to a Send Email or Slack node that notifies your team.
Common errors to handle:
- 401: Invalid API key. Check your credentials.
- 402: Quota exhausted. The workflow will fail until you upgrade or wait for reset.
- 429: Rate limited. Add a Wait node (60 seconds) before retrying.
For the rate limit case, you can add a Wait node followed by a copy of the HTTP Request node to automatically retry after the cooldown.
Import the workflow JSON
If you prefer to import the complete workflow, here is the n8n JSON. Go to Workflows > Import from File and paste this:
{
"name": "ScamVerify Form Screening",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "form-screening",
"responseMode": "lastNode"
},
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"position": [250, 300]
},
{
"parameters": {
"method": "POST",
"url": "https://scamverify.ai/api/v1/phone/lookup",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "phone_number",
"value": "={{ $json.phone }}"
}
]
}
},
"name": "ScamVerify Lookup",
"type": "n8n-nodes-base.httpRequest",
"position": [470, 300]
},
{
"parameters": {
"rules": {
"rules": [
{
"output": 0,
"conditions": {
"conditions": [
{ "leftValue": "={{ $json.risk_score }}", "rightValue": 30, "operator": { "type": "number", "operation": "lt" } }
]
}
},
{
"output": 1,
"conditions": {
"conditions": [
{ "leftValue": "={{ $json.risk_score }}", "rightValue": 70, "operator": { "type": "number", "operation": "lt" } }
]
}
},
{
"output": 2,
"conditions": {
"conditions": [
{ "leftValue": "={{ $json.risk_score }}", "rightValue": 70, "operator": { "type": "number", "operation": "gte" } }
]
}
}
]
}
},
"name": "Route by Risk",
"type": "n8n-nodes-base.switch",
"position": [690, 300]
}
],
"connections": {
"Webhook": { "main": [[{ "node": "ScamVerify Lookup", "type": "main", "index": 0 }]] },
"ScamVerify Lookup": { "main": [[{ "node": "Route by Risk", "type": "main", "index": 0 }]] }
}
}After importing, add your destination nodes (Google Sheets, Slack, email) to each of the three Switch outputs.
Next Steps
- Add URL screening by calling the
/url/lookupendpoint when the form includes a website field - Use the batch endpoint to screen multiple leads at once
- Set up a daily summary workflow that reports how many submissions were approved, flagged, and rejected
- Add text message screening by piping the form's "message" field through the
/text/analyzeendpoint