GeoVerdictDocs
Browse documentation
Reference

API reference

Address validation and autocomplete through one API. Version 1.0.0, generated from the OpenAPI 3.1 specification.

Base URL

https://geoverdict.com

Authentication

Secret API key

Authorization: Bearer ak_live_... or ak_test_...

Secret server-side API key, created in the GeoVerdict console. Format ak_(live|test)_<base64url>. Send as Authorization: Bearer ak_live_.... ak_test_ keys call the same real providers and draw from the same monthly and purchased-credit balance as live keys. They are tagged separately in analytics and carry a best-effort 60-request/minute limit.

Publishable widget token

Authorization: Bearer gv_pk_live_... or gv_pk_test_...

Project-scoped publishable widget token with an exact HTTPS origin allowlist. Only valid on /v1/widget/autocomplete. Safe to expose in browser code; cannot call any other endpoint.

Endpoints

GET/healthz

Auth: None (public endpoint)

Service health

Returns service status and the ids of the currently active geocoding providers. Free, unauthenticated.

Responses

StatusBodyDescription
200 object Service is up.
200 example
{
  "status": "ok",
  "providers": [
    "bag"
  ]
}

POST/v1/validate

Auth: Secret API key

Validate an address

Validates a single address and returns a verdict, a 0-100 confidence score, the standardized address, per-component comparison results, and a provider-consensus report. Provide either a free-form query or structured components (at least one is required).

Costs 1 credit per provider that answered; a cache hit or a request where no provider answers costs 0.

Parameters

NameInTypeDescription
source query string
length 0–64
Fallback for the source body field; the body value wins when both are set.

Request body

Provide query, components, or both. At least one is required.

FieldTypeDescription
query string
length 1–500
Free-form address text.
components AddressComponents Structured address parts. All fields optional.
country string
length 2–2
ISO 3166-1 alpha-2 country bias/filter. Providers that do not cover this country are skipped.
language string
length 2–8
Preferred response language (e.g. en, nl-NL).
source string
length 1–64
Free-form tag for segmenting usage per feature or system (e.g. checkout). Appears in /v1/usage and the console.
debug boolean When true, the response additionally includes candidates (all scored provider results) and trace (the provider routing trail).
Free-form query
{
  "query": "Prinsengracht 263, Amsterdam",
  "country": "NL"
}
Structured components
{
  "components": {
    "street": "Prinsengracht",
    "houseNumber": "263",
    "postcode": "1016 GV",
    "city": "Amsterdam",
    "country": "NL"
  }
}
With provider trail
{
  "query": "Prinsengracht 263, Amsterdam",
  "country": "NL",
  "debug": true
}

Responses

StatusBodyDescription
200 ValidateResponse Validation result. candidates and trace are present only when the request set "debug": true.
400 ValidationError The request body failed schema validation. issues lists each violation.
401 Error Missing, malformed, unknown, or revoked API key.
429 Error The account's monthly plan credits plus purchased extra credits are used up. Resolve by upgrading the plan or buying a credit pack in the console; the counter resets on the 1st of each month (UTC).
200 example
Typo fixed by the engine
{
  "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"
  ],
  "consensus": {
    "status": "single-provider",
    "score": null,
    "baseConfidence": 84,
    "confidenceDelta": 0,
    "supportingProviders": [
      "bag"
    ],
    "conflictingProviders": [],
    "disagreements": []
  },
  "cached": false
}
400 example
{
  "message": "Validation failed",
  "issues": [
    {
      "code": "too_small",
      "minimum": 1,
      "path": [
        "query"
      ],
      "message": "Too small, expected string to have >=1 characters"
    }
  ]
}
401 example
missing
{
  "message": "Missing API key. Send it as: Authorization: Bearer ak_live_…"
}
malformed
{
  "message": "Malformed API key"
}
unknown
{
  "message": "Unknown or revoked API key"
}
429 example
{
  "message": "Monthly credits exhausted (500 plan credits on the free plan). Upgrade or buy credits at https://geoverdict.com/dashboard"
}

POST/v1/autocomplete

Auth: Secret API key

Autocomplete an address

Returns up to limit (default 5) address suggestions for a partial query. Suggestions are deduplicated across providers.

Each uncached call costs 1 credit per provider that answered. A cache hit or a request where no provider answers costs 0. sessionToken is echoed back for client-side correlation only; it does not deduplicate billing.

