Skip to content

Signal codes

A signup check reports what the signals service found about the visit in signals.findings and what it could not decide in signals.not_evaluated. Every entry is a code from this vocabulary, prefixed fp_ so it can never be confused with a verification’s reason codes.

"findings": [
{ "code": "fp_fast_submission", "class": "binding", "default_raises": true, "detail": { "since_first_token_ms": 812 } },
{ "code": "fp_network_vpn", "class": "identity", "default_raises": false }
],
"not_evaluated": ["fp_novelty_not_evaluated"],
"not_evaluated_classes": ["novelty"]

default_raises: true says the default policy treats the finding as worth asking the person to confirm their email address. It is a default, not a verdict: no finding says what a person is, and none of them can refuse a signup. A refusal only ever comes from the email verification.

Emvero follows the default. signal_codes in the answer is every finding with default_raises: true, in the order the findings came, without repeats, and a non-empty list moves an allow to allow_with_email_confirmation. Nothing moves it further, and nothing softens what the email verification answered.

Read default_raises from the finding, not from this page. Each finding carries its own value, and that is the one Emvero acted on. The tables below show the same values for reading; code that branches on the finding’s own keeps working when a code is added.

The three kinds of code:

Kind Where it appears default_raises
Raising findings true - asks for an email confirmation
Reporting findings false - reported, raises nothing
Not evaluated not_evaluated, never in findings -

A code in not_evaluated says something could not be decided, so it is not a clean result either. not_evaluated_classes lists the classes of those codes, so you can ask “were the connection’s layers compared at all?” without keeping a copy of this table.

Every code lies on exactly one class, and the set of classes is closed. If you write a policy of your own over the findings, write it over classes: it then covers a code added later, which a list of codes silently would not.

Class The question it answers
token Was there a token, and could it be read?
binding Does the token belong to this submission - the address, the browser’s self-description, the time between them?
identity What does the network, browser statement or browser probe report, including automation indicators?
novelty How common is this combination of layers in ordinary traffic?
frequency How many other signups look like this one? No code of this class is issued.
anomaly Was there a protocol irregularity, forged probe or browser-property change?
availability Could the signals service look at all?
  • A code can be added. Adding one raises signals.vocabulary_version, so a code you have not seen arrives with a version you have not seen.
  • A code can be retired. It stops being issued, and its meaning stays written down here.
  • A code never changes. Not its meaning, not its class, not its kind, not its default_raises, in any version.
  • detail can gain fields. Skip the ones you do not know.

Version 10, pinned to Emvero’s internal service source at revision c53579916601.

Raising: default_raises: true

CodeClassMeaningIssued
fp_token_absenttokenNo token came with the signup: the field was empty, the script was blocked, the page never asked for one, or the capture node could not issue one.yes
fp_token_alteredtokenThe token failed its integrity check and was not read.yes
fp_token_expiredtokenThe token had expired by the time it was checked.yes
fp_token_foreigntokenThe token is genuine, but was issued for a page key of another account than the one checking it.yes
fp_token_reusedtokenThis token was already presented in an earlier check on your account, within 70 minutes of being issued.yes, by Emvero
fp_fast_submissionbindingThe check came sooner after the first token of this page view than a person filling a form takes; `detail.since_first_token_ms` says how soon.yes
fp_ip_mismatchbindingThe address that fetched the token and the address that submitted the form differ beyond the comparison prefix.yes
fp_ua_mismatchbindingThe browser described itself differently when it fetched the token and when it submitted; `detail.fields` names what differs.yes
fp_label_botidentityA controlled run labelled a layer of the connection as a bot.retired
fp_label_impersonation_toolidentityA controlled run labelled a layer of the connection as an impersonation tool.retired
fp_label_libraryidentityA controlled run labelled a layer of the connection as an HTTP library.retired
fp_probe_automationidentityThe browser probe found automation indicators, listed in detail.flags. This finding requires email confirmation; it does not establish abuse.yes
fp_rule_violationidentityA consistency rule over the layers fired, or could not be read.retired
fp_transport_os_mismatchidentityThe transport layer pointed at a different operating system than the browser claimed.retired
fp_combination_unseennoveltyThis combination of connection layers has not been seen in ordinary traffic within the evaluation window.not in this version
fp_frequency_domainfrequencyEnough signups within the window used one email domain, popular mail services aside.retired
fp_frequency_identityfrequencyEnough signups within the window shared one combination that is rare in ordinary traffic.retired
fp_frequency_prefixfrequencyEnough signups within the window came from one network prefix.retired
fp_probe_forgedanomalyThe browser probe opened but its build checks were inconsistent. This finding requires email confirmation.yes

