Signup protection
Check the visit, not only the address.
A script on your signup page gets a visit token while the form is open. Your server sends the token to Emvero with the address and the visitor's connection details, and gets one recommended action for the signup with the codes that explain it.
Signals never reject a signup on their own. When a finding raises the decision, a signup that would have been allowed is asked for email confirmation instead. Only the email check can reject an address.
Invitation-only pilot · Server-side API · 1 credit per evaluated check
Signup protection adds signals about the visit to the check you already run on the address. It is for signups whose address passes but whose request does not match the visit that should have produced it: a form posted without the page being loaded, a token reused from an earlier session, a submission made a moment after the page was served.
Signals do not identify the person and do not prove abuse. Each finding is evidence for your own rules, and the recommended action never goes beyond email confirmation.
Add the token to your signup page
In your account, open Signup protection and create a page key for the origin of your signup page, such as https://example.com. A page key is not a secret: anyone who loads the page can read it, and it works only from the origins you list on it.
The snippet in your account adds a hidden field and a small script. When the form is shown, the script asks the token node for a visit token and writes it into the field, and your form submits the field with everything else. If the script is blocked or the node does not answer, the field stays empty, and the check asks for email confirmation rather than refusing the signup. The documentation covers the script, its version and the Content-Security-Policy lines your page needs.
Send the token from your server
At signup, your server sends the token with the address and the visitor’s connection details to POST /v1/signup-checks. It uses the same API credential as email verification, and the credential stays on your server.
curl -sS https://api.emvero.tech/v1/signup-checks \
-H "Authorization: Bearer emv_your_credential" \
-H "Content-Type: application/json" \
-d '{"email":"ada@example.com","token":"<value of the fp_token field>","ip":"203.0.113.7","user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..."}'
Client Hints, when your server receives them, go in a client_hints object. The response carries one action for the signup, the signal_codes that raised it, the full email result and the signals. These selected fields illustrate a possible result; they are not a measurement:
{
"id": "0b8e6f2a-4d1c-4f7e-9a3b-2c5d6e7f8a90",
"action": "allow_with_email_confirmation",
"signal_codes": ["fp_fast_submission"],
"email": { "status": "deliverable", "action": "allow", "reason_codes": [] },
"signals": {
"status": "evaluated",
"findings": [
{ "code": "fp_fast_submission", "class": "binding", "default_raises": true },
{ "code": "fp_network_vpn", "class": "identity", "default_raises": false }
]
}
}
Here the address is deliverable, and the email check alone would allow it. The form was submitted very soon after the page received its token, a finding that raises the decision, so action is allow_with_email_confirmation and signal_codes names the reason. The visitor was also on a VPN: the finding is reported, but on its own it does not raise the decision.
If you already check the address elsewhere, POST /v1/signup-signals takes the same request without email and answers as if the email check had returned allow.
How signals change the decision
Signals can raise allow to allow_with_email_confirmation. They never raise a decision to reject and never soften the email check’s decision.
| Email check | Signals | Recommended action |
|---|---|---|
reject | Any | reject |
allow_with_email_confirmation | Any | allow_with_email_confirmation |
allow | Evaluated, nothing raises the decision | allow |
allow | Evaluated, a finding raises the decision | allow_with_email_confirmation |
allow | No usable token | allow_with_email_confirmation |
allow | Signals unavailable | allow |
When the email check is still pending, the signals are already final and action is allow_with_email_confirmation. Retrieve GET /v1/signup-checks/{id} after email.retry_after_ms: polling is free, and the action is worked out again from the finished email result and the saved signal codes.
What the signals look at
- The token. A token that is missing, expired, altered, issued for another account’s pages or presented a second time raises the decision.
- The visit against the request. A different IP address or browser at submission from the one the token was issued to raises the decision, and so does a submission made very soon after the first token.
- The network and the browser’s claims. VPNs, Tor, public proxies, private relays, hosting networks, and a time zone or platform that does not match the connection are reported for your own rules. They do not raise the decision on their own.
Every finding carries default_raises, which says whether it raises the decision. The result keeps the findings that do not, so your application can apply its own rules to them. The documentation lists every code.
The signals service also builds a list of addresses and networks recently seen acting as relays on your pages. GET /v1/relay-list returns it free of charge, within a per-minute limit, so you can check requests that never loaded your page, such as a mobile app’s call to your API.
What a check costs
| Signals result | Credits |
|---|---|
Token evaluated (evaluated) | 1 credit |
No usable token (token_unusable) | 0 credits |
Signals unavailable (unavailable) | 0 credits |
A combined check also charges the email verification exactly as POST /v1/verifications does. Issuing tokens, polling a pending check and fetching the relay list are free. Everything uses the shared account balance; when it cannot cover a check, the check answers 402 before any work starts.
What happens to visitor data
Your server sends the token, the visitor’s IP address, User-Agent and Client Hints. Emvero passes them to the signals service to evaluate the check and does not keep them in its logs or storage; the saved result holds no IP address or part of one. The signals service receives a client code for your account, never your account’s email address or ID. Results are kept for 30 days, as email checks are.
During the pilot, each participant signs a separate written agreement that covers how the signals service processes visitor data.
Manage it in your account
Once signup protection is enabled, your account shows its status, your page keys with their origins, the snippet for each key and the connections recorded with your keys each day. You can revoke a key at any time. To switch signup protection off and delete its data, write to us.
Questions
Frequently asked.
What does signup protection check?
It compares the visit with the signup request. A script on your page gets a token when the form is shown; at signup, your server sends that token with the visitor's IP address, User-Agent and Client Hints. The findings show, for example, a submission made very soon after the token was issued, a different IP address or browser from the visit, or a token that is missing, expired, altered, issued for another account's pages or used twice.
Can signals reject a signup?
No. Signals never raise the decision to reject and never soften the email check's decision. When a finding raises the decision, allow becomes allow_with_email_confirmation. Only the email check can return reject.
How much does a check cost?
The signals cost 1 credit when the token is evaluated, and nothing when no token can be used or the signals are unavailable. A combined check also charges the email verification exactly as POST /v1/verifications does. Issuing tokens, polling a pending check and fetching the relay list are free.
What happens if the script is blocked?
The hidden field stays empty, and the check reports fp_token_absent, which raises the decision to email confirmation. If the signals service does not answer, signals.status is unavailable: the decision is the email check's alone and the signals are not charged.
What visitor data does the check use?
The token, the visitor's IP address, User-Agent and Client Hints, which your server sends. Emvero passes them to the signals service for the check and does not keep them in its logs or storage. The signals service receives a client code for your account, not your account's email address or ID. During the pilot, a separate written agreement covers how the signals service processes visitor data.
How do I get access?
Signup protection is in an invitation-only pilot. Contact us with the site your signup form is on and the volume you expect. Once a written agreement is in place, we enable it on your account. You then create page keys and copy the snippet in your account.
Invitation-only pilot
Ask to join the pilot.
Signup protection is available by invitation while the pilot runs. Tell us which site your signup form is on and how many signups you expect. We enable it on your account once a separate written agreement is in place.