> ## Documentation Index
> Fetch the complete documentation index at: https://docs.verisoul.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Changelog

> New features and improvements across the Verisoul API, SDKs, and dashboard

Everything we ship that changes what you can see or do.

<Update label="October 1, 2026" description="Exclude personal data from ID Check responses" tags={["API", "Verifications"]} rss={{ title: "Exclude personal data from ID Check responses" }}>
  ## Exclude personal data from Verify ID

  Add `?excludePII=true` to `POST /liveness/verify-id` and the response leaves out `document_data`, `photo_urls`, and `video_urls`. Everything else is unchanged. Without the parameter you get the full response, as before. Webhooks are not affected.
</Update>

<Update label="September 17, 2026" description="List endpoints, ID Check name signals, and faster account grids" tags={["API", "Verifications", "Dashboard"]} rss={{ title: "List endpoints, ID Check name signals, and faster account grids" }}>
  ## Move accounts between lists, and update a list description

  `PATCH /list/{list_name}` updates the description on a list.

  `POST /list/{list_name}/account/move` moves up to 1,000 accounts to another list in one call, and returns an outcome per account, such as `moved`, `conflict`, or `not_found`.

  ## Name signals on ID Check

  Document signals include `name_not_found`, which fires when the name is missing from the document, and `name_partially_missing`, which fires when only part of it is found. Both work as rule conditions.

  ## Authenticate rejects a body that is missing an account

  `POST /session/authenticate` returns `400` when the request body is missing a usable `account` object, for example when the keys arrive capitalized as `Account` and `Session_id`. These requests returned `500` before, so error handling keyed on the status code sees the new value.

  ## Account grids load in seconds

  Opening a list's accounts on a large project takes seconds. Measured on a project with 75 million accounts: the block list page at 3.5 seconds, down from 100 to 300 seconds, an unfiltered page at 2.6 seconds, a country filter at 2.8 seconds, and a 4.2 million member list at 3.3 seconds.
</Update>

<Update label="September 10, 2026" description="Analyze with AI on verifications, and incomplete session review" tags={["Dashboard", "Verifications"]} rss={{ title: "Analyze with AI on verifications, and incomplete session review" }}>
  ## Analyze with AI on ID Check and Face Match

  The AI investigation panel runs on verification sessions. The liveness video analysis and the captured photos feed into it.

  On accounts, the analysis reads your project's own scoring thresholds, the definitions of the lists the account is on, and the conditions of the rules it hit.

  ## Incomplete verification sessions

  ID Check and Face Match sessions that ended before they completed open from the grid. Photos and videos captured up to that point are in their tabs, and the sections that need a finished session carry a placeholder explaining what is missing.
</Update>

<Update label="August 27, 2026" description="Custom dashboards for everyone, digital ID signals, and rule building" tags={["Dashboard", "Verifications", "Rules"]} rss={{ title: "Custom dashboards for everyone, digital ID signals, and rule building" }}>
  ## Dashboards for every customer

  Dashboards is in the sidebar for every customer, and you can build your own. Charts and tables built in an Agent chat can be added to them.

  ## Digital IDs on ID Check

  A digital ID comes back as a risk signal, and you can write rules on it. When a digital ID is on screen, the video analysis view shows the clips that apply to it.

  ## Rule building

  Domain Type, Country, and Mobile Languages offer value suggestions on **contains** conditions, with exact matches ranked first, so typing `us` gives United States.

  School ID and employee ID are available as document templates in rules.

  ## Numeric rule conditions require a value

  Conditions using `>`, `>=`, `<`, and `<=` match when the field they read has a value. A rule on `verification.id_age < 18` matches only when the document carries a readable date of birth. Missing values used to compare as zero, so rules of this shape match fewer accounts and sessions from now on.

  [Rules](/action/rules)
</Update>

<Update label="August 11, 2026" description="Session source in the dashboard" tags={["Dashboard", "Rules"]} rss={{ title: "Session source in the dashboard" }}>
  The sessions table has a **Source** column, filterable by web, iOS, and Android, and a **Source Version** column you can turn on from the column panel. Both values show in the session side panel and come along in CSV exports.

  You can write rules on session source.