Reporting: default_raises: false

CodeClassMeaningIssued
fp_ip_samebindingThe token was fetched from the same address that submitted the form.yes
fp_ip_same_prefixbindingThe two addresses differ but share a comparison prefix (`detail.prefix`: `v4/24` or `v6/64`).yes
fp_client_claim_conflictidentityThe User-Agent and the client hints of the same request disagree with each other.yes
fp_client_tls_mismatchidentityThe browser engine the User-Agent implies is not the one clients with this TLS handshake usually claim. An app with its own network stack looks the same.yes
fp_client_tls_version_mismatchidentityThe claimed Chromium version is older or newer than the handshake it arrived with. An app writing a fresh version over an older system WebView looks the same.yes
fp_label_otheridentityA layer carried a label that raises nothing: not from a controlled run, or of another type.retired
fp_network_geo_rtt_mismatchidentityThe round trip was too short for the distance the address's location implies.yes
fp_network_hostingidentityThe connection that fetched the token came from a hosting network. Reported only: iCloud Private Relay and WARP arrive through such networks.yes
fp_network_private_relayidentityThe token's connection came from an iCloud Private Relay egress address.yes
fp_network_public_proxyidentityThe token's connection came from an address on a public proxy list.yes
fp_network_rtt_gapidentityThe connection's HTTP/2 round trip is much longer than its TCP round trip, the way a connection ending at an intermediary looks.yes
fp_network_stack_platform_mismatchidentityThe TCP stack of the connection points at a different operating system than the browser claims.yes
fp_network_toridentityThe token's connection came from a Tor exit.yes
fp_network_vpnidentityThe token's connection came from an address on a public VPN list.yes
fp_timezone_claim_conflictidentityThe browser's IANA time zone does not match its own UTC offset.yes
fp_timezone_offset_mismatchidentityThe browser's UTC offset differs from the offset at the address's location.yes
fp_transport_intermediaryidentityThe transport layer belonged to a declared intermediary, so its operating system was not compared.retired
fp_combination_rarenoveltyThe combination has been seen in ordinary traffic, but is not among the common ones.not in this version
fp_anomalyanomalyThe connection that fetched the token had protocol irregularities, listed in `detail.flags`. A signal, not a violation.yes
fp_probe_tamperinganomalyNative browser properties were changed, listed in detail.flags. Informational: browser extensions and page code can also cause this.yes

Not evaluated: in not_evaluated

CodeClassMeaningIssued
fp_ip_not_comparablebindingThe two addresses are of different families, IPv4 and IPv6, and were not compared.yes
fp_ip_not_suppliedbindingAddresses were not compared: no `ip` was sent, it could not be read, or there was no token.yes
fp_ua_not_suppliedbindingSelf-descriptions were not compared: no `user_agent` was sent, or there was no token.yes
fp_client_claims_not_evaluatedidentityThe client's claims could not be compared with each other.yes
fp_client_tls_not_evaluatedidentityThe claimed engine could not be compared with the TLS handshake.yes
fp_client_tls_version_not_evaluatedidentityThe claimed Chromium version could not be compared with the TLS handshake.yes
fp_layer_absentidentityNo findings about the connection's layers could be made: the token carries none.yes
fp_layer_unlabelledidentityNo layer of the token carried a label, or labels were not checked.retired
fp_network_intelligence_not_evaluatedidentityAt least one of the public network lists was unavailable; `network` says which.yes
fp_network_measurements_not_evaluatedidentityThe connection's network measurements were not available to compare.yes
fp_network_not_evaluatedidentityThe kind of network the token's connection came from could not be established.yes
fp_no_rulesidentityNo consistency rules were applied.retired
fp_probe_not_evaluatedidentityThe browser probe was absent, unreadable, from an unknown or retired build, or could not finish a group of checks. A usable token can still be evaluated.yes
fp_timezone_not_evaluatedidentityThe browser's time zone was not compared with the address's.yes
fp_transport_unavailableidentityThe transport layer's operating system was not compared.retired
fp_novelty_not_evaluatednoveltyThe current service does not evaluate combination rarity or novelty; the token slots remain unavailable.yes
fp_client_part_not_evaluatedavailabilityThe signals service did not evaluate the visit at all.yes
fp_version_supersededavailabilityThe token's layers were computed under a different rules version than the signals service now runs, so they were not compared.yes
fp_working_set_unavailableavailabilityThe set of observations the visit is compared against was not ready.retired

