{"openapi":"3.0.1","info":{"title":"GEOREFER API","description":"**Azmoris Geographic Reference Engine** — Production SaaS REST API for French geographic data, address validation, and enterprise intelligence.\n\n## Overview\n| Metric | Value |\n|--------|-------|\n| French cities | 37,000+ communes |\n| SIRENE companies | 16.8M+ active establishments |\n| Autocomplete latency | <50ms (Elasticsearch) |\n| Address validation | AFNOR NF Z 10-011 |\n\n## Base URL\n```\nhttps://georefer.io/geographical_repository/v1\n```\n\n## Features\n- **City Search** — 37,000+ French communes with pagination, postal/INSEE code lookup\n- **Autocomplete** — Elasticsearch-powered typeahead (<50ms response)\n- **Fuzzy Search** — Typo-tolerant city search with Levenshtein distance\n- **Address Validation** — KYC/AML postal address verification with confidence scoring\n- **AFNOR Normalization** — NF Z 10-011 postal address formatting\n- **GeoTrust Score** — Composite geographic reliability score (0-100), FATF/GAFI risk assessment\n- **City Enrichment** — Demographics, geography, economics data (PRO+)\n- **Companies** — 16.8M SIRENE establishments: SIREN/SIRET lookup, name search with trigram matching (PRO+)\n- **Commune History** — COG historical events (mergers, splits, name changes)\n- **Departments & Regions** — Full French administrative hierarchy (101 departments, 18 regions)\n- **Billing** — Self-service Stripe subscription management\n\n## Authentication\nAll endpoints require an API key via the `X-Georefer-API-Key` header.\n\n```\ncurl -H 'X-Georefer-API-Key: YOUR_API_KEY' https://georefer.io/geographical_repository/v1/cities?name=Paris\n```\n\n**Try it now** with the demo key: `demo-0000-0000-0000-000000000000`\n\n## Rate Limiting\nResponses include rate-limit headers:\n\n| Header | Description |\n|--------|-------------|\n| `X-RateLimit-Limit` | Max requests per minute |\n| `X-RateLimit-Remaining` | Remaining requests in window |\n| `X-RateLimit-Reset` | Seconds until limit resets |\n| `X-Georefer-Plan` | Your current plan name |\n\n## Response Format\nAll responses use a consistent JSON envelope:\n\n```json\n{\n  \"success\": true,\n  \"data\": { ... },\n  \"metadata\": { \"total_count\": 150, \"page\": 0, \"page_size\": 25 }\n}\n```\n\n## Error Handling\nErrors follow [RFC 7807](https://tools.ietf.org/html/rfc7807) Problem Details:\n\n| Code | Description |\n|------|-------------|\n| 400 | Bad Request — invalid parameters |\n| 401 | Unauthorized — missing or invalid API key |\n| 403 | Forbidden — feature not available on your plan |\n| 429 | Too Many Requests — rate limit or quota exceeded |\n| 500 | Internal Server Error |\n\n## Plans\n| Plan | Daily Limit | Rate/min | Features | Price |\n|------|------------|----------|----------|-------|\n| DEMO | 50/day | 10 | cities, countries, search | Free |\n| FREE | 100/day | 10 | cities, countries | Free |\n| STARTER | 5,000/day | 30 | + departments, regions, search | 49 EUR/mo |\n| PRO | 50,000/day | 60 | + companies, enrichment | 199 EUR/mo |\n| ENTERPRISE | Unlimited | 200 | + admin, bulk | Custom |\n\n## Changelog\n- **v3.1.0** (Mar 2026) — Redoc documentation, x-tagGroups, x-codeSamples, billing endpoints exposed\n- **v3.0.0** (Feb 2026) — SIRENE 16.8M companies, Stripe billing, developer portal, GeoTrust Score\n- **v2.0.0** (Feb 2026) — Elasticsearch autocomplete, fuzzy search, address validation, AFNOR normalization","contact":{"name":"AZMORIS Group","url":"https://georefer.io","email":"support@georefer.io"},"license":{"name":"Copyright 2026 AZMORIS"},"version":"3.1.0"},"externalDocs":{"description":"GEOREFER Interactive Playground","url":"https://georefer.io/#playground"},"servers":[{"url":"https://georefer.io","description":"Production"},{"url":"http://localhost:8081","description":"Development"}],"security":[{"ApiKeyAuth":[]}],"tags":[{"name":"Address Validation","description":"Address validation for KYC/AML compliance"},{"name":"Cities","description":"Geographic city/town reference data endpoints"},{"name":"City Enrichment","description":"Geographic city enrichment data (demographics, geography, economics)"},{"name":"Companies","description":"French business establishment reference data (Sirene directory)"},{"name":"Regions","description":"French administrative regions"},{"name":"Search","description":"Elasticsearch index management and search operations"},{"name":"Monitoring","description":"Application monitoring and info endpoints"},{"name":"Countries","description":"Country reference data — ISO 3166-1 country lookups"},{"name":"Billing","description":"Stripe subscription management"},{"name":"Admin","description":"Admin dashboard and API key management (admin keys only)"},{"name":"Commune History","description":"French commune historical events (COG)"},{"name":"Developer Portal","description":"Self-service API key registration and recovery"},{"name":"Departments","description":"French administrative departments"},{"name":"API Info","description":"API key status and usage information"},{"name":"Usage","description":"Self-service usage statistics"}],"paths":{"/geographical_repository/v1/search/reindex":{"post":{"tags":["Search"],"summary":"Reindex all cities into Elasticsearch","description":"Drops the existing index and reindexes all French cities from PostgreSQL. This operation may take several seconds depending on database size.","operationId":"reindex","responses":{"200":{"description":"Reindexation completed (check status field)","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/geographical_repository/v1/billing/portal":{"post":{"tags":["Billing"],"summary":"Create customer portal session","description":"Creates a Stripe Customer Portal session. User can manage subscription and payment methods.","operationId":"createPortal","responses":{"200":{"description":"Portal session created — redirect user to portalUrl","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No Stripe customer found — subscribe first","content":{"*/*":{"schema":{"type":"object"}}}},"503":{"description":"Stripe billing not configured","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/geographical_repository/v1/billing/checkout":{"post":{"tags":["Billing"],"summary":"Create checkout session","description":"Creates a Stripe Checkout session to upgrade to STARTER or PRO plan. Returns a checkout URL for redirection.","operationId":"createCheckout","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Checkout session created — redirect user to checkoutUrl","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid plan or cannot upgrade (already on higher plan)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"type":"object"}}}},"503":{"description":"Stripe billing not configured","content":{"*/*":{"schema":{"type":"object"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"curl -X POST 'https://georefer.io/geographical_repository/v1/billing/checkout' \\\n  -H 'Content-Type: application/json' \\\n  -H 'X-Georefer-API-Key: YOUR_API_KEY' \\\n  -d '{\"plan\": \"STARTER\"}'"}]}},"/geographical_repository/v1/billing/cancel":{"post":{"tags":["Billing"],"summary":"Cancel subscription","description":"Cancels the subscription at end of billing period. Key keeps current plan until period ends.","operationId":"cancelSubscription","responses":{"200":{"description":"Cancellation scheduled","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"No active subscription to cancel","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"type":"object"}}}},"503":{"description":"Stripe billing not configured","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/geographical_repository/v1/api/register":{"post":{"tags":["Developer Portal"],"summary":"Register for a FREE API key","description":"Create a new FREE plan API key. Requires name and email. One key per email address. The full API key is shown only once in the response — save it immediately.","operationId":"register","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"409":{"description":"Email already registered","content":{"*/*":{"schema":{"type":"object"}}}},"429":{"description":"Rate limit exceeded — max 3 registrations per hour per IP","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request (missing fields or invalid email)","content":{"*/*":{"schema":{"type":"object"}}}},"201":{"description":"API key created successfully","content":{"*/*":{"schema":{"type":"object"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"curl -X POST 'https://georefer.io/geographical_repository/v1/api/register' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"email\": \"dev@example.com\",\n    \"name\": \"John Doe\",\n    \"company\": \"Acme Corp\",\n    \"plan\": \"FREE\"\n  }'"},{"lang":"Python","label":"Python","source":"import requests\n\nresponse = requests.post(\n    'https://georefer.io/geographical_repository/v1/api/register',\n    json={\n        'email': 'dev@example.com',\n        'name': 'John Doe',\n        'company': 'Acme Corp',\n        'plan': 'FREE'\n    }\n)\napi_key = response.json()['data']['api_key']\nprint(f'Your API key: {api_key}')"}]}},"/geographical_repository/v1/api/recover":{"post":{"tags":["Developer Portal"],"summary":"Recover API key by email","description":"Returns a masked hint of your API key. The full key was shown only once at registration.","operationId":"recover","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecoverRequest"}}},"required":true},"responses":{"404":{"description":"No active key found for this email","content":{"*/*":{"schema":{"type":"object"}}}},"200":{"description":"Key hint returned","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request (missing or invalid email)","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/geographical_repository/v1/admin/keys":{"get":{"tags":["Admin"],"summary":"List all API keys","description":"Returns all API keys with masked values. Admin key only.","operationId":"listKeys","responses":{"403":{"description":"Requires admin access","content":{"*/*":{"schema":{"type":"object"}}}},"200":{"description":"Successful operation — list of API keys returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"type":"object"}}}}}},"post":{"tags":["Admin"],"summary":"Create a new API key","description":"Creates a new API key for a given plan. Admin key only.","operationId":"createKey","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyRequest"}}},"required":true},"responses":{"403":{"description":"Requires admin access","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request parameters (missing fields or unknown plan)","content":{"*/*":{"schema":{"type":"object"}}}},"201":{"description":"API key created successfully","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/geographical_repository/v1/addresses/validate":{"post":{"tags":["Address Validation"],"summary":"Validate a postal address","description":"Validates a postal address for KYC/AML compliance. Performs country verification, postal code matching, and confidence scoring.","operationId":"validateAddress","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressValidationRequest"}}},"required":true},"responses":{"200":{"description":"Address validation completed (regardless of validity)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AddressValidationResponse"}}}},"401":{"description":"Unauthorized - missing or invalid API key","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AddressValidationResponse"}}}},"400":{"description":"Bad request - missing or invalid required fields","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AddressValidationResponse"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"curl -X POST 'https://georefer.io/geographical_repository/v1/addresses/validate' \\\n  -H 'Content-Type: application/json' \\\n  -H 'X-Georefer-API-Key: YOUR_API_KEY' \\\n  -d '{\n    \"street_line\": \"15 Rue de la Paix\",\n    \"postal_code\": \"75002\",\n    \"city\": \"Paris\",\n    \"country_code\": \"FR\"\n  }'"},{"lang":"Python","label":"Python","source":"import requests\n\nresponse = requests.post(\n    'https://georefer.io/geographical_repository/v1/addresses/validate',\n    headers={'X-Georefer-API-Key': 'YOUR_API_KEY'},\n    json={\n        'street_line': '15 Rue de la Paix',\n        'postal_code': '75002',\n        'city': 'Paris',\n        'country_code': 'FR'\n    }\n)\nprint(response.json())"},{"lang":"JavaScript","label":"JavaScript","source":"const response = await fetch(\n  'https://georefer.io/geographical_repository/v1/addresses/validate',\n  {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      'X-Georefer-API-Key': 'YOUR_API_KEY'\n    },\n    body: JSON.stringify({\n      street_line: '15 Rue de la Paix',\n      postal_code: '75002',\n      city: 'Paris',\n      country_code: 'FR'\n    })\n  }\n);\nconst data = await response.json();"}]}},"/geographical_repository/v1/addresses/normalize":{"post":{"tags":["Address Validation"],"summary":"Normalize a postal address (AFNOR NF Z 10-011)","description":"Normalizes a French postal address according to AFNOR NF Z 10-011 / La Poste standards. Applies uppercase, accent removal, progressive abbreviation, and 38-char line limits. Full normalization for France (FR), basic normalization for other countries.","operationId":"normalizeAddress","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddressNormalizationRequest"}}},"required":true},"responses":{"401":{"description":"Unauthorized - missing or invalid API key","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AddressNormalizationResponse"}}}},"400":{"description":"Bad request - missing or invalid required fields","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AddressNormalizationResponse"}}}},"200":{"description":"Address normalization completed","content":{"*/*":{"schema":{"$ref":"#/components/schemas/AddressNormalizationResponse"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"curl -X POST 'https://georefer.io/geographical_repository/v1/addresses/normalize' \\\n  -H 'Content-Type: application/json' \\\n  -H 'X-Georefer-API-Key: YOUR_API_KEY' \\\n  -d '{\n    \"street_line\": \"15 rue de la paix\",\n    \"postal_code\": \"75002\",\n    \"city\": \"paris\",\n    \"country_code\": \"FR\"\n  }'"}]}},"/geographical_repository/v1/admin/contacts/{id}/read":{"patch":{"tags":["Admin"],"summary":"Mark contact as read","description":"Sets is_read=true for a contact message. Requires admin key.","operationId":"markContactRead","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int64"}}],"responses":{"404":{"description":"Contact message not found","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Requires admin access","content":{"*/*":{"schema":{"type":"object"}}}},"200":{"description":"Contact marked as read","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/monitoring/info":{"get":{"tags":["Monitoring"],"summary":"Get application info and statistics","operationId":"getInfo","responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/geographical_repository/v1/search/stats":{"get":{"tags":["Search"],"summary":"Get Elasticsearch index statistics","description":"Returns current index stats including document count, index name, and health status.","operationId":"stats","responses":{"200":{"description":"Index statistics","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"object"}}}}}}}},"/geographical_repository/v1/regions":{"get":{"tags":["Regions"],"summary":"Get all French regions","description":"Returns list of all 18 French regions (13 metropolitan + 5 DOM) with their department codes","operationId":"getAllRegions","responses":{"200":{"description":"List of regions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionDTO"}}}}}}},"/geographical_repository/v1/regions/{code}":{"get":{"tags":["Regions"],"summary":"Get region by code","description":"Returns a specific region with all its departments","operationId":"getRegionByCode","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Region found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionDTO"}}}},"404":{"description":"Region not found","content":{"application/json;charset=UTF-8":{"schema":{"$ref":"#/components/schemas/RegionDTO"}}}}}}},"/geographical_repository/v1/regions/{code}/departments":{"get":{"tags":["Regions"],"summary":"Get departments in a region","description":"Returns all departments for a specific region","operationId":"getDepartmentsByRegion","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"404":{"description":"Region not found","content":{"application/json;charset=UTF-8":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DepartmentDTO"}}}}},"200":{"description":"List of departments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DepartmentDTO"}}}}}}},"/geographical_repository/v1/departments":{"get":{"tags":["Departments"],"summary":"Get all French departments","description":"Returns list of all 101 French departments (96 metropolitan + 5 DOM) with their region information","operationId":"getAllDepartments","responses":{"200":{"description":"List of departments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DepartmentDTO"}}}}}}},"/geographical_repository/v1/departments/{code}":{"get":{"tags":["Departments"],"summary":"Get department by code","description":"Returns a specific department with region information","operationId":"getDepartmentByCode","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Department found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DepartmentDTO"}}}},"404":{"description":"Department not found","content":{"application/json;charset=UTF-8":{"schema":{"$ref":"#/components/schemas/DepartmentDTO"}}}}}}},"/geographical_repository/v1/departments/{code}/cities":{"get":{"tags":["Departments"],"summary":"Get cities in a department","description":"Returns all cities/towns in a specific department with pagination support","operationId":"getCitiesByDepartment","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}},{"name":"size","in":"query","required":false,"schema":{"maximum":500,"minimum":0,"type":"integer","format":"int32","default":100}}],"responses":{"200":{"description":"List of cities","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResponse"}}}},"404":{"description":"Department not found","content":{"application/json;charset=UTF-8":{"schema":{"$ref":"#/components/schemas/PagedResponseCityDTO"}}}}}}},"/geographical_repository/v1/countries":{"get":{"tags":["Countries"],"summary":"Search countries by name","description":"Search for countries by name with optional exact matching. Returns ISO 3166-1 alpha-2/alpha-3 codes, country labels, and status. Available on all plans (FREE+).","operationId":"getCountry","parameters":[{"name":"name","in":"query","description":"Country name to search for","required":true,"schema":{"type":"string"},"example":"France"},{"name":"is_exact_match","in":"query","description":"If true, match exact name only; if false/null, partial match (contains)","required":false,"schema":{"type":"boolean"},"example":false},{"name":"max_results","in":"query","description":"Maximum number of results to return","required":false,"schema":{"type":"integer","format":"int32"},"example":10}],"responses":{"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CountryDTO"}}}}},"400":{"description":"Invalid request — name parameter is required","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CountryDTO"}}}}},"200":{"description":"Countries matching the search criteria","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CountryDTO"}}}}}}}},"/geographical_repository/v1/companies":{"get":{"tags":["Companies"],"summary":"Search companies by SIREN, SIRET, or name","description":"Lookup establishments by SIREN (9 digits, returns all establishments), SIRET (14 digits, returns single establishment), or search by company name with optional postal code, department, and NAF code filters. Priority: siren > siret > name search.","operationId":"getCompanies","parameters":[{"name":"siren","in":"query","description":"SIREN number (9 digits) — returns all establishments for the company","required":false,"schema":{"pattern":"\\d{9}","type":"string"}},{"name":"siret","in":"query","description":"SIRET number (14 digits) — returns the specific establishment","required":false,"schema":{"pattern":"\\d{14}","type":"string"}},{"name":"name","in":"query","description":"Company name search term (min 2 characters, searches both company name and trade name)","required":false,"schema":{"maxLength":128,"minLength":2,"type":"string"}},{"name":"postal_code","in":"query","description":"Filter by postal code (5 digits)","required":false,"schema":{"type":"string"}},{"name":"department_code","in":"query","description":"Filter by department code (2-3 chars)","required":false,"schema":{"type":"string"}},{"name":"naf_code","in":"query","description":"Filter by NAF/APE activity code (e.g., '70.10Z')","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number (0-indexed)","required":false,"schema":{"minimum":0,"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","description":"Number of results per page (max 100)","required":false,"schema":{"maximum":100,"minimum":0,"type":"integer","format":"int32","default":25}}],"responses":{"404":{"description":"No establishment found for given SIREN/SIRET","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySearchResponse"}}}},"200":{"description":"Successful search with results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySearchResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySearchResponse"}}}},"400":{"description":"Invalid request parameters (SIREN/SIRET format, name too short)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySearchResponse"}}}},"403":{"description":"Feature not available on your plan — requires PRO or ENTERPRISE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySearchResponse"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# Search by SIREN\ncurl 'https://georefer.io/geographical_repository/v1/companies?siren=552120222' \\\n  -H 'X-Georefer-API-Key: YOUR_API_KEY'\n\n# Search by name\ncurl 'https://georefer.io/geographical_repository/v1/companies/search?name=BNP+Paribas&limit=5' \\\n  -H 'X-Georefer-API-Key: YOUR_API_KEY'"},{"lang":"Python","label":"Python","source":"import requests\n\n# Search by SIREN\nresponse = requests.get(\n    'https://georefer.io/geographical_repository/v1/companies',\n    params={'siren': '552120222'},\n    headers={'X-Georefer-API-Key': 'YOUR_API_KEY'}\n)\ncompany = response.json()['results'][0]\nprint(company['company_name'], company['legal_form'])"},{"lang":"JavaScript","label":"JavaScript","source":"const response = await fetch(\n  'https://georefer.io/geographical_repository/v1/companies?siren=552120222',\n  { headers: { 'X-Georefer-API-Key': 'YOUR_API_KEY' } }\n);\nconst { results } = await response.json();\nconsole.log(results[0].company_name);"}]}},"/geographical_repository/v1/companies/{siret}":{"get":{"tags":["Companies"],"summary":"Get detailed establishment information by SIRET","description":"Returns comprehensive details for a specific establishment identified by its SIRET number.","operationId":"getEstablishmentDetail","parameters":[{"name":"siret","in":"path","description":"SIRET number (14 digits)","required":true,"schema":{"pattern":"\\d{14}","type":"string"}}],"responses":{"400":{"description":"Invalid SIRET format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTO"}}}},"200":{"description":"Establishment details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTO"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTO"}}}},"404":{"description":"Establishment not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTO"}}}},"403":{"description":"Feature not available on your plan — requires PRO or ENTERPRISE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDTO"}}}}}}},"/geographical_repository/v1/companies/search":{"get":{"tags":["Companies"],"summary":"Search companies by name with filters","description":"Full-text company name search with optional geographic and activity filters. Searches both registered company name (raison sociale) and trade name (enseigne). Results are paginated and sorted alphabetically by company name.","operationId":"searchCompanies","parameters":[{"name":"name","in":"query","description":"Company name search term (min 2 chars)","required":true,"schema":{"maxLength":128,"minLength":2,"type":"string"}},{"name":"postal_code","in":"query","description":"Filter by postal code","required":false,"schema":{"type":"string"}},{"name":"department_code","in":"query","description":"Filter by department code","required":false,"schema":{"type":"string"}},{"name":"naf_code","in":"query","description":"Filter by NAF/APE code","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","description":"Page number (0-indexed)","required":false,"schema":{"minimum":0,"type":"integer","format":"int32","default":0},"example":0},{"name":"size","in":"query","description":"Number of results per page (max 100)","required":false,"schema":{"maximum":100,"minimum":0,"type":"integer","format":"int32","default":10},"example":10},{"name":"limit","in":"query","description":"Limit number of results (overrides size, max 50)","required":false,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"Search results with pagination","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySearchResponse"}}}},"400":{"description":"Invalid search parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySearchResponse"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySearchResponse"}}}},"403":{"description":"Feature not available on your plan — requires PRO or ENTERPRISE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySearchResponse"}}}}}}},"/geographical_repository/v1/cities":{"get":{"tags":["Cities"],"summary":"Search cities by criteria with pagination","description":"Search for cities/towns matching the given criteria with support for pagination. Can search by name, postal code, or INSEE code. INSEE code takes priority when provided.","operationId":"getCities","parameters":[{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"is_current_city","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"country_code","in":"query","required":false,"schema":{"type":"string"}},{"name":"district_code","in":"query","required":false,"schema":{"type":"string"}},{"name":"department_code","in":"query","required":false,"schema":{"type":"string"}},{"name":"postal_code","in":"query","required":false,"schema":{"type":"string"}},{"name":"insee_code","in":"query","required":false,"schema":{"type":"string"}},{"name":"is_exact_match","in":"query","required":false,"schema":{"type":"boolean"}},{"name":"max_results","in":"query","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"page","in":"query","required":false,"schema":{"maximum":10000,"minimum":0,"type":"integer","format":"int32","default":0}},{"name":"size","in":"query","required":false,"schema":{"maximum":100,"minimum":0,"type":"integer","format":"int32","default":25}},{"name":"search_date","in":"query","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResponseCityDTO"}}}},"204":{"description":"No cities found matching criteria","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResponseCityDTO"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResponseCityDTO"}}}},"200":{"description":"Successful search with results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PagedResponse"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"curl 'https://georefer.io/geographical_repository/v1/cities?name=Paris&country_code=FR&size=10' \\\n  -H 'X-Georefer-API-Key: YOUR_API_KEY'"},{"lang":"Python","label":"Python","source":"import requests\n\nresponse = requests.get(\n    'https://georefer.io/geographical_repository/v1/cities',\n    params={'name': 'Paris', 'country_code': 'FR', 'size': 10},\n    headers={'X-Georefer-API-Key': 'YOUR_API_KEY'}\n)\nprint(response.json())"},{"lang":"JavaScript","label":"JavaScript","source":"const response = await fetch(\n  'https://georefer.io/geographical_repository/v1/cities?name=Paris&country_code=FR&size=10',\n  { headers: { 'X-Georefer-API-Key': 'YOUR_API_KEY' } }\n);\nconst data = await response.json();"}]}},"/geographical_repository/v1/cities/{insee_code}/successors":{"get":{"tags":["Commune History"],"summary":"Get commune successor","description":"Returns the current commune that absorbed/replaced this one, or null if still active","operationId":"getSuccessor","parameters":[{"name":"insee_code","in":"path","description":"INSEE code (5 digits)","required":true,"schema":{"pattern":"\\d{5}","type":"string"}}],"responses":{"200":{"description":"Successful operation — successor information returned","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommuneSuccessorDTO"}}}},"400":{"description":"Invalid request parameters (INSEE code format)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommuneSuccessorDTO"}}}},"404":{"description":"Commune not found for given INSEE code","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommuneSuccessorDTO"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommuneSuccessorDTO"}}}}}}},"/geographical_repository/v1/cities/{insee_code}/history":{"get":{"tags":["Commune History"],"summary":"Get commune historical events","description":"Returns all historical events for a commune with optional filtering","operationId":"getHistory","parameters":[{"name":"insee_code","in":"path","description":"INSEE code (5 digits)","required":true,"schema":{"pattern":"\\d{5}","type":"string"}},{"name":"eventType","in":"query","description":"Event type filter (FUSION, ABSORPTION, CHANGEMENT_NOM, etc.)","required":false,"schema":{"type":"string"}},{"name":"from","in":"query","description":"Start date (YYYY-MM-DD)","required":false,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","description":"End date (YYYY-MM-DD)","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"400":{"description":"Invalid request parameters (INSEE code format)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommuneHistoryDTO"}}}},"404":{"description":"Commune not found for given INSEE code","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommuneHistoryDTO"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommuneHistoryDTO"}}}},"200":{"description":"Successful operation — commune history returned","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CommuneHistoryDTO"}}}}}}},"/geographical_repository/v1/cities/{insee_code}/enrichment":{"get":{"tags":["City Enrichment"],"summary":"Get city enrichment data","description":"Returns comprehensive geographical, demographic, and socioeconomic data for a French commune","operationId":"getEnrichment","parameters":[{"name":"insee_code","in":"path","description":"INSEE code (5 digits)","required":true,"schema":{"pattern":"\\d{5}","type":"string"}}],"responses":{"400":{"description":"Invalid request parameters (INSEE code format)","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CityEnrichmentDTO"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CityEnrichmentDTO"}}}},"404":{"description":"City or enrichment data not found for given INSEE code","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CityEnrichmentDTO"}}}},"403":{"description":"Feature not available on your plan — requires PRO or ENTERPRISE","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CityEnrichmentDTO"}}}},"200":{"description":"Successful operation — enrichment data returned","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CityEnrichmentDTO"}}}}}}},"/geographical_repository/v1/cities/statistics":{"get":{"tags":["City Enrichment"],"summary":"Get city enrichment statistics","description":"Returns aggregated statistics and distributions across all enriched cities","operationId":"getStatistics","responses":{"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CityStatisticsDTO"}}}},"200":{"description":"Successful operation — statistics returned","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CityStatisticsDTO"}}}},"403":{"description":"Feature not available on your plan — requires PRO or ENTERPRISE","content":{"*/*":{"schema":{"$ref":"#/components/schemas/CityStatisticsDTO"}}}}}}},"/geographical_repository/v1/cities/search":{"get":{"tags":["Cities"],"summary":"Fuzzy search for cities with typo tolerance","description":"Full-text city search with optional fuzzy matching for typo tolerance. Uses a multi-layer strategy: exact match (boost 3.0), fuzzy match with Levenshtein distance (boost 1.5), and normalized wildcard match (boost 1.0). Results are sorted by relevance then population. Falls back to PostgreSQL if Elasticsearch is unavailable.","operationId":"fuzzySearch","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"country_code","in":"query","required":false,"schema":{"type":"string"}},{"name":"fuzzy","in":"query","required":false,"schema":{"type":"boolean","default":true}}],"responses":{"400":{"description":"Invalid query parameters (query too short, limit out of range)","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object"}}}},"200":{"description":"Search results with fuzzy matches","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutocompleteResponse"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"# Fuzzy search with typo tolerance\ncurl 'https://georefer.io/geographical_repository/v1/cities/search?q=marsseille&limit=5' \\\n  -H 'X-Georefer-API-Key: YOUR_API_KEY'"},{"lang":"Python","label":"Python","source":"import requests\n\n# Typo-tolerant search: 'marsseille' -> 'Marseille'\nresponse = requests.get(\n    'https://georefer.io/geographical_repository/v1/cities/search',\n    params={'q': 'marsseille', 'limit': 5},\n    headers={'X-Georefer-API-Key': 'YOUR_API_KEY'}\n)\nprint(response.json())"}]}},"/geographical_repository/v1/cities/autocomplete":{"get":{"tags":["Cities"],"summary":"Autocomplete for city names (Elasticsearch-powered)","description":"Typeahead/autocomplete endpoint using Elasticsearch completion suggest. Returns rich suggestions with label, display, coordinates, and population. Falls back to PostgreSQL if Elasticsearch is unavailable. Supports prefix matching, postal code search (if query starts with digit), and optional country filtering.","operationId":"autocomplete","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32"}},{"name":"country_code","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"400":{"description":"Invalid query parameters (query too short, limit out of range)","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"type":"object"}}}},"200":{"description":"Autocomplete suggestions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutocompleteResponse"}}}}},"x-codeSamples":[{"lang":"Shell","label":"cURL","source":"curl 'https://georefer.io/geographical_repository/v1/cities/autocomplete?q=marseil&limit=5' \\\n  -H 'X-Georefer-API-Key: YOUR_API_KEY'"},{"lang":"Python","label":"Python","source":"import requests\n\nresponse = requests.get(\n    'https://georefer.io/geographical_repository/v1/cities/autocomplete',\n    params={'q': 'marseil', 'limit': 5},\n    headers={'X-Georefer-API-Key': 'YOUR_API_KEY'}\n)\nfor city in response.json().get('data', []):\n    print(city['name'], city.get('postal_code', ''))"},{"lang":"JavaScript","label":"JavaScript","source":"const response = await fetch(\n  'https://georefer.io/geographical_repository/v1/cities/autocomplete?q=marseil&limit=5',\n  { headers: { 'X-Georefer-API-Key': 'YOUR_API_KEY' } }\n);\nconst { data } = await response.json();\ndata.forEach(city => console.log(city.name));"}]}},"/geographical_repository/v1/billing/status":{"get":{"tags":["Billing"],"summary":"Get billing status","description":"Returns the billing status for the current API key: plan, subscription status, invoices.","operationId":"getBillingStatus","responses":{"200":{"description":"Billing status returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/geographical_repository/v1/api/usage":{"get":{"tags":["Usage"],"summary":"Get your usage statistics","description":"Returns usage breakdown for your API key. Supports period: today, week, month, or custom with from/to dates.","operationId":"getUsage","parameters":[{"name":"period","in":"query","description":"Time period: today, week, month, or custom","required":false,"schema":{"type":"string","default":"today"},"example":"week"},{"name":"from","in":"query","description":"Start date for custom period (yyyy-MM-dd)","required":false,"schema":{"type":"string"},"example":"2026-01-01"},{"name":"to","in":"query","description":"End date for custom period (yyyy-MM-dd)","required":false,"schema":{"type":"string"},"example":"2026-01-31"}],"responses":{"404":{"description":"API key not found","content":{"*/*":{"schema":{"type":"object"}}}},"200":{"description":"Successful operation — usage statistics returned","content":{"*/*":{"schema":{"type":"object"}}}},"400":{"description":"Invalid request parameters (bad period or date format)","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/geographical_repository/v1/api/info":{"get":{"tags":["API Info"],"summary":"Get API key status","description":"Returns your plan, quotas, current usage, and available features.","operationId":"getApiInfo","responses":{"200":{"description":"Successful operation — API key info returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/geographical_repository/v1/admin/usage":{"get":{"tags":["Admin"],"summary":"Global usage statistics","description":"Aggregated usage across all keys. Supports group_by: key (default), plan, day. Admin key only.","operationId":"getGlobalUsage","parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","default":"today"}},{"name":"from","in":"query","required":false,"schema":{"type":"string"}},{"name":"to","in":"query","required":false,"schema":{"type":"string"}},{"name":"group_by","in":"query","required":false,"schema":{"type":"string","default":"key"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/geographical_repository/v1/admin/usage/{keyIdentifier}":{"get":{"tags":["Admin"],"summary":"Usage statistics for a specific key","description":"Detailed usage for a specific API key. Accepts numeric ID or UUID key value. Admin key only.","operationId":"getKeyUsage","parameters":[{"name":"keyIdentifier","in":"path","required":true,"schema":{"type":"string"}},{"name":"period","in":"query","required":false,"schema":{"type":"string","default":"today"}},{"name":"from","in":"query","required":false,"schema":{"type":"string"}},{"name":"to","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/geographical_repository/v1/admin/plans":{"get":{"tags":["Admin"],"summary":"List available plans","description":"Returns all active subscription plans. Admin key only.","operationId":"listPlans","responses":{"403":{"description":"Requires admin access","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"type":"object"}}}},"200":{"description":"Successful operation — list of plans returned","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/geographical_repository/v1/admin/dashboard":{"get":{"tags":["Admin"],"summary":"Admin dashboard metrics","description":"Returns all KPIs, charts data, and tables in a single payload. Requires admin key.","operationId":"getDashboard","responses":{"403":{"description":"Requires admin access (is_admin=true)","content":{"*/*":{"schema":{"type":"object"}}}},"200":{"description":"Dashboard data returned","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"type":"object"}}}}}}},"/geographical_repository/v1/addresses/suggest":{"get":{"tags":["Address Validation"],"summary":"Get BAN address suggestions","description":"Returns street name suggestions from BAN (Base Adresse Nationale) for autocomplete. Optionally filter by postal_code or city. Without filters, returns top streets from all cities. Query must be at least 3 characters.","operationId":"suggestAddresses","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"}},{"name":"postal_code","in":"query","required":false,"schema":{"type":"string"}},{"name":"city","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","format":"int32","default":8}}],"responses":{"401":{"description":"Unauthorized - missing or invalid API key","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AddressSuggestDTO"}}}}},"200":{"description":"Suggestions returned","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AddressSuggestDTO"}}}}},"400":{"description":"Bad request - query too short (min 3 characters)","content":{"*/*":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AddressSuggestDTO"}}}}}}}},"/geographical_repository/v1/admin/keys/{keyIdentifier}":{"delete":{"tags":["Admin"],"summary":"Revoke an API key","description":"Deactivates an API key by numeric ID or UUID key value. Admin key only.","operationId":"revokeKey","parameters":[{"name":"keyIdentifier","in":"path","description":"API key ID (numeric) or key value (UUID) to revoke","required":true,"schema":{"type":"string"}}],"responses":{"404":{"description":"API key not found","content":{"*/*":{"schema":{"type":"object"}}}},"403":{"description":"Requires admin access","content":{"*/*":{"schema":{"type":"object"}}}},"200":{"description":"API key revoked successfully","content":{"*/*":{"schema":{"type":"object"}}}},"401":{"description":"Missing or invalid API key","content":{"*/*":{"schema":{"type":"object"}}}}}}}},"components":{"schemas":{"CheckoutRequest":{"required":["plan"],"type":"object","properties":{"plan":{"pattern":"^(STARTER|PRO)$","type":"string","description":"Target plan name","example":"STARTER","enum":["STARTER","PRO"]}},"description":"Checkout request to upgrade plan"},"RegisterRequest":{"required":["email","name"],"type":"object","properties":{"name":{"maxLength":128,"minLength":2,"type":"string"},"email":{"maxLength":255,"minLength":0,"type":"string"},"organization":{"maxLength":255,"minLength":0,"type":"string"},"use_case":{"maxLength":500,"minLength":0,"type":"string"}}},"RecoverRequest":{"required":["email"],"type":"object","properties":{"email":{"maxLength":255,"minLength":0,"type":"string"}}},"CreateApiKeyRequest":{"required":["client_name"],"type":"object","properties":{"client_name":{"maxLength":128,"minLength":1,"type":"string"},"client_email":{"maxLength":255,"minLength":0,"type":"string"},"organization":{"maxLength":255,"minLength":0,"type":"string"},"plan_name":{"type":"string"},"plan_code":{"type":"string","writeOnly":true}}},"AddressValidationRequest":{"type":"object","properties":{"city":{"maxLength":128,"minLength":0,"type":"string"},"street":{"maxLength":256,"minLength":0,"type":"string"},"postal_code":{"maxLength":10,"minLength":0,"type":"string"},"country_code":{"maxLength":2,"minLength":0,"type":"string"},"department_code":{"maxLength":3,"minLength":0,"type":"string"},"insee_code":{"maxLength":5,"minLength":0,"type":"string"}}},"AddressSuggestionDTO":{"type":"object","properties":{"postal_code":{"type":"string"},"city":{"type":"string"},"insee_code":{"type":"string"},"department_code":{"type":"string"}}},"AddressValidationResponse":{"type":"object","properties":{"validation_status":{"type":"string"},"confidence_score":{"type":"number","format":"double"},"input":{"$ref":"#/components/schemas/AddressValidationRequest"},"validated_address":{"$ref":"#/components/schemas/ValidatedAddressDTO"},"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationErrorDTO"}},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/ValidationWarningDTO"}},"suggestions":{"type":"array","items":{"$ref":"#/components/schemas/AddressSuggestionDTO"}},"geo_trust_score":{"$ref":"#/components/schemas/GeoTrustScoreDTO"},"timestamp":{"type":"string"}}},"GeoTrustMetadataDTO":{"type":"object","properties":{"fatf_status":{"type":"string","description":"FATF membership status","example":"member","enum":["member","grey_list","black_list","non_member"]},"aml_zone":{"type":"string","description":"AML risk zone classification","example":"low_risk","enum":["low_risk","medium_risk","high_risk","very_high_risk"]},"country_code":{"type":"string","description":"ISO 3166-1 alpha-2 country code","example":"FR"},"last_risk_update":{"type":"string","description":"Date of last FATF/EU risk data update (ISO format)","example":"2026-02-13"}},"description":"GeoTrust metadata - FATF/GAFI status and AML zone classification"},"GeoTrustScoreDTO":{"type":"object","properties":{"street_match":{"maximum":100,"minimum":0,"type":"integer","description":"BAN street-level validation score (0-100). 100=exact match in BAN, 70=partial, 40=fuzzy, 20=no street input, 0=street not found.","format":"int32","example":100},"confidence":{"maximum":100,"minimum":0,"type":"integer","description":"Address matching confidence score (0-100). Based on postal code, city, department, and INSEE code matching.","format":"int32","example":85},"geo_consistency":{"maximum":100,"minimum":0,"type":"integer","description":"Geographic consistency score (0-100). Cross-validates postal code, commune, department, and region layers.","format":"int32","example":100},"postal_match":{"maximum":100,"minimum":0,"type":"integer","description":"Postal code matching precision score (0-100). 100=exact match, 80=multiple possible, 60=fallback, 0=invalid.","format":"int32","example":100},"country_risk":{"maximum":100,"minimum":0,"type":"integer","description":"Country risk score based on FATF/GAFI data (0-100). 0=no risk, 100=highest risk.","format":"int32","example":8},"geo_trust_score":{"maximum":100,"minimum":0,"type":"integer","description":"Composite weighted score: streetMatch*0.30 + confidence*0.20 + geoConsistency*0.20 + postalMatch*0.15 + (100-countryRisk)*0.15","format":"int32","example":88},"risk_level":{"type":"string","description":"Risk level derived from geoTrustScore: LOW (>=80), MEDIUM (>=60), HIGH (>=40), VERY_HIGH (<40)","example":"LOW","enum":["LOW","MEDIUM","HIGH","VERY_HIGH"]},"street_validation":{"$ref":"#/components/schemas/StreetValidationResult"},"metadata":{"$ref":"#/components/schemas/GeoTrustMetadataDTO"}},"description":"GeoTrust Score - composite geographic trust score for KYC/AML compliance. Available for PRO and ENTERPRISE plans only."},"StreetValidationResult":{"type":"object","properties":{"match_type":{"type":"string","description":"Type of match: EXACT (numero+voie), STREET_ONLY (voie only), NUMERO_OUT_OF_RANGE, PARTIAL, FUZZY, NONE, NONE_BUT_COVERED, NO_INPUT","example":"EXACT","enum":["EXACT","STREET_ONLY","NUMERO_OUT_OF_RANGE","PARTIAL","FUZZY","NONE","NONE_BUT_COVERED","NO_INPUT"]},"match_score":{"type":"number","description":"Match confidence score (0.0 to 1.0). 1.0 = exact numero + voie match.","format":"double","example":1.0},"ban_street_name":{"type":"string","description":"Official street name from BAN (if matched)","example":"Rue de la Paix"},"ban_street_afnor":{"type":"string","description":"AFNOR-normalized street name from BAN (if matched)","example":"RUE DE LA PAIX"},"ban_commune":{"type":"string","description":"Commune name from BAN (if matched)","example":"Paris 2e Arrondissement"},"suggestions":{"type":"array","description":"Suggested street names if no exact match found","items":{"type":"string","description":"Suggested street names if no exact match found"}},"numero_verified":{"type":"boolean","description":"Whether the house number was verified against BAN address data","example":true},"input_numero":{"type":"string","description":"House number extracted from input (if any)","example":"12"},"ban_longitude":{"type":"number","description":"GPS longitude from BAN (if address matched)","format":"double","example":2.3308},"ban_latitude":{"type":"number","description":"GPS latitude from BAN (if address matched)","format":"double","example":48.8698}},"description":"Street validation result from BAN (Base Adresse Nationale). Shows match type, score, official street name, house number verification, and GPS coordinates."},"ValidatedAddressDTO":{"type":"object","properties":{"street":{"type":"string"},"postal_code":{"type":"string"},"city":{"type":"string"},"department_code":{"type":"string"},"department_name":{"type":"string"},"region":{"type":"string"},"country_code":{"type":"string"},"country_name":{"type":"string"},"insee_code":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"}}},"ValidationErrorDTO":{"type":"object","properties":{"code":{"type":"string"},"field":{"type":"string"},"message":{"type":"string"}}},"ValidationWarningDTO":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}},"AddressNormalizationRequest":{"required":["city","country_code","postal_code","street"],"type":"object","properties":{"recipient":{"maxLength":256,"minLength":0,"type":"string"},"additional":{"maxLength":256,"minLength":0,"type":"string"},"complement":{"maxLength":256,"minLength":0,"type":"string"},"street":{"maxLength":256,"minLength":0,"type":"string"},"locality":{"maxLength":256,"minLength":0,"type":"string"},"postal_code":{"maxLength":10,"minLength":0,"type":"string"},"city":{"maxLength":128,"minLength":0,"type":"string"},"country_code":{"pattern":"^[A-Za-z]{2}$","type":"string"}}},"AddressNormalizationResponse":{"type":"object","properties":{"normalization_status":{"type":"string"},"input":{"$ref":"#/components/schemas/AddressNormalizationRequest"},"normalized_address":{"$ref":"#/components/schemas/NormalizedAddressDTO"},"formatted_lines":{"type":"array","items":{"type":"string"}},"line_count":{"type":"integer","format":"int32"},"max_line_length":{"type":"integer","format":"int32"},"afnor_compliant":{"type":"boolean"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/ValidationWarningDTO"}},"timestamp":{"type":"string"}}},"NormalizedAddressDTO":{"type":"object","properties":{"line1":{"type":"string"},"line2":{"type":"string"},"line3":{"type":"string"},"line4":{"type":"string"},"line5":{"type":"string"},"line6":{"type":"string"}}},"RegionDTO":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"departments":{"type":"array","items":{"type":"string"}}}},"DepartmentDTO":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"region_code":{"type":"string"},"region_name":{"type":"string"}}},"PagedResponse":{"title":"PagedResponse","type":"object","properties":{"data":{"type":"array","description":"List of results","items":{"type":"object","description":"List of results"}},"pagination":{"$ref":"#/components/schemas/PaginationMetadata"},"timestamp":{"type":"string","description":"ISO 8601 timestamp when response was generated","format":"date-time"}},"description":"Paginated response with metadata"},"PaginationMetadata":{"title":"PaginationMetadata","type":"object","properties":{"page":{"type":"integer","description":"Current page number (0-indexed)","format":"int32","example":0},"size":{"type":"integer","description":"Number of items per page","format":"int32","example":25},"total_count":{"type":"integer","description":"Total number of results","format":"int64","example":150},"total_pages":{"type":"integer","description":"Total number of pages","format":"int32","example":6},"has_next":{"type":"boolean","description":"Whether there is a next page","example":true}},"description":"Pagination information"},"CityDTO":{"type":"object","properties":{"name":{"type":"string"},"municipalityCode":{"type":"string"},"parentMunicipalityCode":{"type":"string"},"postalCode":{"type":"string"},"districtCode":{"type":"string"},"departmentCode":{"type":"string"},"countryCode":{"type":"string"},"insee_code":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"population":{"type":"integer","format":"int32"},"density":{"type":"number","format":"double"},"zone_type":{"type":"string"}},"description":"List of results"},"PagedResponseCityDTO":{"title":"PagedResponse","type":"object","properties":{"data":{"type":"array","description":"List of results","items":{"$ref":"#/components/schemas/CityDTO"}},"pagination":{"$ref":"#/components/schemas/PaginationMetadata"},"timestamp":{"type":"string","description":"ISO 8601 timestamp when response was generated","format":"date-time"}},"description":"Paginated response with metadata"},"CountryDTO":{"type":"object","properties":{"name":{"type":"string"},"iso3Code":{"type":"string"},"iso2Code":{"type":"string"},"statusCode":{"type":"string"}}},"AddressSection":{"type":"object","properties":{"street_address":{"type":"string"},"address_complement":{"type":"string"},"postal_code":{"type":"string"},"city":{"type":"string"},"insee_code":{"type":"string"},"department_code":{"type":"string"},"country_code":{"type":"string"}}},"CompanyDTO":{"type":"object","properties":{"siren":{"type":"string"},"siret":{"type":"string"},"nic":{"type":"string"},"company_name":{"type":"string"},"trade_name":{"type":"string"},"legal_form":{"type":"string"},"naf_code":{"type":"string"},"naf_label":{"type":"string"},"employee_range":{"type":"string"},"is_headquarters":{"type":"boolean"},"address":{"$ref":"#/components/schemas/AddressSection"},"coordinates":{"$ref":"#/components/schemas/CoordinatesSection"},"is_active":{"type":"boolean"},"creation_date":{"type":"string","format":"date"},"closure_date":{"type":"string","format":"date"}}},"CompanySearchResponse":{"type":"object","properties":{"query":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/CompanyDTO"}},"total_results":{"type":"integer","format":"int64"},"page":{"type":"integer","format":"int32"},"page_size":{"type":"integer","format":"int32"},"has_next":{"type":"boolean"},"response_time_ms":{"type":"integer","format":"int64"},"source":{"type":"string"},"timestamp":{"type":"string"}}},"CoordinatesSection":{"type":"object","properties":{"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"}}},"CommuneSuccessorDTO":{"type":"object","properties":{"original":{"$ref":"#/components/schemas/OriginalCommune"},"successor":{"$ref":"#/components/schemas/SuccessorCommune"},"message":{"type":"string"},"timestamp":{"type":"string","format":"date-time"}}},"OriginalCommune":{"type":"object","properties":{"insee_code":{"type":"string"},"name":{"type":"string"}}},"SuccessorCommune":{"type":"object","properties":{"insee_code":{"type":"string"},"name":{"type":"string"},"department_code":{"type":"string"},"postal_code":{"type":"string"},"event_type":{"type":"string"},"event_date":{"type":"string","format":"date"}}},"CommuneEventDTO":{"type":"object","properties":{"event_type":{"type":"string"},"event_date":{"type":"string","format":"date"},"related_insee_code":{"type":"string"},"old_name":{"type":"string"},"new_name":{"type":"string"},"old_insee_code":{"type":"string"},"new_insee_code":{"type":"string"},"description":{"type":"string"},"source":{"type":"string"}}},"CommuneHistoryDTO":{"type":"object","properties":{"insee_code":{"type":"string"},"current_name":{"type":"string"},"department_code":{"type":"string"},"events":{"type":"array","items":{"$ref":"#/components/schemas/CommuneEventDTO"}},"event_count":{"type":"integer","format":"int32"},"timestamp":{"type":"string","format":"date-time"}}},"AdministrativeSection":{"type":"object","properties":{"phone_prefix":{"type":"string"},"epci_code":{"type":"string"},"epci_name":{"type":"string"},"canton_code":{"type":"string"}}},"CityEnrichmentDTO":{"type":"object","properties":{"insee_code":{"type":"string"},"city_name":{"type":"string"},"demographics":{"$ref":"#/components/schemas/DemographicsSection"},"geography":{"$ref":"#/components/schemas/GeographySection"},"administrative":{"$ref":"#/components/schemas/AdministrativeSection"},"economics":{"$ref":"#/components/schemas/EconomicsSection"},"metadata":{"$ref":"#/components/schemas/MetadataSection"},"timestamp":{"type":"string"}}},"DemographicsSection":{"type":"object","properties":{"population":{"type":"integer","format":"int32"},"population_year":{"type":"integer","format":"int32"},"density":{"type":"number"},"zone_type":{"type":"string"}}},"EconomicsSection":{"type":"object","properties":{"median_income":{"type":"integer","format":"int32"},"poverty_rate":{"type":"number"},"unemployment_rate":{"type":"number"}}},"GeographySection":{"type":"object","properties":{"area_km2":{"type":"number"},"altitude_min":{"type":"integer","format":"int32"},"altitude_max":{"type":"integer","format":"int32"},"timezone":{"type":"string"},"is_mountain_zone":{"type":"boolean"},"is_coastal":{"type":"boolean"},"is_overseas":{"type":"boolean"}}},"MetadataSection":{"type":"object","properties":{"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"data_quality_score":{"type":"number","format":"double"}}},"CitySnapshot":{"type":"object","properties":{"insee_code":{"type":"string"},"name":{"type":"string"},"population":{"type":"integer","format":"int32"}}},"CityStatisticsDTO":{"type":"object","properties":{"total_cities":{"type":"integer","format":"int64"},"enriched_cities":{"type":"integer","format":"int64"},"demographics":{"$ref":"#/components/schemas/DemographicsStatistics"},"zone_distribution":{"type":"object","additionalProperties":{"type":"integer","format":"int64"}},"mountain_zone_count":{"type":"integer","format":"int64"},"coastal_count":{"type":"integer","format":"int64"},"overseas_count":{"type":"integer","format":"int64"},"timestamp":{"type":"string"}}},"DemographicsStatistics":{"type":"object","properties":{"total_population":{"type":"integer","format":"int64"},"avg_density":{"type":"number","format":"double"},"most_populated":{"$ref":"#/components/schemas/CitySnapshot"},"least_populated":{"$ref":"#/components/schemas/CitySnapshot"}}},"AutocompleteResponse":{"type":"object","properties":{"query":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/AutocompleteSuggestion"}},"total_results":{"type":"integer","format":"int32"},"response_time_ms":{"type":"integer","format":"int64"},"source":{"type":"string"}}},"AutocompleteSuggestion":{"type":"object","properties":{"label":{"type":"string"},"display":{"type":"string"},"insee_code":{"type":"string"},"postal_code":{"type":"string"},"department_code":{"type":"string"},"country_code":{"type":"string"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"population":{"type":"integer","format":"int32"},"score":{"type":"number","format":"double"}}},"AddressSuggestDTO":{"type":"object","properties":{"street_name":{"type":"string","description":"Official street name from BAN","example":"Rue de la Paix"},"street_afnor":{"type":"string","description":"AFNOR-normalized street name","example":"RUE DE LA PAIX"},"postal_code":{"type":"string","description":"Postal code","example":"75002"},"city":{"type":"string","description":"Commune name","example":"Paris 2e Arrondissement"},"insee_code":{"type":"string","description":"INSEE code","example":"75102"},"sample_numero":{"type":"string","description":"A representative house number for this street","example":"12"},"longitude":{"type":"number","description":"Longitude (representative point)","format":"double","example":2.3308},"latitude":{"type":"number","description":"Latitude (representative point)","format":"double","example":48.8698}},"description":"Address suggestion from BAN (Base Adresse Nationale)"}},"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","description":"API key for authentication. Send your key in the X-Georefer-API-Key header.\n\n**Demo key for testing:** `demo-0000-0000-0000-000000000000` (50 req/day, limited features)\n\n**Get a free key:** Sign up at https://georefer.io/#signup\n\n**Plans:** FREE (100/day) | STARTER (5,000/day) | PRO (50,000/day) | ENTERPRISE (unlimited)","name":"X-Georefer-API-Key","in":"header"}}},"x-tagGroups":[{"name":"Getting Started","tags":["Developer Portal","API Info"]},{"name":"Geographic Data","tags":["Cities","Countries","Departments","Regions"]},{"name":"Address Services","tags":["Address Validation"]},{"name":"City Intelligence","tags":["Commune History","City Enrichment"]},{"name":"Enterprise Data","tags":["Companies"]},{"name":"Account & Billing","tags":["Usage","Billing"]}]}