{
  "info": {
    "name": "GeoVerdict API v1.0.0",
    "description": "Address validation and autocomplete through one API.\n\nSet the `apiKey` collection variable to a secret key from https://geoverdict.com/dashboard\nbefore sending the Validation, Autocomplete, or Usage requests.\n\nThe widget request additionally needs `widgetToken` (a gv_pk_ publishable token) and\n`widgetOrigin` set to an exact HTTPS origin on that token's allowlist.\n\nTest keys call the same real providers with a separate 5,000-credit daily allowance\nand best-effort 60-request/minute limit; they do not consume monthly plan credits.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://geoverdict.com",
      "type": "string"
    },
    {
      "key": "apiKey",
      "value": "ak_live_REPLACE_ME",
      "type": "string"
    },
    {
      "key": "widgetToken",
      "value": "gv_pk_live_REPLACE_ME",
      "type": "string"
    },
    {
      "key": "widgetOrigin",
      "value": "https://shop.example",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "Status",
      "description": "Service health.",
      "item": [
        {
          "name": "Service health",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/healthz",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "healthz"
              ]
            },
            "description": "Returns service status and the ids of the currently active geocoding providers. Free, unauthenticated."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Validation",
      "description": "Address validation with a normalized verdict and confidence score.",
      "item": [
        {
          "name": "Validate an address",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{apiKey}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/validate?source=",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "validate"
              ],
              "query": [
                {
                  "key": "source",
                  "value": "",
                  "description": "Fallback for the `source` body field; the body value wins when both are set.",
                  "disabled": true
                }
              ]
            },
            "description": "Validates a single address and returns a verdict, a 0-100 confidence score, the\nstandardized address, and per-component comparison results. Provide either a\nfree-form `query` or structured `components` (at least one is required).\n\nCosts 1 credit per provider that answered; a cache hit or a request where no\nprovider answers costs 0.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"query\": \"Prinsengracht 263, Amsterdam\",\n  \"country\": \"NL\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "Autocomplete",
      "description": "Address suggestions while the user types.",
      "item": [
        {
          "name": "Autocomplete an address",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{apiKey}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/autocomplete?source=",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "autocomplete"
              ],
              "query": [
                {
                  "key": "source",
                  "value": "",
                  "description": "Fallback for the `source` body field; the body value wins when both are set.",
                  "disabled": true
                }
              ]
            },
            "description": "Returns up to `limit` (default 5) address suggestions for a partial query.\nSuggestions are deduplicated across providers.\n\nEach uncached call costs 1 credit per provider that answered. A cache hit or a\nrequest where no provider answers costs 0. `sessionToken` is echoed back for\nclient-side correlation only; it does not deduplicate billing.\n\nFor browser-side autocomplete use the embeddable widget with a publishable\ntoken (`/v1/widget/autocomplete`) instead of exposing a secret key.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"query\": \"Prinsengracht 26\",\n  \"country\": \"NL\",\n  \"limit\": 5\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Browser widget autocomplete",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{widgetToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Origin",
                "value": "{{widgetOrigin}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/widget/autocomplete",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "widget",
                "autocomplete"
              ]
            },
            "description": "Browser-safe autocomplete for the embeddable GeoVerdict widget. Authenticates\nwith a project-scoped publishable token (`gv_pk_live_...` / `gv_pk_test_...`)\nand requires a request `Origin` on the token's exact HTTPS origin allowlist.\nSecret API keys (`ak_...`) and console sessions are rejected.\n\nSuggestions are mapped to a browser-safe shape with opaque ids; provider-native\nidentifiers and raw metadata are never returned. Per-token and per-origin rate\nlimits of 120 requests/minute apply in addition to the account credit gate.\nBilling matches server autocomplete: 1 credit per answering provider per\nuncached call.\n\nMost integrations should not call this endpoint directly; the hosted widget\n(`https://geoverdict.com/widget/v1/geoverdict-autocomplete.js`) implements the\ncontract, keyboard navigation, and accessibility.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"query\": \"Prinsengracht 26\",\n  \"country\": \"NL\",\n  \"limit\": 5,\n  \"sessionToken\": \"3f5a1c9e-session\",\n  \"source\": \"widget\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Widget CORS preflight",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "OPTIONS",
            "header": [
              {
                "key": "Origin",
                "value": "{{widgetOrigin}}"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/widget/autocomplete",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "widget",
                "autocomplete"
              ]
            },
            "description": "CORS preflight for the widget endpoint. Because browsers omit the\n`Authorization` value during preflight, the server reflects an origin only when\nan active publishable token currently allows it; the subsequent `POST` still\nbinds the exact token and origin."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Usage",
      "description": "Credit and usage reporting for the authenticated account.",
      "item": [
        {
          "name": "Usage and credit balance",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{apiKey}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/usage?source=",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "v1",
                "usage"
              ],
              "query": [
                {
                  "key": "source",
                  "value": "",
                  "description": "Filter `summary`, `daily`, and `recent` to a single `source` tag. `sources` always covers all tags.",
                  "disabled": true
                }
              ]
            },
            "description": "Current-month credit consumption plus recent activity for the account that owns\nthe API key. This call consumes no credits and never writes a usage event, but\nthe shared API-key quota gate still returns `429` after the account exhausts its\ncredits. Displays can lag the ledger by up to 60 seconds."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Demo",
      "description": "Unauthenticated, rate-limited demo used by the geoverdict.com homepage.",
      "item": [
        {
          "name": "Homepage demo validation",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/demo/validate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "demo",
                "validate"
              ]
            },
            "description": "Unauthenticated validation used by the geoverdict.com homepage demo. Forced to\nthe Netherlands (`country: NL`), costs 0 credits, and is rate limited per\nvisitor IP over rolling windows: 10 requests / 5 minutes, 20 / 24 hours,\n50 / 7 days, and 200 / 30 days. Not intended for production integrations; use\n`/v1/validate` with an API key instead.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"query\": \"prinsengrach 263, amsterdm\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    }
  ]
}