</Update>

<Update label="August 10, 2026" description="Carrier identity, session source, and linked account history" tags={["API", "Mobile"]} rss={{ title: "Carrier identity, session source, and linked account history" }}>
  Sessions from the iOS, Android, and Flutter SDKs now report the SIM carrier and the country that carrier operates in. Carrier country comes from the device, so it holds up when the IP is proxied.

  Every session returns `source` (`web`, `ios`, or `android`) and `source_version`, so you can tell which integration produced a session and which SDK version it ran.

  Linked accounts return `first_seen` and `last_seen`, showing when two accounts were first connected and when that link was last active.

  ## Account timestamp format

  `first_seen` and `last_seen` come back as normalized ISO 8601 timestamps, on the account itself and on linked accounts. Earlier responses passed through nanosecond precision, for example `2026-04-22T21:38:47.806000000Z`, so anything parsing these fields sees a different string from now on.

  [Account object](/api-reference/types/account)

  ## Sessions with an out of range country code

  A session persists even when network intelligence reports a country code outside the two letter form, such as `CN-TW` for Taiwan. The country code on that session is left unset, and the account behind it gets its scores, decision, and `last_seen` as usual. Sessions like these were dropped before, so they now appear in the sessions table and in Get Session.
</Update>

<Update label="August 4, 2026" description="Rules and lists for verifications, and automatic enrollment" tags={["Verifications", "Rules", "API"]} rss={{ title: "Rules and lists for verifications, and automatic enrollment" }}>
  ## Rules and lists act on verification results

  Two rule triggers are live in the dashboard: **ID Check Completed** and **Face Match Completed**. Rules on these triggers can read the verification decision, risk score, risk signals, document country, ID age, and the rest of the verification response.

  Rules apply to the account behind the verification. A rule like `IF risk signals contains id_age_below_16 → Add to Block List` adds the account itself, tied to the session where the condition matched.

  List membership now flows through to verification decisions. Block-listed accounts return `Fake` on `/verify-id` and `/verify-face`, allow-listed accounts return `Real`. Both endpoints return `lists` and `rules` fields showing what was applied.

  If you already keep accounts on lists, some verification decisions will change to match the account decision.

  ## Automatic enrollment

  Pass an `account_id` when you create a verification session and we enroll the account once the session completes. Enrollment was previously a separate call that had to happen in the right order, and sessions that skipped it returned confusing `Fake` results.

  [Rules](/action/rules) · [Face Match session setup](/verifications/face-match/integration/initialize-session) · [ID Check session setup](/verifications/id-check/integration/initialize-session)

  ## Rule suggestions from the agent

  Ask the dashboard agent for a rule and it proposes conditions backed by backtest numbers from your own data, then hands off to the rule create form with those conditions filled in. Suggestions arrive disabled and the backtesting drawer runs on arrival, so you see what the rule would have caught before you turn it on.

  ## Online presence signals on email

  Email intelligence reports online presence in tiers. `no_online_presence` and `sparse_online_presence` come back as risk signals, `moderate_online_presence` and `strong_online_presence` as trust signals. All four work as filters on the email table. Rows scored before this change stay filterable on `online_presence_detected`.

  [Email Intelligence](/email-intelligence/overview)
</Update>

<Update label="July 24, 2026" description="Named risk signals and native mobile device facts" tags={["API", "Dashboard", "Signals"]} rss={{ title: "Named risk signals and native mobile device facts" }}>
  ## Risk signal details

  Sessions return `risk_signal_details`, a set of named reason codes that explain why a risk score is elevated. It comes back on Authenticate, Unauthenticated, and Get Session.

  * **Network**: 13 signals covering the proxy, VPN, and location scores, such as `ip_on_vpn_list` and `true_country_mismatch`.
  * **Device**: 22 signals covering device risk, such as `browser_tampering_detected` and `android_emulator_or_rooted`. This includes emulator and jailbreak detection, factory reset boot profiles, Play Integrity verdicts, and device brand signals.

  Signals stay consistent with the scores beside them. A clean proxy score carries no proxy signal, and an elevated score always carries at least one signal explaining it. A few factual signals fire independently of score level, so you can write rules directly against them.

  ## Mobile device facts

  Sessions from the iOS and Android SDKs return a `mobile` block: brand, model, RAM, boot count, uptime, battery, languages, and OEM integrity verdicts. Native sessions also improve the existing `device` fields with values a WebView masks or misreports.

  All of it works in rules, as filterable columns in the sessions table, and in the session side panel. You may need to enable the new columns to see them.

  [Risk Signals](/signals-scores/risk-signals) · [Mobile](/signals-scores/mobile)

  ## Android time settings signal

  Device risk signals include `android_manual_time_settings`, which fires when a device has automatic time or automatic time zone turned off. It works in rules and as a filter on the sessions table.