For browser-side autocomplete use the embeddable widget with a publishable token (/v1/widget/autocomplete) instead of exposing a secret key.

Parameters

NameInTypeDescription
source query string
length 0–64
Fallback for the source body field; the body value wins when both are set.

Request body

FieldTypeDescription
query required string
length 1–200
Partial address text.
country string
length 2–2
ISO 3166-1 alpha-2 country bias/filter.
language string
length 2–8
limit integer
range 1–10, default 5
Maximum number of suggestions.
sessionToken string
length 0–64
Client-generated correlation id, echoed back unchanged. Correlation only; it does not deduplicate billing.
source string
length 1–64
Usage segmentation tag, as on /v1/validate.
{
  "query": "Prinsengracht 26",
  "country": "NL",
  "limit": 5
}

Responses

StatusBodyDescription
200 AutocompleteResponse Suggestions ordered by provider result order, deduplicated by label.
400 ValidationError The request body failed schema validation. issues lists each violation.
401 Error Missing, malformed, unknown, or revoked API key.
429 Error The account's monthly plan credits plus purchased extra credits are used up. Resolve by upgrading the plan or buying a credit pack in the console; the counter resets on the 1st of each month (UTC).
200 example
{
  "suggestions": [
    {
      "label": "Prinsengracht 263, 1016GV Amsterdam",
      "components": {
        "street": "Prinsengracht",
        "houseNumber": "263",
        "postcode": "1016 GV",
        "city": "Amsterdam",
        "country": "NL"
      },
      "location": {
        "lat": 52.3752,
        "lng": 4.8836
      },
      "provider": "bag"
    }
  ],
  "sessionToken": null,
  "cached": false
}
400 example
{
  "message": "Validation failed",
  "issues": [
    {
      "code": "too_small",
      "minimum": 1,
      "path": [
        "query"
      ],
      "message": "Too small, expected string to have >=1 characters"
    }
  ]
}
401 example
missing
{
  "message": "Missing API key. Send it as: Authorization: Bearer ak_live_…"
}
malformed
{
  "message": "Malformed API key"
}
unknown
{
  "message": "Unknown or revoked API key"
}
429 example
{
  "message": "Monthly credits exhausted (500 plan credits on the free plan). Upgrade or buy credits at https://geoverdict.com/dashboard"
}

POST/v1/widget/autocomplete

Auth: Publishable widget token

Browser widget autocomplete

Browser-safe autocomplete for the embeddable GeoVerdict widget. Authenticates with a project-scoped publishable token (gv_pk_live_... / gv_pk_test_...) and requires a request Origin on the token's exact HTTPS origin allowlist. Secret API keys (ak_...) and console sessions are rejected.

Suggestions are mapped to a browser-safe shape with opaque ids; provider-native identifiers and raw metadata are never returned. Per-token and per-origin rate limits of 120 requests/minute apply in addition to the account credit gate. Billing matches server autocomplete: 1 credit per answering provider per uncached call.

