Validate addresses
POST /v1/validate checks one address and answers with a verdict, a 0–100 confidence score, and the standardized address. Results are verified against your input, never taken on a provider's word.
Request
POST https://geoverdict.com/v1/validate
Authorization: Bearer ak_live_…
Content-Type: application/json
Provide query (free-form text), components (structured fields), or both. At least one is required.
| Field | Type | Description |
|---|---|---|
query | string, 1–500 | Free-form address text, e.g. "Prinsengracht 263, Amsterdam". Typos are tolerated and corrected where possible. |
components | object | Structured input: street (1–200), houseNumber (1–20), postcode (1–20), city (1–100), state (1–100), country (2-letter code). All fields optional. Structured input gets exact per-field comparison and is preferred when your form already has separate fields. |
country | string, 2 chars | ISO 3166-1 alpha-2 country bias/filter, e.g. "NL". Providers that do not cover the country are skipped (traced as no-coverage). |
language | string, 2–8 | Preferred response language where providers support it, e.g. "en", "nl-NL". |
source | string, 1–64 | Free-form tag for segmenting usage per feature or system (e.g. "checkout", "crm-import"). Shows up in /v1/usage and the console. Can also be sent as a ?source= query parameter; the body field wins. |
debug | boolean | When true, the response additionally includes candidates (every scored provider result) and trace (the provider routing trail). |
Response
| Field | Type | Description |
|---|---|---|
verdict | string | valid, correctable, or invalid. See Verdicts & confidence. |
confidence | integer 0–100 | Unified confidence score. 0 when no provider returned a result. |
address | object or null | The standardized address of the best result: street, houseNumber, postcode, city, state, country, plus lat/lng when the provider returned coordinates. null when nothing was found. |
components | object | Per-component comparison of the best result against your input. Keys among street, houseNumber, postcode, city, country; values are match, corrected, mismatch, missing, or not-checked. Only checked components appear. |
provider | string or null | Id of the provider behind the best result (e.g. bag). |
reasons | string[] | Why the verdict is not a clean valid: any of no_results, low_confidence, no_house_number_match, components_incomplete, components_corrected. Empty for a clean pass. |
cached | boolean | true when served from the response cache. Cached responses cost 0 credits. |
candidates | array | Debug only. All scored provider results, best first: provider, components, location, optional normalized provider confidence, unified confidence, and per-component verdicts. |
trace | array | Debug only. One step per routed provider: provider, status (ok, error, timeout, aborted, skipped, circuit-open, no-coverage, unsupported, unknown-provider), latencyMs, resultCount. |
Example: a typo gets corrected
curl -s https://geoverdict.com/v1/validate \
-H "Authorization: Bearer $GEOVERDICT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "prinsengrach 263, amsterdm", "country": "NL"}'
{
"verdict": "correctable",
"confidence": 84,
"address": {
"street": "Prinsengracht",
"houseNumber": "263",
"postcode": "1016 GV",
"city": "Amsterdam",
"country": "NL",
"lat": 52.3752,
"lng": 4.8836
},
"components": {
"street": "corrected",
"houseNumber": "match",
"city": "corrected",
"country": "match"
},
"provider": "bag",
"reasons": ["components_corrected"],
"cached": false
}
A correctable verdict is a feature, not a failure: GeoVerdict found a sufficiently confident result after correcting part of the input, and address holds the standardized form you can offer back to the user or write to your records.
Debugging with the provider trail
Set "debug": true to see exactly which providers were asked and what each one said:
{
"verdict": "valid",
"…": "…",
"trace": [
{ "provider": "bag", "status": "ok", "latencyMs": 131, "resultCount": 1 }
],
"candidates": [
{
"provider": "bag",
"confidence": 100,
"components": { "street": "Prinsengracht", "houseNumber": "263", "…": "…" },
"componentVerdicts": { "street": "match", "houseNumber": "match" }
}
]
}
The same trail is stored with every request and browsable per call in the console's API Logs, so you rarely need debug in production.
Routing strategies and thresholds
How providers are queried is configured per account (console Settings) with optional per-project overrides, not per request:
| Strategy | Behavior |
|---|---|
| Cost Efficient (default) | Try providers in order, stop at the first result that clears your valid threshold. Cheapest. |
| Balanced | Race the selected providers, return the first sufficient answer, abort the rest. |
| Most Accurate | Query all selected providers in parallel and keep the best-scoring result. |
The confidence threshold (default 85, configurable 50–99) sets the valid bar; the correctable bar is 25 points below it (never under 40). Projects can also restrict and reorder which providers are used. Note that fan-out strategies consume more credits per call because each answering provider costs one credit.
Caching
Identical lookups (same normalized input, provider set, and configuration) are served from cache for up to an hour where provider terms permit. Cached responses return "cached": true and cost 0 credits. Change your strategy, threshold, or provider selection and the cache key changes with it.