</Update>

<Update label="July 22, 2026" description="Rule duplication, list operators, and account columns" tags={["Dashboard", "Rules"]} rss={{ title: "Rule duplication, list operators, and account columns" }}>
  ## Duplicate a rule, and create rules disabled

  You can duplicate an existing rule, which opens the create form with its conditions and actions filled in.

  The create and edit forms carry a **Status** switch, so you can save a rule disabled and turn it on once you have reviewed it. New rules default to enabled.

  ## Equals and not equals on lists

  Rules on the Lists field take **Equals** and **Not equals**. Matching is on exact list membership, so a condition on `advertiser 10` treats `advertiser 100` as a separate list.

  ## Account fields in the accounts table

  The accounts table shows a **Phone** column, with **Username**, **First Name**, **Last Name**, and **Expected Countries** available from the column panel. All five filter, and the filters sync to the URL.

  ## Share a view, and clear a custom date range

  Tables and analytics pages have a Share button beside the date picker. It copies the current URL, which already carries the date range and the filters you have applied.

  An active custom date range gets an X beside it that clears the range and returns the page to the default 7 day period.

  [Rules](/action/rules)
</Update>

<Update label="July 20, 2026" description="Phone, name, username, and expected countries on accounts" tags={["API", "Multi-Accounting"]} rss={{ title: "Phone, name, username, and expected countries on accounts" }}>
  Five optional fields are accepted on the account object, through Authenticate Session and Update Account: `phone`, `first_name`, `last_name`, `username`, and `expected_countries`.

  **Phone, name, and username feed multi-accounting.** They become additional identifiers for linking accounts. A shared phone number or username is a full match on its own. A shared name supports links alongside device, network, and email matches. Matches appear in linked accounts with their match type. Values are normalized behind the scenes, so `+1 (415) 555-0123` matches `+1-415-555-0123` and `José García` matches `jose garcia`.

  **Expected countries feed location spoofing.** Declare where an account should be operating, for example `["US", "CA"]`. Sessions from outside those countries, or far from them, factor into that account's location spoofing score.

  All five fields are optional and additive. Send nothing and behavior stays the same. Updating a field later works as you would expect, with last write winning per field.

  [Account object](/api-reference/types/account) · [Multi-Accounting](/signals-scores/multi-accounting) · [Expected Countries](/signals-scores/expected-countries)
</Update>

<Update label="July 7, 2026" description="Upgraded risk models, the dashboard AI agent, and rebuilt verifications" tags={["Dashboard", "Device", "Network", "Verifications"]} rss={{ title: "Upgraded risk models, the dashboard AI agent, and rebuilt verifications" }}>
  ## Upgraded real-time models

  We improved how device and network data is collected. Measured against the previous models:

  * 31% better catch rate on sophisticated proxies and anti-detect browsers
  * 10 to 14% fewer false positives on location spoofing and proxy/VPN, with the largest gains on slow networks
  * 18 to 20% faster session IDs and API responses

  ## AI agent in the dashboard

  There is an agent in the bottom-left corner of the dashboard. It has access to your project data in a privacy-preserving sandbox, which is never shared with model providers or used for training. It can run investigations, build charts, slides, and CSVs, and take actions such as adding accounts to lists.

  Prompts worth trying:

  * "Pull all accounts linked to {account_id} at above 50% strength, three levels deep"
  * "Compare fake and suspicious users over the last 7 days against the prior 7. What is driving the change?"
  * "Here are 100 emails. Find their accounts and add them to the block list."
  * "Build a report on the last 30 days: fraud rates, key drivers, trends"

  The agent keeps per-user and per-project memory, so context you give it in one chat carries into later ones. You can react to its messages with feedback, which we review weekly.

  ## Face Match and ID Check

  We rebuilt the data processing and risk engine behind both products, and we now capture and return session video in the dashboard.

  * 30% more accurate ID data capture
  * 82% fewer false positive risk flags, while catching more fraud
  * Video makes phone handoffs, digital IDs, and background characteristics visible during review
