Veterans Crisis Line: dial 988 then Press 1, or text 838255.
Data Pipeline + Verification Disclosure

How we verify 143,700+ veteran resources

Most nonprofit directories say "verified" without saying what that means. We publish the actual pipeline: data sources, verification cadence, scoring formula, geocoding methodology, and quality-assurance workflows. Deterministic, reproducible, and open under CC-BY 4.0.

1. Data sources

Records are aggregated from authoritative federal, state, and nonprofit sources. We never accept payment for inclusion. Original-source attribution is preserved in each record's data_source field.

SourceCoverage
VA Lighthouse Facilities APIVA Medical Centers, CBOCs, Vet Centers, Mobile Vet Centers, National Cemeteries (~1,500 records)
VA Office of General Counsel Accreditation RosterVA-accredited attorneys, claim agents, and VSO representatives (~50,000 records)
State CVSO directories (50 states + DC)County Veterans Service Officers — free claims-help offices
HRSA Federally Qualified Health Centers (FQHCs)~14,000 federally-qualified clinics that accept veterans
CMS Medicare-certified providersNursing homes, home-health, hospice, dialysis
SAMHSA-tagged behavioral health providersMental health + substance use providers serving veterans
HUD-VASH granteesSupportive Housing for veterans (joint HUD-VA program)
SSVF granteesSupportive Services for Veteran Families
VSO chapter directoriesAmerican Legion, VFW, DAV, AMVETS, PVA posts
State agency veteran-services directoriesState-level benefits offices, veteran homes, etc.
U.S. Census ACS 5-year (2020–2024)Tract-level veteran demographics, housing burden, income
CDC PLACESTract-level health prevalences (used for context, not as resources)

2. Verification cadence

Records are maintained by automated pipelines plus a community-feedback review loop. Stale data is flagged + auto-demoted; broken URLs trigger Wayback Machine snapshots; contact details are ingested from authoritative federal and state directories and corrected when visitors report errors. We do not independently call-verify every phone number — see Phone accuracy below.

PipelineCadenceWhat it does
Self-healing daemonEvery 6 hoursEvaluates health_score, auto-demotes flagged-closed rows, runs HEAD probes on URLs, runs Census Geocoder on next 100 unprocessed rows
Census GeocoderEvery 6 hoursAssigns FIPS state/county/tract to records missing them. ~100 rows/run, ~400/day
Wayback Machine snapshot backfillEvery 6 hoursCaptures snapshots of broken URLs to archive.org for posterity
Haiku enrichment passWeekly (Tuesday 08:00 UTC)Claude Haiku 4.5 enriches 100 stale rows with structured eligibility tags, specialty programs, walk-in/appointment status, language, women-focused, va_accredited, and 1-line summary
ProPublica Form 990 enrichmentWeekly (Tuesday)EIN-matched records get latest 990 revenue, expenses, year-of-filing
VA Lighthouse reconcilerWeekly (Sunday 06:00 UTC)Stages differences between our records and VA's authoritative facility data to pending_updates queue for staff review
URL health scanWeekly (Wednesday 04:00 UTC), rollingHEAD probe + Google Safe Browsing on the 1,000 least-recently-checked URLs per run
Community feedback auto-triageContinuousVisitor reports (incorrect / closed / outdated) are deduplicated by reporter; ≥2 independent reports auto-escalate the record for review and add a caution notice on its page
IndexNow re-push (Bing/Yandex/Seznam/Naver)Weekly post-enrichmentPushes the 200 most-recently-updated URLs for instant search-engine re-crawl

3. Completeness-score formula

The completeness_score (0-100, integer) is a deterministic function of which fields are populated + verification status + ProPublica match. No manual curation, no payment for placement. Recomputed nightly. Full formula:

completeness_score = base + bonuses base (max 60): +10 if name + address populated +10 if phone populated +10 if website populated AND website_status = 'ok' +10 if hours populated +10 if services populated (>= 1 tag) +5 if eligibility populated +5 if specialty_programs populated bonuses (max 40): +5 if FIPS state/county/tract assigned (Census Geocoder) +5 if verified_date within last 90 days +5 if EIN populated AND ProPublica 990 match +5 if phone_verified = true (reserved; phones are not independently call-verified) +5 if veteran_relevance != 'general' (focused on vets) +5 if Wayback snapshot exists for the URL +10 if 0 healing-events triggered in last 30 days (no auto-demotions)