Most integrations should not call this endpoint directly; the hosted widget (https://geoverdict.com/widget/v1/geoverdict-autocomplete.js) implements the contract, keyboard navigation, and accessibility.

Parameters

NameInTypeDescription
Origin required header string Exact HTTPS origin of the embedding page. Must be on the publishable token's origin allowlist.

Request body

FieldTypeDescription
query required string
length 1–200
Partial address text.
country string
length 2–2
ISO 3166-1 alpha-2 country bias/filter.
language string
length 2–8
limit integer
range 1–10, default 5
Maximum number of suggestions.
sessionToken string
length 0–64
Client-generated correlation id, echoed back unchanged. Correlation only; it does not deduplicate billing.
source string
length 1–64
Usage segmentation tag, as on /v1/validate.
{
  "query": "Prinsengracht 26",
  "country": "NL",
  "limit": 5,
  "sessionToken": "3f5a1c9e-session",
  "source": "widget"
}

Responses

StatusBodyDescription
200 WidgetAutocompleteResponse Browser-safe suggestions. Access-Control-Allow-Origin echoes the validated origin.
400 ValidationError The request body failed schema validation. issues lists each violation.
401 Error Missing, malformed, revoked, or origin-restricted publishable token.
403 Error The request carried no Origin header or the origin is not an exact HTTPS origin.
429 Error Widget rate limit reached (120 requests/minute per token and per origin, with an additional 60/minute limit for test tokens) or the account's shared monthly and purchased-credit balance is exhausted.
200 example
{
  "suggestions": [
    {
      "id": "gv_s_1f7c0a92be34d56e78a90c12",
      "label": "Prinsengracht 263, 1016GV Amsterdam",
      "provider": "bag",
      "address": {
        "street": "Prinsengracht",
        "houseNumber": "263",
        "postcode": "1016 GV",
        "city": "Amsterdam",
        "country": "NL"
      }
    }
  ],
  "sessionToken": "3f5a1c9e-session",
  "cached": false
}
400 example
{
  "message": "Validation failed",
  "issues": [
    {
      "code": "too_small",
      "minimum": 1,
      "path": [
        "query"
      ],
      "message": "Too small, expected string to have >=1 characters"
    }
  ]
}
401 example
{
  "message": "Unknown, revoked, or origin-restricted publishable token"
}
403 example
{
  "message": "A permitted HTTPS Origin is required"
}
429 example
rateLimit
{
  "message": "Widget autocomplete rate limit reached"
}
credits
{
  "message": "Monthly project credits exhausted"
}

OPTIONS/v1/widget/autocomplete

Auth: None (public endpoint)

Widget CORS preflight

CORS preflight for the widget endpoint. Because browsers omit the Authorization value during preflight, the server reflects an origin only when an active publishable token currently allows it; the subsequent POST still binds the exact token and origin.

Parameters

NameInTypeDescription
Origin required header string
Access-Control-Request-Method required header POST

Responses

StatusBodyDescription
204 no body Origin currently allowed by at least one active token; CORS headers set.
403 no body Origin missing, not HTTPS, or not on any active token's allowlist.

GET/v1/usage

Auth: Secret API key

Usage and credit balance

Current-month credit consumption plus recent activity for the account that owns the API key. This call consumes no credits and never writes a usage event, but the shared API-key quota gate still returns 429 after the account exhausts its credits. Displays can lag the ledger by up to 60 seconds.

Parameters

NameInTypeDescription
source query string Filter summary, daily, and recent to a single source tag. sources always covers all tags.

Responses

StatusBodyDescription
200 UsageResponse Usage report.
401 Error Missing, malformed, unknown, or revoked API key.
429 Error The account's monthly plan credits plus purchased extra credits are used up. Resolve by upgrading the plan or buying a credit pack in the console; the counter resets on the 1st of each month (UTC).
200 example
{
  "plan": "free",
  "quota": 500,
  "extraCredits": 0,
  "creditsUsedThisMonth": 42,
  "environment": "test",
  "filteredBySource": null,
  "daily": [
    {
      "day": "2026-08-02",
      "n": 12,
      "credits": 10
    }
  ],
  "summary": [
    {
      "endpoint": "validate",
      "verdict": "valid",
      "n": 30,
      "credits": 28
    }
  ],
  "sources": [
    {
      "source": "checkout",
      "n": 25,
      "credits": 22
    },
    {
      "source": "",
      "n": 17,
      "credits": 20
    }
  ],
  "recent": [
    {
      "endpoint": "validate",
      "verdict": "valid",
      "provider": "bag",
      "latency_ms": 132,
      "cached": 0,
      "credits": 1,
      "query": "Prinsengracht 263, Amsterdam",
      "source": "checkout",
      "at": "2026-08-02 14:03:11"
    }
  ]
}
401 example
missing
{
  "message": "Missing API key. Send it as: Authorization: Bearer ak_live_…"
}
malformed
{
  "message": "Malformed API key"
}
unknown
{
  "message": "Unknown or revoked API key"
}
429 example
{
  "message": "Monthly credits exhausted (500 plan credits on the free plan). Upgrade or buy credits at https://geoverdict.com/dashboard"
}

POST/demo/validate

Auth: None (public endpoint)

Homepage demo validation

Unauthenticated validation used by the geoverdict.com homepage demo. It defaults to the Netherlands (country: NL), but honors a trailing ISO alpha-2 country code in the query, and costs 0 credits. The three queries shown on the homepage use stable provider-free responses. Other queries check the engine cache first; cache hits do not consume demo allowance. Only cache misses are rate limited per visitor IP over rolling windows: 10 requests / 5 minutes, 20 / 24 hours, 50 / 7 days, and 200 / 30 days. Not intended for production integrations; use /v1/validate with an API key instead.

Request body

FieldTypeDescription
query required string
length 1–200
{
  "query": "prinsengrach 263, amsterdm"
}

Responses

StatusBodyDescription
200 DemoValidateResponse Validation result (same core fields as /v1/validate, without cached).
400 Error Missing or invalid query.
429 DemoRateLimitError An uncached, non-sample query exhausted one or more rolling demo allowances. The Retry-After header carries the longest required wait in seconds.
400 example
{
  "message": "Type an address first"
}
429 example
{
  "message": "Demo request allowance reached.",
  "limits": [
    {
      "window": "five_minute",
      "max": 10,
      "periodSeconds": 300,
      "retryAfterSeconds": 233
    }
  ],
  "retryAfterSeconds": 233,
  "freeMonthlyCredits": 500
}

Schemas

Error

FieldTypeDescription
message required string

ValidationError

FieldTypeDescription
message required Validation failed
issues required array of object Machine-readable list of schema violations (Zod issue objects).

AddressComponents

Structured address parts. All fields optional.

FieldTypeDescription
street string
length 1–200
houseNumber string
length 1–20
House number including any suffix, e.g. 263, 2B, 2/B.
postcode string
length 1–20
city string
length 1–100
state string
length 1–100
country string
length 2–2
ISO 3166-1 alpha-2 code, e.g. NL.

ValidateRequest

Provide query, components, or both. At least one is required.

FieldTypeDescription
query string
length 1–500
Free-form address text.
components AddressComponents Structured address parts. All fields optional.
country string
length 2–2
ISO 3166-1 alpha-2 country bias/filter. Providers that do not cover this country are skipped.
language string
length 2–8
Preferred response language (e.g. en, nl-NL).
source string
length 1–64
Free-form tag for segmenting usage per feature or system (e.g. checkout). Appears in /v1/usage and the console.
debug boolean When true, the response additionally includes candidates (all scored provider results) and trace (the provider routing trail).

Verdict

- valid: confidence at or above the project's valid threshold and every checked component matched. - correctable: the address was found but something was fixed (the response carries the standardized address). - invalid: below the correctable threshold, or a supplied house number could not be matched.

One of: valid, correctable, invalid

Reason

One of: no_results, low_confidence, no_house_number_match, components_incomplete, components_corrected

ComponentVerdict

One of: match, corrected, mismatch, missing, not-checked

ComponentVerdicts

Per-component comparison of the best result against the input. Keys are only present for checked components.

FieldTypeDescription
street ComponentVerdict
houseNumber ComponentVerdict
postcode ComponentVerdict
city ComponentVerdict
country ComponentVerdict

ResolvedAddress

The standardized address and WGS 84 coordinates of the best usable result, or null when no provider returned a result with valid coordinates.

FieldTypeDescription
street string
houseNumber string
postcode string
city string
state string
country string ISO 3166-1 alpha-2.
lat required number
lng required number

GeoPoint

FieldTypeDescription
lat required number
lng required number

TraceStep

One provider attempt in the routing trail.

FieldTypeDescription
provider required string
status required ok · error · timeout · aborted · skipped · circuit-open · no-coverage · unsupported · unknown-provider
latencyMs integer
resultCount integer
error string

Candidate

A provider result scored against the caller's input before the top-level consensus adjustment (debug only).

FieldTypeDescription
provider required string
components required AddressComponents Structured address parts. All fields optional.
location GeoPoint
providerConfidence number
range 0–1
Provider-native confidence normalized to 0..1; absent when the provider reports none.
label string
raw any Provider-native payload; shape varies per provider.
confidence required integer
range 0–100
componentVerdicts required ComponentVerdicts Per-component comparison of the best result against the input. Keys are only present for checked components.

ConsensusStatus

One of: unavailable, single-provider, agreement, partial-agreement, disagreement

ConsensusDifference

FieldTypeDescription
field required street · houseNumber · postcode · city · state · country · location
selected string
alternative string
distanceMeters number Present for a coordinate disagreement beyond the 25 metre agreement window.

ProviderDisagreement

FieldTypeDescription
provider required string
confidence required integer
range 0–100
The conflicting provider candidate's input-verification confidence.
differences required array of ConsensusDifference

ConsensusReport

FieldTypeDescription
status required ConsensusStatus
score required integer or null
range 0–100
Percentage of participating providers supporting the selected address; null when fewer than two providers answered.
baseConfidence required integer
range 0–100
Selected candidate confidence before provider consensus is blended in.
confidenceDelta required integer
range -100–100
Points added to or removed from baseConfidence to produce the top-level confidence.
supportingProviders required array of string
conflictingProviders required array of string
disagreements required array of ProviderDisagreement

ValidateResponse

FieldTypeDescription
verdict required Verdict - valid: confidence at or above the project's valid threshold and every checked component matched. - correctable: the address was found but something was fixed (the response carries the standardized address). - invalid: below the correctable threshold, or a supplied house number could not be matched.
confidence required integer
range 0–100
Unified confidence score, comparable across providers. 0 when no result was found.
address required ResolvedAddress The standardized address and WGS 84 coordinates of the best usable result, or null when no provider returned a result with valid coordinates.
components required ComponentVerdicts Per-component comparison of the best result against the input. Keys are only present for checked components.
provider required string or null Id of the provider that produced the best result, or null when there was none.
reasons required array of Reason
consensus required ConsensusReport
cached required boolean True when served from the response cache. Cached responses cost 0 credits.
candidates array of Candidate Only present when the request set "debug": true.
trace array of TraceStep Only present when the request set "debug": true.

AutocompleteRequest

FieldTypeDescription
query required string
length 1–200
Partial address text.
country string
length 2–2
ISO 3166-1 alpha-2 country bias/filter.
language string
length 2–8
limit integer
range 1–10, default 5
Maximum number of suggestions.
sessionToken string
length 0–64
Client-generated correlation id, echoed back unchanged. Correlation only; it does not deduplicate billing.
source string
length 1–64
Usage segmentation tag, as on /v1/validate.

Suggestion

FieldTypeDescription
label required string Formatted display label.
components required AddressComponents Structured address parts. All fields optional.
location GeoPoint
provider required string

AutocompleteResponse

FieldTypeDescription
suggestions required array of Suggestion
sessionToken required string or null The request's sessionToken, echoed back; null when none was sent.
cached required boolean

WidgetSuggestion

FieldTypeDescription
id required string Opaque suggestion id scoped to the publishable token (prefix gv_s_).
label required string
provider required string
address required AddressComponents Structured address parts. All fields optional.

WidgetAutocompleteResponse

FieldTypeDescription
suggestions required array of WidgetSuggestion
sessionToken required string or null
cached required boolean

UsageResponse

FieldTypeDescription
plan required string Current plan id (free, starter, growth, scale).
quota required integer Monthly plan credits.
extraCredits required integer Purchased pack credits still attributed to the account. Consumed only after the monthly grant.
creditsUsedThisMonth required integer Credits consumed by live and test credentials this calendar month (UTC). May lag the ledger by up to 60 seconds.
environment required live · test Environment of the API key used to request this report. The totals remain account-wide and include both environments.
filteredBySource required string or null The source filter applied to summary, daily, and recent, or null.
daily required array of object Daily request and credit counts for the last 14 days.
summary required array of object Current-month totals grouped by endpoint and verdict.
sources required array of object Current-month totals per source tag (untagged traffic groups under an empty string). Always account-wide, ignoring the source filter.
recent required array of object The 50 most recent usage events.

DemoValidateResponse

FieldTypeDescription
verdict required Verdict - valid: confidence at or above the project's valid threshold and every checked component matched. - correctable: the address was found but something was fixed (the response carries the standardized address). - invalid: below the correctable threshold, or a supplied house number could not be matched.
confidence required integer
range 0–100
address required ResolvedAddress The standardized address and WGS 84 coordinates of the best usable result, or null when no provider returned a result with valid coordinates.
components required ComponentVerdicts Per-component comparison of the best result against the input. Keys are only present for checked components.
provider required string or null
reasons required array of Reason
consensus required ConsensusReport

DemoRateLimitError

FieldTypeDescription
message required string
limits required array of object Every rolling window that is currently exhausted.
retryAfterSeconds required integer The longest wait among all exhausted windows.
freeMonthlyCredits required integer Monthly credits included with a free account (sign-up removes the demo limits).