</Update>

<Update label="June 22, 2026" description="Smaller additions across ID Check, network, and email" tags={["API", "Verifications", "Email"]} rss={{ title: "Smaller additions across ID Check, network, and email" }}>
  * ID Check returns a face age estimate on the verification response.
  * Network intelligence identifies satellite connections as a distinct connection type.
  * The `id_age` document signal description now states what it measures: the age derived from the date of birth on the document.
  * Email intelligence groups the Identity Intelligence signals together and marks them as such in the API reference.
</Update>

<Update label="May 27, 2026" description="Session video on Face Match and ID Check responses" tags={["Verifications", "API"]} rss={{ title: "Session video on Face Match and ID Check responses" }}>
  Face Match and ID Check responses include a URL for the recorded session video. The same video is available in the dashboard on the verification detail view.

  Video shows the context around a capture: a phone handed between people, an ID held up on another screen, and the surroundings the capture happened in.
</Update>

<Update label="May 7, 2026" description="Serve the browser SDK from your own domain" tags={["Integration"]} rss={{ title: "Serve the browser SDK from your own domain" }}>
  You can serve the Verisoul browser SDK from a subdomain you own, for example `verify.yourcompany.com`. Requests go to your domain and reach us behind it.

  Setup is a nameserver delegation on a subdomain you dedicate to us. We handle the certificate and keep it renewed.

  Traffic to a first-party domain gets past ad blockers and tracker blocklists, which raises the share of sessions that produce a full signal set.

  [Custom Hostname](/integration/custom-hostname)
</Update>

<Update label="April 9, 2026" description="Location spoofing score on sessions and accounts" tags={["API", "Network"]} rss={{ title: "Location spoofing score on sessions and accounts" }}>
  Sessions and accounts return a `location_spoofing` score. It combines the signals we collect about where a session claims to be and where it appears to actually be: timezone, locale, GPS where available, IP geolocation, and network routing.

  The score is in the API reference for Get Session and Get Account, in the sessions and accounts tables, and available in rules.

  [Get Session](/api-reference/session/get) · [Network Intelligence](/signals-scores/network)
</Update>

<Update label="March 30, 2026" description="Email Intelligence API" tags={["Email", "API", "Dashboard"]} rss={{ title: "Email Intelligence API" }}>
  Email intelligence used to run only as part of a real-time session through `/session/authenticate`. It is now a standalone endpoint, so you can submit an email on its own and get a full assessment back.

  Email carries history, and history takes years to fake. It also links out to names, phones, and locations, which adds identity context to device and network signals.

  What comes back:

  * **Risk score** from -1 (high trust) to +1 (high risk), with a decision label of `high_trust`, `trusted`, `moderate`, `risky`, or `high_risk`, plus the trust and risk signals behind it.
  * **Online history and age**: how long the address has existed, where it has appeared, and breach history with dates.
  * **Social signals**: which platforms the address is registered on, such as Google, Facebook, and LinkedIn.
  * **Deliverability**: whether the address can receive mail, with a recommendation of `send`, `send_with_caution`, or `do_not_send`.
  * **Domain intelligence**: disposable, fresh, and fake domains, classified as personal, business, education, government, relay, or inactive.
  * **Identity intelligence**: pass an expected name, phone, and country, and we match those claims against external data, then return connected names and phone numbers.

  Batches of up to 1,000 emails go through the API or a CSV upload in the dashboard. Results arrive by webhook and appear in the dashboard within a few minutes.

  Email Intelligence replaces Manual Lookup. Data from Manual Lookup stays in the email table.

  [Email Intelligence](/email-intelligence/overview)
</Update>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.