Score is exposed in every /resource/{slug}-{id} page header (gold pill on /best-of/* pages) and in the /api/resources/bulk JSON. Reproducible — run our SQL against your own snapshot of /api/export/snapshot to get identical scores.

4. Geocoding pipeline

Records with a postal address are geocoded to FIPS-tract level via the US Census Geocoder (Single-Address One-Line API) wherever the address resolves to a census tract — most records, not all. Tract-level granularity (median ~4,000 residents per tract) lets us join records to ACS demographics + CDC PLACES health data + ACS housing burden — surfacing service deserts for grant proposals.

Pipeline:

  1. Address normalized (USPS-compliant case + abbreviations)
  2. POST to Census Geocoder Locations API benchmark Public_AR_Census2020
  3. If match, capture lat/lng + FIPS state (2-digit) + FIPS county (3-digit) + FIPS tract (6-digit) + FIPS block group (1-digit) + match-type confidence
  4. If no match, retry with address fuzz (drop apt#, normalize street suffixes); if still no match, mark geocode_source = 'failed' for manual review
  5. Store + index FIPS columns for fast tract-level joins

Current FIPS-tract assignment: 90% of records (live count on /dashboard). Records without a tract match are mostly newer rows not yet run through the geocoder, PO Box addresses, or military APO/FPO.

5. Quality assurance

  • URL health: HEAD probes on a rolling weekly schedule + on-demand. Google Safe Browsing API check (free tier 10K URLs/day). Records with broken URLs get website_status = 'broken' and a Wayback snapshot link.
  • Phone accuracy: Phone numbers are ingested from authoritative federal and state directories (CMS, VA, HRSA, HUD, SAMHSA, state DVAs). We do not independently call-verify every number; accuracy is maintained through the community-feedback auto-triage loop — visitor reports of wrong or disconnected numbers escalate the record for correction. phone_verified + phone_type are reserved for records confirmed against an authoritative live source.
  • EIN verification: 501(c)(3) records cross-referenced against ProPublica Nonprofit Explorer. Mismatched EINs flagged.
  • Duplicate detection: dedup_candidates table holds suspected duplicates (same address + same name fuzz match) for staff review.
  • Veteran relevance tier: Three tiers (veteran_primary = built for veterans; veteran_serving = veterans named target population; vet_accepting = general healthcare). Default search filters to first two tiers.
  • Editorial review: Tier-1 (high-traffic, high-stakes) records get manual quarterly review. Editorial flags surface in verification_runs table.

6. Correction workflows

Anyone — including the listed organization, a veteran, a journalist, or a researcher — can submit a correction or addition. Workflow:

  1. Submit via POST /api/feedback or email info@warriorsfund.org
  2. Review queue at resource_feedback table
  3. Staff review within 5 business days
  4. Verified corrections committed; original-state archived in resource_history for full audit trail
  5. If the change came from the listed organization, reply with confirmation + commit timestamp

7. Open-data license

All Wounded Warriors datasets are licensed under Creative Commons Attribution 4.0 International (CC-BY 4.0). Free to share, adapt, and build upon for any purpose (commercial included), provided you credit "Wounded Warriors (EIN 86-1336741)" and link back to https://warriorsfund.org/.

Bulk data: CSV · JSON · snapshot manifest with a SHA-256 data fingerprint · Project Open Data v1.1 / DCAT 1.1 catalog

8. Data fingerprint

The directory is too large for one response, so there is no single hashed file of every record. Instead /api/export/snapshot publishes a data fingerprint: a SHA-256 over three aggregate values for the live (not soft-deleted) records — the total record count, the newest updated_at timestamp, and the per-state record counts. It changes whenever the published counts or the latest update change, so you can tell whether the directory changed between two downloads. It does not hash individual records, so it cannot prove that a given record is unaltered.

How it is computed:

  1. total = live record count; lastUpdated = MAX(updated_at); stateVector = [[state, count], …] for live records, sorted by state code.
  2. Serialize exactly JSON.stringify({ total, lastUpdated, stateVector }) (that key order, no whitespace).
  3. SHA-256 of that string, hex-encoded, is meta.data_fingerprint_sha256; the response also carries total_resources, states_covered and last_updated.

For the records themselves, page through /api/resources/bulk (numbered pages: follow _links.next while has_next is true).

About this disclosure

This methodology page is the canonical reference for our data pipeline. It's updated whenever the pipeline changes — see Git history at github.com/EmperorMew/WWF for the audit trail. Foundation officers + academic reviewers + journalists doing source-evaluation: this page should answer your "how do you verify?" question definitively. If anything is unclear, email info@warriorsfund.org.