fp_probe_forged and fp_probe_automation require confirmation when email would otherwise allow. fp_probe_tampering is informational. Missing or incomplete probe checks are reported as fp_probe_not_evaluated; a usable token can still produce an evaluated, billable check. This is different from a whole-service unavailable result.

Automation indicators do not prove abuse. Some developer tools also trigger the CDP indicator; the rule discounts a detected docked desktop DevTools panel, but a separate DevTools window or mobile remote debugging can still appear.

Besides the findings, an evaluated answer carries the node’s comparisons as reports. Every yes in a report’s checks is also a finding, and every unavailable is also a not_evaluated code; the reports say which checks ran and what was not carried. A check is yes, no or unavailable.

Report Fields Check → finding
network One entry per public list - vpn, public_proxy, tor, private_relay - each with status (listed, not_listed or unavailable) and, when unavailable, reason (address_unavailable, not_configured, source_unavailable, source_stale, unsupported_address_family); source, fetched_at and source_updated_at name the list listed → fp_network_vpn, fp_network_public_proxy, fp_network_tor, fp_network_private_relay
transport rules_version; status - available, not_observed or rules_version_unknown; provenance is not_carried stack_platform_mismatch → fp_network_stack_platform_mismatch, rtt_gap → fp_network_rtt_gap, geo_rtt_mismatch → fp_network_geo_rtt_mismatch
timezone browser (source browser_claim) and ip (source geoip), each with status: not_carried - the token carries the outcome, not the zones offset_mismatch → fp_timezone_offset_mismatch, claim_conflict → fp_timezone_claim_conflict
client_claims status: available, hints: not_carried; tls.status - match, mismatch, labels_unavailable, unlabeled, no_claim or not_evaluated; tls_version with status (consistent, claim_newer, claim_older, version_unknown, no_claim, unlabeled, labels_unavailable), claimed_version and epoch conflict → fp_client_claim_conflict; tls.status: mismatch → fp_client_tls_mismatch; a version mismatch → fp_client_tls_version_mismatch
probe (v13) status - ok, forged, absent, malformed, build_unknown, build_retired or unknown; build forged → fp_probe_forged, automation → fp_probe_automation, tampering → fp_probe_tampering

A report can gain fields; skip the ones you do not know.

Since token v13, responses carry signals.notes and signals.notes_version. Notes are separate from findings: they have no default_raises, do not enter signal_codes and do not change the default action. Each entry contains code, value, rules_version and group.

Notes vocabulary 2:

CodeGroupValues
rtt_extra_legpathunavailable, none, far
webtransportpathunavailable, not_attempted, unsupported, failed, timeout, ok, refused
ua_brandclientunavailable, named, generic_chromium, hints_missing
bot_claimclientunavailable, none, crawler_verified, crawler_unverified, crawler_unchecked, tool
bot_operatorclientunavailable, google, apple, meta, microsoft, yandex, baidu, huawei, openai, anthropic, other

rtt_extra_leg describes a pattern in TCP, TLS and HTTP/2 timing; webtransport records the optional session’s outcome; ua_brand describes the browser’s brand statement. They do not establish that a connection is a proxy or abusive. bot_claim reports a declared crawler inside its operator’s network (crawler_verified), outside that network (crawler_unverified), a crawler with no supported operator check (crawler_unchecked), a declared tool (tool) or no such claim (none). bot_operator names the declared crawler’s operator. These are notes, including crawler_unverified: none changes the default action. none does not establish a human visitor. unavailable means the note could not be evaluated. There are no repeat-visit counters or farm-cluster notes, and a declared tool is not currently a raising signal.

Observations in one group can describe the same cause, so do not treat them as independent proof. Under a newer note vocabulary, an unrecognized value can be reported as unknown. Neither that value nor unavailable means the whole signal service was unavailable.