Configuration Guide
Last updated: 2026-06-01
This guide covers every configuration option in config/addresses.php, what happens when each is disabled or misconfigured, and how to avoid common mistakes.
Table of Contents
- Quick Reference: Environment Variables
- Feature Toggle Reference
- Critical Interdependencies
- Common Misconfigurations
- Configuration by Use Case
- Troubleshooting
Quick Reference: Environment Variables
All package variables are optional except the API credentials you choose to activate. Variables are grouped below by functional area and mirror the sections in .env.example.
License (Runtime Validation)
Runtime license validation enforces activation limits at boot time via the Anystack API. Without a key configured, the package operates silently with no validation (suitable for local development).
| Variable | Default | Notes |
|---|---|---|
FILAMENT_ADDRESS_LICENSE_KEY | (none) | Customer license key — obtained from your Anystack license portal. Leave unset for local dev. |
ANYSTACK_PRODUCT_ID | (none) | Vendor product ID — set in your .env server-side only, never expose to customers |
ANYSTACK_API_TOKEN | (none) | Vendor bearer token — server-side only, never expose to customers |
FILAMENT_ADDRESS_LICENSE_CACHE_TTL | 86400 | Seconds between re-validation calls to Anystack API (default: 24h) |
Behavior:
- No key configured → silent skip. Supports local development without a license key.
- First boot with key → activates against Anystack, stores activation record in the Laravel Cache.
- Subsequent boots within TTL → no API call (reads cached activation record).
- Anystack unreachable → logs a warning, allows boot — never blocks production over a licensing API outage.
- Expired maintenance → logs a warning only. Version gating is handled by Anystack Satis, not this setting.
Artisan command:
php artisan addresses:license:deactivateRun this on the old server before moving a Solo license to a new domain. It calls the Anystack deactivation API and removes the local activation file so you can activate on the new domain.
Maps & Geocoding
Google Maps API keys power the address search field, map preview, blur geocoding, and Google-based verification. Two separate keys are recommended for production so each can carry different API and IP restrictions. A single GOOGLE_MAPS_API_KEY works as a fallback for simpler setups.
| Variable | Default | Notes |
|---|---|---|
GOOGLE_MAPS_SERVER_KEY | (none) | Server-side: geocoding, static maps, Address Validation — restrict to server IP |
GOOGLE_MAPS_BROWSER_KEY | (none) | Browser-side: Maps JavaScript API + Places API — restrict to your domain |
GOOGLE_MAPS_API_KEY | (none) | Single-key fallback — both above default to this when not set |
ADDRESS_INPUT_MODE | auto | auto / autocomplete / geocoding / manual |
ADDRESS_REVERSE_GEOCODING_ENABLED | true | Populate address fields when a map pin is dropped |
ADDRESS_BLUR_GEOCODING_ENABLED | true | Auto-fill address components when user tabs out of address_line_1 |
ADDRESS_BLUR_MIN_LENGTH | 10 | Min characters before blur geocoding triggers |
ADDRESS_BLUR_SKIP_IF_VERIFIED | true | Skip blur geocoding if address already has verified coordinates |
ADDRESS_BLUR_DEBOUNCE_MS | 0 | Blur debounce delay (ms) |
ADDRESS_BLUR_DETECT_PASTE | true | Detect pasted full addresses and geocode immediately |
ADDRESS_BLUR_REQUIRE_COMPLETENESS | any | Required completeness before blur: any / basic / complete |
ADDRESS_BLUR_SMART_DETECTION | basic | Detection sophistication: basic / smart / aggressive |
Verification
Address verification confirms deliverability and standardizes addresses to postal authority format. USPS is free for US addresses; configure Smarty or Google for international coverage. All providers are independently enabled/disabled so credentials can remain configured while a provider is temporarily switched off.
General
| Variable | Default | Notes |
|---|---|---|
ADDRESS_VERIFICATION_ENABLED | true | Enable/disable all address verification |
ADDRESS_VERIFICATION_PROVIDER | auto | auto / usps / google / smarty / loqate / none |
ADDRESS_VERIFICATION_MODE | interactive | interactive (comparison dialog) / silent (auto-applies on save) |
ADDRESS_VERIFICATION_CACHE_TTL | 86400 | Verification result cache TTL (seconds) |
USPS
| Variable | Default | Notes |
|---|---|---|
ADDRESS_VERIFICATION_USPS_ENABLED | true | Enable USPS provider (credentials can remain set while disabled) |
USPS_CONSUMER_KEY | (none) | OAuth key — register at developer.usps.com |
USPS_CONSUMER_SECRET | (none) | OAuth secret |
USPS_BASE_URL | https://apis.usps.com | Use https://apis-tem.usps.com for the testing environment |
USPS_RATE_LIMIT_ENABLED | true | Enable rate limiting (USPS enforces 60 calls/hour by default) |
USPS_RATE_LIMIT | 60 | Calls per hour — upgrade via usps.com web tools inquiry |
USPS_LIMIT_BEHAVIOR | queue | When rate limit hit: queue / fail / fallback (to Google) |
Smarty
| Variable | Default | Notes |
|---|---|---|
ADDRESS_VERIFICATION_SMARTY_US_ENABLED | true | Enable Smarty for US addresses |
ADDRESS_VERIFICATION_SMARTY_INTERNATIONAL_ENABLED | true | Enable Smarty for international addresses |
SMARTY_AUTH_ID | (none) | Smarty authentication ID |
SMARTY_AUTH_TOKEN | (none) | Smarty authentication token |
SMARTY_LICENSE | us-core-cloud | US Street API license — must match your Smarty account dashboard exactly |
SMARTY_LICENSE_INTL | international-cloud | International Street API license |
SMARTY_INTL_GEOCODE | false | Request geocoordinates from International API (requires Smarty add-on) |
SMARTY_MONTHLY_LIMIT_US | (none) | US monthly quota — set to show the quota bar in the Usage Widget |
SMARTY_MONTHLY_LIMIT_INTL | (none) | International monthly quota |
SMARTY_US_ENDPOINT | https://us-street.api.smarty.com/street-address | US Street API endpoint |
SMARTY_INTL_ENDPOINT | https://international-street.api.smarty.com/verify | International Street API endpoint |
Loqate
| Variable | Default | Notes |
|---|---|---|
LOQATE_API_KEY | (none) | API key — get from loqate.com |
LOQATE_ENDPOINT | https://api.addressy.com/Capture/Interactive | Loqate API endpoint |
Google Address Validation
| Variable | Default | Notes |
|---|---|---|
ADDRESS_VERIFICATION_GOOGLE_ENABLED | true | Enable Google Address Validation provider |
ADDRESS_VERIFICATION_GOOGLE_ENDPOINT | https://addressvalidation.googleapis.com/v1:validateAddress | Google Address Validation API endpoint |
Webhooks
| Variable | Default | Notes |
|---|---|---|
ADDRESS_VERIFICATION_WEBHOOKS_ENABLED | false | Emit webhooks on verification events |
ADDRESS_VERIFICATION_WEBHOOK_URL | (none) | Destination URL for webhook payloads |
ADDRESS_VERIFICATION_WEBHOOK_SECRET | (none) | HMAC signing secret |
Caching & Cost Tracking
Caching dramatically reduces API costs by reusing results for the same address. Never disable geocoding cache in production — at $0.005/request, a site processing 1,000 addresses/day spends ~$0.10/day with cache vs. ~$5/day without. Audit logging records every API call for cost analysis and compliance reporting.
Geocoding Cache
| Variable | Default | Notes |
|---|---|---|
ADDRESS_GEOCODING_CACHE_ENABLED | true | Cache geocoding and verification results — keep enabled in production |
ADDRESS_GEOCODING_CACHE_TTL_GEOCODE | 2592000 | Forward geocoding cache TTL (30 days) |
ADDRESS_GEOCODING_CACHE_TTL_REVERSE | 604800 | Reverse geocoding cache TTL (7 days) |
ADDRESS_GEOCODING_CACHE_TTL_VERIFY | 2592000 | Verification result cache TTL (30 days) |
Audit Logging
| Variable | Default | Notes |
|---|---|---|
ADDRESS_GEOCODING_AUDIT_ENABLED | true | Log all API calls — required for the Addressing Dashboard |
ADDRESS_GEOCODING_AUDIT_TRACK_USER | true | Include user_id and session_id in audit log |
ADDRESS_GEOCODING_AUDIT_TRACK_IP | false | Include IP address in audit log (disable for GDPR compliance) |
API Cost Tracking
Override these if you have negotiated rates different from the published defaults.
| Variable | Default | Notes |
|---|---|---|
ADDRESS_API_COST_GOOGLE | 0.005 | Google geocoding cost per request (USD) |
ADDRESS_API_COST_GOOGLE_VERIFICATION | 0.005 | Google Address Validation cost per request |
ADDRESS_API_COST_USPS | 0.000 | USPS cost per request (free) |
ADDRESS_API_COST_SMARTY | 0.006 | Smarty cost per lookup |
ADDRESS_API_COST_LOQATE | 0.150 | Loqate cost per verification |
ADDRESS_API_COST_AUTOCOMPLETE | 0.017 | Google Places Autocomplete cost per session |
ADDRESS_API_COST_STATIC_MAP | 0.002 | Google Static Maps cost per image |
Static Map Cache
| Variable | Default | Notes |
|---|---|---|
ADDRESS_STATIC_MAP_CACHE_ENABLED | true | Cache static map images on disk (storage/app/map-cache/) |
ADDRESS_STATIC_MAP_CACHE_TTL | 7776000 | Static map cache TTL (90 days) |
ADDRESS_STATIC_MAP_ZOOM | 15 | Map zoom level (0–21; 15 = neighborhood/street names visible) |
ADDRESS_STATIC_MAP_SIZE | 800x400 | Map image dimensions (WxH) |
ADDRESS_STATIC_MAP_SCALE | 2 | Image scale: 1 = standard, 2 = retina |
ADDRESS_STATIC_MAP_MAX_DIMENSION | 1280 | Max image dimension in pixels |
ADDRESS_STATIC_MAP_RATE_LIMIT | 60,1 | Throttle: requests per minute |
Subdivision Cache
| Variable | Default | Notes |
|---|---|---|
ADDRESS_SUBDIVISION_CACHE_ENABLED | true | Cache subdivision dropdown queries (states, cities, districts) |
ADDRESS_SUBDIVISION_CACHE_TTL | 86400 | Subdivision cache TTL (seconds) |
ADDRESS_CACHE_PREFIX | addresses | Cache key prefix (useful when sharing a cache with multiple apps) |
UI & Form
Configure which Filament panel the package registers resources to, which form components to display, and UI display preferences. ADDRESS_PANEL_ID and ADDRESS_PANEL_PATH must match your PanelProvider configuration.
| Variable | Default | Notes |
|---|---|---|
ADDRESS_PANEL_ID | app | Filament panel ID for resource registration |
ADDRESS_PANEL_PATH | app | Filament panel URL path |
ADDRESS_PANEL_BRAND | Addressing | Panel sidebar header title |
ADDRESS_FORM_MAP | true | Show map preview + Places autocomplete search (in autocomplete mode) |
ADDRESS_FORM_PREVIEW | true | Show live formatted address preview |
ADDRESS_SHOW_LOCAL_NAMES | true | Show local-language names in dropdowns (e.g. "Beijing (北京市)") |
ADDRESS_TABLE_NAME | addresses | Table name — change only if it conflicts with an existing table |
ADDRESS_RESOURCE_ENABLED | false | Auto-register standalone AddressResource (not yet active) |
ADDRESS_PREVIEW_INTERNATIONAL_LABEL | INTERNATIONAL | Preview section header label |
ADDRESS_PREVIEW_DOMESTIC_LABEL | DOMESTIC | Preview section header label |
ADDRESS_PREVIEW_EMPTY_MESSAGE | Fill in address fields to see preview | Preview placeholder (no input yet) |
ADDRESS_PREVIEW_NO_COUNTRY_MESSAGE | Select a country to see address preview | Preview placeholder (no country selected) |
ADDRESS_PREVIEW_PLACEHOLDER_FIRST_NAME | First Name | Placeholder name shown in preview |
ADDRESS_PREVIEW_PLACEHOLDER_LAST_NAME | Last Name | Placeholder name shown in preview |
ADDRESS_PREVIEW_PLACEHOLDER_ORGANIZATION | Organization Name | Placeholder organization shown in preview |
ADDRESS_PREVIEW_PLACEHOLDER_COLOR | #9ca3af | Placeholder text color (CSS value) |
Quality Scoring
Every address receives a score from 0–100 based on completeness, verification status, data quality, and recency. Weights determine how many points each attribute contributes and should sum to 100. Thresholds map scores to labels (Excellent, Good, Fair, Poor, Very Poor).
Weights
| Variable | Default | Notes |
|---|---|---|
ADDRESS_QUALITY_WEIGHT_REQUIRED_FIELDS | 15 | Completeness: required fields present |
ADDRESS_QUALITY_WEIGHT_OPTIONAL_FIELDS | 10 | Completeness: optional fields (city, state, line 2) |
ADDRESS_QUALITY_WEIGHT_COORDINATES | 5 | Completeness: lat/lon captured |
ADDRESS_QUALITY_WEIGHT_STRUCTURED | 5 | Completeness: subdivision IDs stored (not just text) |
ADDRESS_QUALITY_WEIGHT_VERIFIED_CONFIRMED | 40 | Verification: full delivery point confirmed (USPS/Smarty DPV=Y) |
ADDRESS_QUALITY_WEIGHT_VERIFIED_WARNINGS | 25 | Verification: verified with delivery point caveats (DPV=D/S) |
ADDRESS_QUALITY_WEIGHT_VERIFIED_REVIEW | 15 | Verification: verified but flagged for review |
ADDRESS_QUALITY_WEIGHT_VERIFIED_BASIC | 20 | Verification: verified, no granular delivery point data (Google, Loqate) |
ADDRESS_QUALITY_WEIGHT_NO_DUPLICATE | 10 | Data quality: no duplicate detected |
ADDRESS_QUALITY_WEIGHT_ADDITIONAL_FIELDS | 5 | Data quality: bldg/box/ico populated |
ADDRESS_QUALITY_WEIGHT_RECENT_30 | 10 | Recency: verified within 30 days |
ADDRESS_QUALITY_WEIGHT_RECENT_90 | 5 | Recency: verified within 90 days |
Thresholds
| Variable | Default | Notes |
|---|---|---|
ADDRESS_QUALITY_THRESHOLD_EXCELLENT | 80 | Minimum score for "Excellent" |
ADDRESS_QUALITY_THRESHOLD_GOOD | 60 | Minimum score for "Good" |
ADDRESS_QUALITY_THRESHOLD_FAIR | 40 | Minimum score for "Fair" |
ADDRESS_QUALITY_THRESHOLD_POOR | 20 | Minimum score for "Poor" (below = "Very Poor") |
Authorization
Disabled by default for backward compatibility. Enable for any production application with multiple users. When enabled, the AddressPolicy class controls access using the boolean defaults below; closures in config/addresses.php allow row-level permissions and Spatie Permission integration.
| Variable | Default | Notes |
|---|---|---|
ADDRESS_AUTHORIZATION_ENABLED | false | Enable authorization checks — required for multi-user production apps |
ADDRESS_AUTH_VIEW_ANY | true | Default: can user view the address list |
ADDRESS_AUTH_CREATE | true | Default: can user create addresses |
ADDRESS_AUTH_UPDATE | true | Default: can user update addresses |
ADDRESS_AUTH_DELETE | true | Default: can user delete addresses |
ADDRESS_AUTH_BULK_VERIFY | true | Default: can user trigger bulk verification |
ADDRESS_AUTH_IMPORT | true | Default: can user import from CSV/Excel |
ADDRESS_AUTH_EXPORT | true | Default: can user export to CSV/Excel |
Import & Misc
| Variable | Default | Notes |
|---|---|---|
ADDRESS_IMPORT_VERIFY_DEFAULT | false | Verify addresses during import by default (users can override in form) |
ADDRESS_IMPORT_GEOCODE_DEFAULT | false | Geocode addresses during import by default |
ADDRESS_DUPLICATE_DETECTION_ENABLED | true | Warn when entering a duplicate address for the same entity |
Feature Toggle Reference
Google Maps API Keys - Core requirement
Most features depend on a Google Maps API key. The package supports two separate keys for improved security, with a single-key fallback for simpler setups.
Two-key setup (recommended for production)
| Variable | Restriction type | APIs to enable |
|---|---|---|
GOOGLE_MAPS_SERVER_KEY | IP address (your server) | Geocoding API, Maps Static API, Address Validation API |
GOOGLE_MAPS_BROWSER_KEY | HTTP referrer (your domain) | Maps JavaScript API, Places API |
This ensures the server key (used for geocoding and static maps) is never exposed in the browser, and the browser key is locked to your domain so it cannot be used from other sites.
Single-key fallback
Set only GOOGLE_MAPS_API_KEY - both GOOGLE_MAPS_SERVER_KEY and GOOGLE_MAPS_BROWSER_KEY fall back to it automatically. Suitable for development or low-traffic apps where separate key restrictions are impractical.
Behavior when keys are missing
| Feature | Behavior |
|---|---|
| Address search field / map preview | JavaScript error in the browser; map does not load |
| Blur geocoding | HTTP 403 from Google; address fields do not auto-fill |
| Google verification | HTTP 403; falls back to geocoding, then fails too |
| Live preview | Still works, computed locally from form data |
| USPS verification | Still works, USPS does not use Google keys |
| Subdivision dropdowns | Still works, data is from the local database |
ADDRESS_FORM_MAP — Map preview
When false: The AddressSearchField component is hidden entirely. This component contains the static map image and, when in autocomplete mode, the Places autocomplete search box. In geocoding mode the map is still shown (no Places search box is rendered), so setting this to false in geocoding mode removes the static map preview but blur geocoding on address_line_1 continues to work. Coordinates are not collected unless blur geocoding or manual entry is used.
When true but browser key is missing in autocomplete mode: The map renders but the Places autocomplete element fails to load with a JavaScript error. The form remains usable via manual input or blur geocoding.
Dependency: In autocomplete mode, requires GOOGLE_MAPS_BROWSER_KEY (or GOOGLE_MAPS_API_KEY fallback) with Maps JavaScript API + Places API enabled. In geocoding mode, requires GOOGLE_MAPS_SERVER_KEY for the static map proxy.
ADDRESS_FORM_PREVIEW — Live address preview
When false: The formatted address preview panel is hidden. No impact on data or API calls.
This is a display-only feature with no external dependencies. Safe to disable for a simpler UI.
ADDRESS_BLUR_GEOCODING_ENABLED — Blur-to-geocode auto-fill
When false: Users cannot paste a full address and have it automatically split into components. They must fill each field (city, state, postal code) by hand or use the map.
When true but server key is missing: Geocoding requests fail silently; the address fields remain as entered.
Dependency: Requires GOOGLE_MAPS_SERVER_KEY (or GOOGLE_MAPS_API_KEY fallback) with the Geocoding API enabled.
The min_length, debounce_ms, detect_paste, require_completeness, and smart_detection_level sub-options only matter when blur geocoding is enabled.
ADDRESS_INPUT_MODE — Choosing an input mode
Controls how addresses are entered in the form. This is the single most impactful configuration choice; it determines whether the Places autocomplete or blur geocoding is active. They are mutually exclusive.
| Value | Requires | Behavior |
|---|---|---|
auto (default) | — | Browser key present → autocomplete; server key only → geocoding; neither → manual |
autocomplete | GOOGLE_MAPS_BROWSER_KEY | Places autocomplete search; blur geocoding disabled |
geocoding | GOOGLE_MAPS_SERVER_KEY | Server-side geocoding on Address Line 1 blur; no autocomplete |
manual | — | No API calls; user fills all fields by hand |
ADDRESS_INPUT_MODE=auto # Recommended, detects from configured keysWhen auto and both keys are set: browser key wins → autocomplete mode. If you set auto and only have a server key, you get geocoding mode, not autocomplete.
When set to autocomplete but browser key is missing: the address search field renders but the Places autocomplete fails to load. Set to geocoding or manual as a fallback.
Which mode should I choose?
| Use case | Recommended mode | Why |
|---|---|---|
| Customer-facing form (checkout, registration) | autocomplete | Best UX, type-ahead reduces errors and speeds entry |
| Staff admin panel with server key only | geocoding | No browser-exposed key; paste-and-tab workflow |
| Strict CSP environment | geocoding | Avoids loading third-party scripts in the browser |
| Internal tool / offline / pre-verified data | manual | No API costs; data comes from another system |
| Not sure yet | auto | Adapts to whichever keys you configure |
Input mode vs. verification mode
Input mode and verification mode (ADDRESS_VERIFICATION_MODE) are independent:
- Input mode controls how the form is filled (autocomplete, geocoding, or manual)
- Verification mode controls what happens after save (
interactivedialog orsilentauto-verify)
Any combination works. For example: autocomplete + silent for a public checkout form, geocoding + interactive for a staff admin panel, or manual + silent for imported data.
Input mode vs. map preview
ADDRESS_FORM_MAP (enable/disable the static map image) is independent of input mode. The map preview requires GOOGLE_MAPS_SERVER_KEY for the proxy route regardless of input mode. A developer who disables the map to avoid exposing a browser key can still use geocoding mode with a server key only.
ADDRESS_GEOCODING_CACHE_ENABLED — Geocoding cache
⚠️ Cost warning: Disable this only for debugging. Never disable in production.
When false: Every geocoding operation (blur auto-fill, map selection, bulk verification) hits the Google API directly. This bypasses all caching and audit logging.
Cost impact example:
- A site with 1,000 address saves per day
- With cache: ~$0.10/day (cache hit rate ~98%)
- Without cache: ~$5/day ($0.005 × 1,000)
- Annual difference: ~$1,800/year
Set the TTL values instead of disabling the cache entirely if you need fresher results.
ADDRESS_GEOCODING_AUDIT_ENABLED — API call audit logging
When false: No API calls are logged. The cache still functions, but you lose:
- Cost tracking and analytics
- The admin Addressing Dashboard resource
- Audit trail for compliance
When true and ADDRESS_GEOCODING_AUDIT_TRACK_IP = false: User IDs and session IDs are recorded but IP addresses are not. This is the recommended setting for GDPR compliance.
ADDRESS_VERIFICATION_MODE — Verification UX mode
Controls how verification interacts with the user.
| Value | Behavior |
|---|---|
interactive (default) | Verify button visible; standardization dialog shown when differences found |
silent | Verification runs automatically on every Address save via observer; button and dialog suppressed |
ADDRESS_VERIFICATION_MODE=interactive # Default for staff workflows
ADDRESS_VERIFICATION_MODE=silent # Public forms (checkout, registration)Silent mode is designed for public-facing forms where showing a standardization dialog would confuse users. On success, the address is silently standardized (is_verified = true). On failure, needs_review = true is set for staff review in the admin panel.
See Public Forms Guide for the full silent mode setup.
ADDRESS_VERIFICATION_ENABLED — Address verification
When false: Addresses are saved exactly as entered, without contacting any verification API. The provider and providers settings are ignored. Addresses will have is_verified = false.
When true but no provider is configured: Verification falls back to geocoding (if enabled). Addresses receive geocoded coordinates but no standardization from a verification API.
ADDRESS_VERIFICATION_PROVIDER — Verification provider
Valid values: auto, usps, google, smarty, loqate, none
Note: Loqate is not yet implemented, but config keys exist as placeholders. Setting
loqatewill fall back to geocoding with a warning.
| Value | Behavior |
|---|---|
auto | Smart routing: USPS for US (via country_providers); Smarty-first for 155 countries with DeliveryPoint precision; Google-first for all others |
usps | Forces USPS for all addresses, non-US addresses will fail and fall back to geocoding |
google | Uses Google Address Validation API (~40 countries) |
smarty | Uses Smarty US Street API (US) or International Street API (240+ countries) |
none | Disables verification (same as ADDRESS_VERIFICATION_ENABLED=false) |
Any unrecognized value (e.g. a typo like ussp) will fall back to geocoding and log a warning. Check your Laravel logs if verification is silently not working.
ADDRESS_SUBDIVISION_CACHE_ENABLED — Subdivision dropdown cache
When false: Every country/state/city dropdown renders by querying the database on each page load. This creates significant database load at scale.
Subdivision data (states, provinces, cities) is reference data that virtually never changes. Disabling this cache provides no meaningful benefit and degrades performance noticeably.
ADDRESS_DUPLICATE_DETECTION_ENABLED — Duplicate address warnings
When false: No duplicate checking occurs. Users can save the same address multiple times for the same entity without any warning. The warning is advisory-only even when enabled.
ADDRESS_REVERSE_GEOCODING_ENABLED — Populate from map coordinates
When false: Selecting a location from the map search does not populate address fields. The map still updates to show the selected location, but the form fields must be filled manually.
ADDRESS_STATIC_MAP_CACHE_ENABLED — Static map disk cache
The map preview displays location using Google's Static Maps API (a plain PNG image) served through a package proxy route at /filament-address/map-image. When caching is enabled, fetched images are stored in storage/app/map-cache/ and reused for the configured TTL.
When true (default): Google Static Maps is called once per unique location; subsequent views serve from disk at zero API cost. The cache key rounds coordinates to 4 decimal places (~11 meters) so addresses at the same building share one image.
When false: Every map view fetches a fresh image from Google ($0.002 each). No disk files are written. Useful for debugging but not recommended in production.
TTL (ADDRESS_STATIC_MAP_CACHE_TTL): Defaults to 90 days (7,776,000 seconds). Google map tiles update infrequently; a slightly stale tile is harmless for address confirmation. Reduce if you need fresher road data in a fast-changing area.
Zoom (ADDRESS_STATIC_MAP_ZOOM): Defaults to 15 (neighborhood level, street names visible). Increase to 17–18 for building-level detail; decrease to 10–12 for city overview.
Scale (ADDRESS_STATIC_MAP_SCALE): 1 = standard resolution (40–50 KB); 2 = retina (80–100 KB, sharper on HiDPI displays). Default is 2.
Cache management:
php artisan addresses:map-cache:stats # Count, size, oldest/newest entry
php artisan addresses:map-cache:cleanup # Delete entries older than TTL
php artisan addresses:map-cache:clear # Delete all (with confirmation)Cost comparison:
| Event | Dynamic Maps (old) | Static Maps (new) |
|---|---|---|
| Page load, no coordinates | $0.007 | ~$0.000 (default location, cached) |
| Page load, has coordinates | $0.007 | $0.002 first time; $0.000 cached |
| Same address, second view | $0.007 | $0.000 |
ADDRESS_AUTHORIZATION_ENABLED — Authorization checks
⚠️ Security warning: This defaults to
falsefor backward compatibility.
When false: All authenticated users have full access to all addresses; view, create, update, delete, bulk verify, import, and export. This is a security risk in multi-user applications.
When true: Access is controlled by the AddressPolicy. The default policy uses the view_any, create, update, etc. settings in the config, with optional Spatie Permission integration.
Required for production multi-user applications. See docs/AUTHORIZATION.md for the full guide and docs/SPATIE-PERMISSION.md for role-based permission setup.
Quality Score Weights and Thresholds
Every address is assigned a quality score (0–100) calculated from four categories. Both the point values and the labels are fully configurable.
Weights must sum to 100 for scores to stay on the 0–100 scale. Scores below poor are labeled "Very Poor". Thresholds affect badge colors in the address table, the "below threshold" scope in the Recalculate Quality action, the scopeNeedsQualityImprovement() model scope, and the stats widget description. See the Quality Scoring Quick Reference above for default values.
Example: de-emphasize verification for a manual-entry-only app:
ADDRESS_QUALITY_WEIGHT_VERIFIED_CONFIRMED=20
ADDRESS_QUALITY_WEIGHT_VERIFIED_BASIC=10
ADDRESS_QUALITY_WEIGHT_REQUIRED_FIELDS=30
ADDRESS_QUALITY_WEIGHT_OPTIONAL_FIELDS=20
ADDRESS_QUALITY_WEIGHT_COORDINATES=10
ADDRESS_QUALITY_WEIGHT_STRUCTURED=5
ADDRESS_QUALITY_WEIGHT_NO_DUPLICATE=5Or publish the config and edit config/addresses.php → quality_score.weights directly for more readable multi-line values.
Critical Interdependencies
Understanding how configuration options interact prevents unexpected behavior.
Address Search Field + Blur Geocoding
The Places autocomplete and blur geocoding are mutually exclusive - set via ADDRESS_INPUT_MODE. enable_map only controls whether the static map preview is displayed; it is independent of the input mode.
ADDRESS_INPUT_MODE | enable_map | Result |
|---|---|---|
autocomplete | true | Full experience: Places searchbox + static map (recommended) |
autocomplete | false | Places searchbox only; no map |
geocoding | true | Blur geocoding + static map |
geocoding | false | Blur geocoding only; no map (lower cost, simpler UI) |
manual | true | Static map image shown alongside manual field entry |
manual | false | Manual entry only; no geocoding at all |
blur_geocoding.enabled has no effect in autocomplete mode; it only applies when ADDRESS_INPUT_MODE is geocoding (or auto resolving to geocoding).
Note:
autocompleterequiresGOOGLE_MAPS_BROWSER_KEY;geocodingand map display requireGOOGLE_MAPS_SERVER_KEY.GOOGLE_MAPS_API_KEYserves as a single-key fallback for both.
Verification + Geocoding Fallback
When verification is enabled but fails (API error, rate limit, unsupported country), the behavior depends on verification.fallback_to_geocoding:
true(default): Falls back to standard geocoding + component extractionfalse: Returns a verification failure; address is saved withis_verified = false
This creates a dependency chain:
verification attempt → [fails] → geocoding fallback → [fails] → save unverifiedIf you disable geocoding cache (ADDRESS_GEOCODING_CACHE_ENABLED=false), fallback geocoding hits Google directly, potentially doubling your API costs during high-failure periods.
USPS Rate Limiting + Fallback
When USPS rate limit is reached, behavior is controlled by USPS_LIMIT_BEHAVIOR:
| Behavior | What happens | Cost |
|---|---|---|
queue | Request is queued for later processing | Delayed cost |
fail | Returns error; user sees failure message | No cost |
fallback | Uses Google geocoding immediately | Google cost |
If behavior = fallback and ADDRESS_GEOCODING_CACHE_ENABLED = false, every rate-limited USPS request immediately becomes a paid Google geocoding call.
Cache + Audit Log
The geocoding cache and audit log are separate systems:
- Cache: Stores results for reuse. If disabled, every request hits the API.
- Audit: Logs all API calls for cost tracking. If disabled, the Addressing Dashboard shows no data.
You can have cache enabled without audit (saves costs, no visibility) or audit without cache (full visibility, high costs). Enabling both is recommended for production.
Authorization + Spatie Permission
When ADDRESS_AUTHORIZATION_ENABLED = true, the package automatically detects whether spatie/laravel-permission is installed:
- Without Spatie: Uses the config-based boolean/closure permissions
- With Spatie: First checks Spatie permissions (
view-addresses,create-addresses, etc.), falls back to config-based permissions if no Spatie role/permission matches
No extra configuration is needed to enable Spatie integration, it is auto-detected.
Common Misconfigurations
1. Missing or wrong Google API key
Symptom: Map does not load; blur geocoding silently fails, and Google verification returns HTTP 403.
Check:
php artisan tinker --execute="dump(config('addresses.google_maps_server_key'), config('addresses.google_maps_browser_key'));"Fix: Ensure at least GOOGLE_MAPS_API_KEY is set in .env (single-key fallback), or set GOOGLE_MAPS_SERVER_KEY and GOOGLE_MAPS_BROWSER_KEY separately. Verify the key has the correct APIs enabled in Google Cloud Console: the server key needs Geocoding API + Maps Static API, and the browser key needs Maps JavaScript API + Places API.
2. Provider name typo (silent fallback)
Symptom: Verification appears to do nothing; addresses are saved without is_verified = true. Logs show: "Unknown verification provider configured, falling back to geocoding".
Example misconfiguration:
# Typo - 'ussp' is not a valid provider
ADDRESS_VERIFICATION_PROVIDER=usspFix: Use one of the valid values: auto, usps, google, smarty, none. Check your Laravel logs (storage/logs/laravel.log) for the warning message with valid value hints.
3. Setting provider = usps for a non-US application
Symptom: International addresses are not verified; logs show "Requested provider not available for this country or not configured".
Why: USPS only supports US addresses. Setting provider = usps globally means all non-US addresses fall through to geocoding.
Fix: Use provider = auto (default). Smart routing handles each country automatically:
- US → USPS (via
country_providerspin) - 155 countries with Smarty DeliveryPoint precision (CA, AU, GB, FR, DE, BR, etc.) → Smarty first
- All others (JP, CN, etc.) → Google first
// config/addresses.php
'country_providers' => [
'US' => 'usps',
// Other countries routed automatically via smart routing
],4. Smarty verification fails
Symptom: Verification falls back to geocoding; log shows an auth or subscription error.
Why: Either the credentials are missing/incorrect, or the license string doesn't match your active Smarty subscription tier.
Fix: Double-check SMARTY_AUTH_ID, SMARTY_AUTH_TOKEN, SMARTY_LICENSE, and SMARTY_LICENSE_INTL in your .env. The license string must exactly match what's shown in your Smarty account dashboard (e.g. us-core-cloud, international-cloud).
5. Disabling geocoding cache in production
Symptom: Google API costs spike dramatically; billing alerts trigger.
Why: Every geocoding operation (blur auto-fill, map selection, bulk verification, import) calls the Google API directly without caching.
Fix:
ADDRESS_GEOCODING_CACHE_ENABLED=true # Default, leave this alone in productionIf you suspect the cache contains stale data, use the Artisan commands instead of disabling it:
php artisan addresses:cache:cleanup # Remove expired geocoding cache entries
php artisan addresses:cache:cleanup --all # Clear all geocoding cache (prompts for confirmation)
php artisan addresses:map-cache:cleanup # Remove expired static map images
php artisan addresses:map-cache:clear # Clear all static map images (prompts for confirmation)6. Authorization disabled in multi-user production app
Symptom: Users can view, edit, and delete addresses belonging to other users or entities.
Why: ADDRESS_AUTHORIZATION_ENABLED defaults to false for backward compatibility.
Fix:
ADDRESS_AUTHORIZATION_ENABLED=trueThen review the permission defaults in config/addresses.php and tighten them for your use case. See docs/AUTHORIZATION.md for a complete guide including Spatie Permission integration.
7. Bulk verification without cost controls
Symptom: A single bulk verification run generates an unexpectedly large Google API bill.
Why: Bulk verification geocodes every address in the selected batch. Without authorization controls, any user can trigger bulk operations on all addresses.
Fix: Restrict bulk operations to admin roles:
// config/addresses.php
'authorization' => [
'enabled' => true,
'bulk_verify' => fn($user) => $user->hasRole('admin'),
'import' => fn($user) => $user->hasRole('admin'),
'export' => fn($user) => $user->hasAnyRole(['admin', 'analyst']),
],8. Blur geocoding triggers too aggressively
Symptom: API calls fire on partial input (e.g., a single word); costs are higher than expected.
Fix: Increase the minimum length and use smarter detection:
ADDRESS_BLUR_MIN_LENGTH=15
ADDRESS_BLUR_SMART_DETECTION=smart
ADDRESS_BLUR_REQUIRE_COMPLETENESS=basicsmart detection mode scores the address for completeness (has street number, has city, has postal) and only geocodes when the score reaches 60%. This catches garbage like "apt" or "123" while still supporting paste workflows.
9. Subdivision cache disabled causing slow dropdowns
Symptom: Country/state/city dropdowns are noticeably slow to load, especially for countries with many subdivisions (US states, Indian states, etc.).
Fix:
ADDRESS_SUBDIVISION_CACHE_ENABLED=true # Default, do not disableSubdivision data is static reference data that never changes between requests. There is no benefit to disabling this cache.
10. USPS credentials not configured (USPS provider silently skipped)
Symptom: US addresses fall through to Google even though provider = usps (or auto).
Why: USPS requires USPS_CONSUMER_KEY and USPS_CONSUMER_SECRET. If these are not set, the USPS provider is registered but isConfigured() returns false, causing it to be skipped.
Check:
php artisan tinker --execute="
\$usps = new \Viewflex\FilamentAddress\Services\Verification\Providers\UspsProvider(config('addresses.verification.providers.usps'));
dump(\$usps->isConfigured());
"Fix: Set both USPS credentials in .env:
USPS_CONSUMER_KEY=your_key_here
USPS_CONSUMER_SECRET=your_secret_hereRegister at developer.usps.com.
Configuration by Use Case
Minimal / No External APIs
For applications that cannot use Google Maps (privacy constraints, budget, intranet):
ADDRESS_FORM_MAP=false
ADDRESS_BLUR_GEOCODING_ENABLED=false
ADDRESS_VERIFICATION_ENABLED=false
ADDRESS_GEOCODING_CACHE_ENABLED=false
ADDRESS_GEOCODING_AUDIT_ENABLED=false
ADDRESS_SUBDIVISION_CACHE_ENABLED=true # Safe - database only
ADDRESS_DUPLICATE_DETECTION_ENABLED=true # Safe - database onlyUsers fill all address fields manually. Dropdowns still work from the local database.
US-Only Application
For applications that only deal with US addresses:
GOOGLE_MAPS_SERVER_KEY=your_server_key # Geocoding API + Maps Static API
GOOGLE_MAPS_BROWSER_KEY=your_browser_key # Maps JavaScript API + Places API
ADDRESS_VERIFICATION_PROVIDER=usps
USPS_CONSUMER_KEY=your_key
USPS_CONSUMER_SECRET=your_secret
ADDRESS_GEOCODING_CACHE_ENABLED=trueUSPS is free and authoritative for US addresses. Google keys are still needed for the address search field and blur geocoding (the address entry UX).
International Application
For applications handling addresses from multiple countries:
GOOGLE_MAPS_SERVER_KEY=your_server_key # Geocoding API + Maps Static API + Address Validation API
GOOGLE_MAPS_BROWSER_KEY=your_browser_key # Maps JavaScript API + Places API
ADDRESS_VERIFICATION_PROVIDER=auto
USPS_CONSUMER_KEY=your_key
USPS_CONSUMER_SECRET=your_secret
ADDRESS_GEOCODING_CACHE_ENABLED=true
ADDRESS_SUBDIVISION_CACHE_ENABLED=trueThe auto provider uses smart routing: USPS for US addresses (via the country_providers pin), Smarty-first for the 155 countries where it has DeliveryPoint-level precision (CA, AU, GB, FR, DE, BR, and others), and Google-first for all remaining countries (JP, CN, etc.). Configure both Smarty and Google for broadest international coverage.
High-Volume / Cost-Sensitive Production
For applications with many address saves per day:
ADDRESS_GEOCODING_CACHE_ENABLED=true
ADDRESS_GEOCODING_CACHE_TTL_GEOCODE=2592000 # 30 days
ADDRESS_GEOCODING_CACHE_TTL_REVERSE=604800 # 7 days
ADDRESS_BLUR_SMART_DETECTION=smart # Avoid geocoding garbage input
ADDRESS_BLUR_REQUIRE_COMPLETENESS=basic # Require city or postal before geocoding
ADDRESS_BLUR_MIN_LENGTH=15 # Avoid short/incomplete input
ADDRESS_IMPORT_GEOCODE_DEFAULT=false # Don't geocode every imported address
ADDRESS_IMPORT_VERIFY_DEFAULT=false # Don't verify every imported addressAnd restrict bulk operations to admins (see authorization above).
Multi-User / Team Application
For applications with multiple users who should not see each other's data:
ADDRESS_AUTHORIZATION_ENABLED=true
ADDRESS_AUTH_BULK_VERIFY=false # Override in config to restrict to admin roles
ADDRESS_AUTH_IMPORT=false
ADDRESS_AUTH_EXPORT=falseThen customize closures in config/addresses.php for row-level permissions, or install Spatie Permission for role-based access:
composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"Then assign permissions to roles. No other configuration is needed.
Troubleshooting
Geocoding is not working
- Check server key is set:
php artisan tinker --execute="dump(config('addresses.google_maps_server_key'));" - Verify the Geocoding API is enabled in Google Cloud Console for that key
- Check Laravel logs for HTTP errors:
tail -f storage/logs/laravel.log | grep geocod
Map image is not loading
- Check
ADDRESS_FORM_MAPistrue - Verify Maps JavaScript API and Static Maps API are both enabled in Google Cloud Console
- Check the
/filament-address/map-imageroute is accessible:php artisan route:list --path=filament-address - Check browser console and Laravel logs for errors from the proxy route
- Ensure the key has no referrer restrictions (the proxy makes server-side requests, which have no referrer)
- Try disabling cache temporarily (
ADDRESS_STATIC_MAP_CACHE_ENABLED=false) to rule out stale cache issues
Verification silently falls back to geocoding
Check the logs for warnings:
tail -f storage/logs/laravel.log | grep -i "verification\|provider"Common log messages and what they mean:
| Log message | Cause | Fix |
|---|---|---|
| "Unknown verification provider configured" | Typo in ADDRESS_VERIFICATION_PROVIDER | Use auto, usps, google, or none |
| "Requested provider not available for this country or not configured" | USPS selected for non-US country, or missing credentials | Use auto or configure credentials |
| "No verification provider available" | No configured provider supports the country | Configure Google provider |
| "Verification is disabled" | ADDRESS_VERIFICATION_ENABLED=false | Enable it if intended |
Costs are higher than expected
- Check if geocoding cache is enabled:
config('addresses.geocoding.cache.enabled') - Check cache hit rate in the Addressing Dashboard resource
- Run
php artisan addresses:cache:stats --days=7for cost analysis - Review smart detection settings to avoid geocoding garbage input
Dropdowns are slow
Enable subdivision caching:
ADDRESS_SUBDIVISION_CACHE_ENABLED=true
ADDRESS_SUBDIVISION_CACHE_TTL=86400If the cache is warm but dropdowns are still slow, check database indexes on the country_subdivisions table.
Authorization is not working
- Confirm
ADDRESS_AUTHORIZATION_ENABLED=true - Check that your Filament panel is using the correct user model
- If using Spatie Permission, confirm permissions are assigned to roles
- Check the
AddressPolicyis registered:php artisan policy:list | grep Address
Import fails with entity type error
The import requires entity types to be explicitly allowed in the config:
// config/addresses.php
'import' => [
'allowed_entity_types' => [
'App\Models\User',
'App\Models\Contact', // Add your model here
],
],If the entity type in the CSV is not in this list, the row will fail silently and be counted in the Failed stat with no error details shown.