Skip to main content
Didit’s Location verification step confirms where a person is while they verify, by reading the device position once (browser or native SDK) or the connection’s IP location, and checking it against allowed and blocked areas, the IP location and the address on their documents. In workflows and the API it is the GEOLOCATION feature, its settings are the geolocation_* keys, and its result is geolocation_checks[] on the session decision.

When to use it

  • You hold a licence for some jurisdictions only (gambling, brokerage, lending) and must prove the person was inside one when they applied.
  • You must keep people out of blocked places, such as a sanctioned region or a state you do not serve.
  • You want one more fraud signal: a device position far from the IP location or from the address on the ID, a mocked position, a VPN or an emulator.
  • You do not need the person’s movements or history, only one reading taken during the session.

How it works

Notice and permission

The person sees why their location is needed and that it is read once, for this verification. Their browser or phone then asks for permission. Didit records the notice they accepted (version, language and time) as consent in the result.

One position per attempt

The client keeps the best reading until it is accurate enough or the per-attempt timeout (default 20 seconds) runs out. Each attempt carries a single-use challenge that is valid for 5 minutes and bound to the session, so a captured submission cannot be replayed.

Checks

Didit judges accuracy, freshness, approximate grants, spoofing signals, areas, the distance to the IP location and to a document address, VPN, proxy, Tor and emulator findings, and the person’s earlier checks.

Outcome

Each finding raises a warning whose configured action (NO_ACTION, REVIEW or DECLINE) sets the step status. The strongest action wins.

Position sources

You choose where the position comes from with geolocation_position_source. On a node that asks the device, an attempt with no position is judged as the refusal or failure it is: the IP location never stands in for it.

Configuration defaults and limits

All keys are optional. The full list is in the workflow feature configs reference.

Presets

geolocation_preset sets the default of every action you leave unset. licensing declines a position outside the allowed areas, inside a blocked area, behind a VPN or Tor, or on an emulator, and reviews a proxy. fraud_screening applies the same findings but sends everything licensing would decline to review. An action you set explicitly always wins.

Geofencing

Turn on is_geolocation_geofencing_enabled and list geolocation_areas. An area is a whole country, regions (ISO 3166-2) of one country, a circle (1 to 500 km) or a polygon (3 to 200 points). Only a position inside an allowed area passes, and a blocked area always wins over an allowed one. A list holds up to 50 areas and needs at least one allowed area. Didit judges the whole accuracy circle of the position, not just its centre:
  • A circle fully outside every allowed area is LOCATION_OUTSIDE_GEOFENCE.
  • A circle that crosses an edge that decides the answer is LOCATION_GEOFENCE_UNDETERMINED, never “outside”.
  • A circle fully inside a blocked area is LOCATION_IN_BLOCKED_AREA, and it is raised in addition to the allowed-area verdict.
A country or region ends where other land begins, not at its coastline. The person is shown where the service is available, but never which areas are blocked. Area rules also work on an ip_only step, judged from the IP location. The older geolocation_geofencing_by_country setting still works but cannot be combined with geolocation_areas.

Distance checks

geolocation_document_distance_basis picks the address: document (the identity document, then the proof of address), proof_of_address, or declared (expected_details.address from session creation). With geolocation_travel_tolerance_enabled, a person seen near their address in the last geolocation_travel_max_days days is not flagged for being far from it now. Travel tolerance never excuses a VPN, a spoofed position, a blocked area or a position outside the allowed areas.

Spoofing and integrity signals

  • Mock providers: Android and iOS report when a position is simulated rather than measured.
  • Device attestation: native SDKs can attach a device attestation. A failed attestation always declines. A missing one is recorded and defaults to no action. Browsers cannot attest and are recorded as unsupported, not as a failure.
  • VPN, proxy and Tor: found on the connection that shared the location. When your action for one of them is not NO_ACTION, the person is asked to turn it off and check again while attempts remain.
  • Emulators: reported by native apps only. An emulator ends the step on that attempt because no retry changes the device.
  • Replay: a challenge presented on another session always declines.

Outcomes

The accepted attempt of the step has one outcome: While attempts remain, a wide, stale, approximate, refused or area finding asks the person to try again, and only the last attempt raises warnings. A mocked position, or an emulator your workflow acts on, ends the step on the attempt that reported it.

Person experience

Nothing is read before the person accepts the notice and answers the system prompt. The notice says the location is read once, for this verification, and is not a record of their movements. A person who refuses is treated according to geolocation_refusal_path:
  • retry_then_handoff asks again while attempts remain and then offers to continue on a phone.
  • continue_without_location offers to go on without a location, and records the refusal as the outcome.
  • end_session ends the step and the session on the first refusal. It needs geolocation_permission_denied_action to be REVIEW or DECLINE, and the session is never approved.
With geolocation_allow_skip on, the person can continue without a location at any time, and the step is judged by geolocation_unavailable_action.

Browser

The hosted flow asks the browser for the position and shows step-by-step help for Chrome and Safari when location is off for the site. A browser cannot tell a precise grant from an approximate one, so web results never raise LOCATION_APPROXIMATE_ONLY, and it never reports a mock provider, an emulator or an attestation. A computer cannot share a precise position, so the flow offers a QR code that continues the same verification on the person’s phone (geolocation_allow_qr_handoff, on by default), and the computer moves on by itself when the phone finishes. When you embed the flow in an iframe, include geolocation in the allow attribute, see in-context iframe. A page that blocks the geolocation permission policy is treated as the site’s decision, not the person’s refusal.

Native SDKs

The iOS and Android SDKs ask the operating system and can attach device attestation and mock-location flags. On iOS add NSLocationWhenInUseUsageDescription to Info.plist, and on Android the SDK declares ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION and asks at runtime only when a workflow has this step. See the native SDKs. An approximate grant on iOS or Android raises LOCATION_APPROXIMATE_ONLY unless geolocation_accuracy_mode is approximate_allowed. An app or SDK build that predates the step is closed out with unsupported_client instead of leaving the session stuck.

What the decision returns

The session decision and the status.updated webhook carry two lists:
  • geolocation_checks[]: one item per Location step, holding that step’s accepted attempt, with its warnings.
  • geolocation_attempts[]: every attempt of every Location step, oldest first.
See the location verification report for every field. The coordinates, accuracy, city and country are personal data of the end user, so a workflow’s response attributes can restrict which geolocation_checks fields your decision returns.

Pricing

Location verification costs $0.05 per check, and it is not part of the free tier. Didit charges once per Location step in a session, whatever its outcome, because the check ran and returned an answer. Retries inside the same step are free. A resubmission that completes the step again is charged again.

Sandbox

Sandbox sessions run the same step in the same hosted flow, and the device or browser still reports a real position. Sandbox sessions never reach the IP lookup service, so the IP comparison only uses what the session already holds. Usage is recorded at a price of 0, so a sandbox session is never charged. There are no magic inputs for this step.
Last modified on October 31, 2026