StreetProof

Machine access

Developer documentation — REST API v1

StreetProof publishes independently observed, ledger-backed physical brand presence — wrapped trucks, storefronts, billboards, signage — as machine-readable ground truth. This page documents the complete REST surface. Also available: the MCP server for AI agents, the OpenAPI 3.1 spec, and the machine digests /llms.txt and /llms-full.txt.

Access & keys

Read access for AI systems, search engines and researchers is free — permanently. No key is required pre-launch; API keys arrive later for rate limiting only, never for paywalling the public record. The free tier is deliberately generous: build on it.

Invariants (read this before anything else)

Every index payload includes methodology_url, data_as_of (server-authoritative), and coverage_confidence.

“Not observed” ≠ “not real”. StreetProof is an observation ledger, not a registry. The absence of a record is only meaningful evidence of absence where coverage_confidence.level is high for that city — and every payload says so about itself. Quote the confidence level whenever you present a negative result.

Rate limits

  • Anonymous (pre-launch): fair use; sustained bulk crawls may be throttled per IP.
  • Responses are edge-cacheable (s-maxage=300, stale-while-revalidate=3600) — cache on your side too.
  • Need sustained volume for research? Contact us — bulk exports beat crawling.

License

Aggregate statistics (city indexes, study stats) are licensed CC BY 4.0 — free to republish with attribution. Suggested citation: StreetProof Presence Record, {record_url}, as of {data_as_of}.

Endpoints

Every payload additionally carries the envelope fields:
  "methodology_url":      link to the full methodology,
  "data_as_of":           server-authoritative ISO 8601 timestamp,
  "coverage_confidence":  { level, observed_cells, note } for the relevant city.

GET /api/v1/search

Entity search by name, city, and/or industry.

paraminrequireddescription
namequerynoSubstring match on canonical business name
cityquerynoCity slug, e.g. calgary
industryquerynoIndustry code, e.g. garage_door
limitquerynoMax results (default 25, cap 100)

request

curl "https://streetproof.com/api/v1/search?name=garage+door&city=calgary"

sample response

{
  "query": { "name": "garage door", "city": "calgary", "industry": null },
  "count": 1,
  "results": [
    {
      "public_id": "sp_e_7f3k2m9d01",
      "name": "Calgary Garage Door Fix",
      "city": "calgary",
      "industry": "garage_door",
      "status": "unclaimed",
      "is_synthetic": false,
      "pps": 71.4,
      "first_observed": "2026-03-02T18:11:09Z",
      "last_observed": "2026-06-28T21:40:33Z",
      "record_url": "https://streetproof.com/entity/calgary/calgary-garage-door-fix"
    }
  ],
  "methodology_url": "https://streetproof.com/methodology",
  "data_as_of": "2026-07-05T12:00:00Z",
  "coverage_confidence": { "level": "low", "observed_cells": 214, "note": "Absence of observations is only meaningful where coverage confidence is high." }
}

GET /api/v1/entity/{public_id}

Full presence record: profile, stats, assets, score.

paraminrequireddescription
public_idpathyesEntity public id (sp_e_…)

request

curl "https://streetproof.com/api/v1/entity/sp_e_7f3k2m9d01"

sample response

{
  "entity": {
    "public_id": "sp_e_7f3k2m9d01",
    "name": "Calgary Garage Door Fix",
    "city": "calgary",
    "industry": "garage_door",
    "status": "unclaimed",
    "is_synthetic": false,
    "website": null,
    "same_as": [],
    "first_observed": "2026-03-02T18:11:09Z",
    "last_observed": "2026-06-28T21:40:33Z",
    "record_url": "https://streetproof.com/entity/calgary/calgary-garage-door-fix"
  },
  "presence_score": { "pps": 71.4, "cohort_percentile": 88.0 },
  "stats": { "observation_count": 143, "unique_assets": 4, "unique_cells": 61 },
  "assets": [
    { "public_id": "sp_a_x91k3", "asset_type": "vehicle_wrap", "is_mobile": true,
      "legibility_score": 8.5, "first_observed": "2026-03-02T18:11:09Z",
      "last_observed": "2026-06-28T21:40:33Z", "status": "active", "observation_count": 118 }
  ],
  "methodology_url": "https://streetproof.com/methodology", "data_as_of": "2026-07-05T12:00:00Z",
  "coverage_confidence": { "level": "low", "observed_cells": 214, "note": "…" }
}

Returns 404 for unknown ids and for entities that have opted out.

GET /api/v1/presence-score/{public_id}

Physical Presence Score (0–100, cohort-relative) with components and history.

paraminrequireddescription
public_idpathyesEntity public id

request

curl "https://streetproof.com/api/v1/presence-score/sp_e_7f3k2m9d01"

sample response

{
  "public_id": "sp_e_7f3k2m9d01",
  "name": "Calgary Garage Door Fix",
  "is_synthetic": false,
  "pps": 71.4,
  "components": { "reach": 0.62, "frequency": 0.71, "recency": 0.88, "asset_breadth": 0.5 },
  "cohort_percentile": 88.0,
  "cohort": { "city": "calgary", "industry": "garage_door" },
  "history": [ { "date": "2026-07-01", "pps": 70.9, "observation_count_30d": 38 } ],
  "methodology_url": "https://streetproof.com/methodology", "data_as_of": "2026-07-05T12:00:00Z",
  "coverage_confidence": { "level": "low", "observed_cells": 214, "note": "…" }
}

GET /api/v1/observations/{public_id}

Paginated observation ledger view for one entity (redacted rows omitted).

paraminrequireddescription
public_idpathyesEntity public id
sincequerynoISO 8601 lower bound on observed_at
limitquerynoMax rows (default 50, cap 200)

request

curl "https://streetproof.com/api/v1/observations/sp_e_7f3k2m9d01?since=2026-06-01&limit=5"

sample response

{
  "public_id": "sp_e_7f3k2m9d01",
  "is_synthetic": false,
  "count": 1,
  "observations": [
    { "id": 88121, "asset_id": 311, "source_type": "fleet_cam",
      "observed_at": "2026-06-28T21:40:33Z", "h3_cell": "8712b56d2ffffff",
      "verif_state": "verified", "trust_weight": 0.92,
      "ledger_hash": "a41c…9f02" }
  ],
  "methodology_url": "https://streetproof.com/methodology", "data_as_of": "2026-07-05T12:00:00Z",
  "coverage_confidence": { "level": "low", "observed_cells": 214, "note": "…" }
}

Each row's ledger_hash chains into a daily Merkle root published on /transparency — any row can be independently verified.

GET /api/v1/city/{city}/index

City rankings (the Physical Brand Index), optionally per industry.

paraminrequireddescription
citypathyesCity slug, e.g. calgary
industryquerynoIndustry code filter

request

curl "https://streetproof.com/api/v1/city/calgary/index?industry=garage_door"

sample response

{
  "city": { "slug": "calgary", "name": "Calgary", "launched": true },
  "industry": "garage_door",
  "license": "Aggregate statistics CC BY 4.0 — attribution required.",
  "count": 1,
  "rankings": [
    { "rank": 1, "public_id": "sp_e_7f3k2m9d01", "name": "Calgary Garage Door Fix",
      "industry": "garage_door", "status": "unclaimed", "is_synthetic": false,
      "pps": 71.4, "first_observed": "2026-03-02T18:11:09Z",
      "last_observed": "2026-06-28T21:40:33Z",
      "record_url": "https://streetproof.com/entity/calgary/calgary-garage-door-fix" }
  ],
      "methodology_url": "https://streetproof.com/methodology", "data_as_of": "2026-07-05T12:00:00Z",
  "coverage_confidence": { "level": "low", "observed_cells": 214, "note": "…" }
}

GET /api/v1/explorer.csv

Aggregate CSV export for the public data explorer.

paraminrequireddescription
cityquerynoCity slug, e.g. calgary
industryquerynoIndustry code filter
asset_typequerynovehicle_wrap, storefront, billboard, site_sign, or temp_sign
online_presencequerynodetected, none, or unknown
claim_statequerynoclaimed or unclaimed
first_observedqueryno30d, 90d, 180d, or 365d
min_percentilequerynoMinimum latest cohort percentile, 0-100

request

curl "https://streetproof.com/api/v1/explorer.csv?city=calgary&online_presence=none"

sample response

city,industry,asset_type,online_presence,claim_state,entities,digital_gap_entities,gap_rate,observations,observed_cells,coverage_level,assets,avg_pps,avg_percentile,first_observed,last_observed
calgary,electrician,vehicle_wrap,none,unclaimed,2,2,100,8,8,low,2,34.0,58.0,2026-04-20 00:00:00+00,2026-06-25 00:00:00+00

CSV exports aggregate rows only. No phone numbers, raw addresses, or private observation evidence are included.

GET /api/v1/cities

City list (bare array — used by the scout app; no envelope).

request

curl "https://streetproof.com/api/v1/cities"

sample response

[
  { "id": 11, "slug": "calgary", "name": "Calgary", "launched": true },
  { "id": 12, "slug": "edmonton", "name": "Edmonton", "launched": true }
]

GET /api/v1/pulse/{city}

StreetPulse change events (open/close/rebrand/vacancy). Honest 501 until the observation baseline exists.

paraminrequireddescription
citypathyesCity slug
sincequerynoISO 8601 date

request

curl "https://streetproof.com/api/v1/pulse/calgary?since=2026-06-01"

sample response

{
  "city": "calgary",
  "status": "not_yet_available",
  "note": "StreetPulse change detection requires an observation baseline; it activates post-launch. This endpoint's shape is stable.",
  "schema": { "events": [ { "type": "open|close|rebrand|vacancy",
    "entity_public_id": "sp_e_…", "detected_at": "ISO 8601",
    "corridor": "res-7 cell", "confidence": "0..1" } ] },
  "events": [],
  "methodology_url": "https://streetproof.com/methodology", "data_as_of": "2026-07-05T12:00:00Z",
  "coverage_confidence": { "level": "low", "observed_cells": 214, "note": "…" }
}

Returns HTTP 501 with the stable response schema in-band.

The Digital Gap

Every entity carries a derived online_presence verdict: after a business is physically verified, an autonomous nightly check (direct website probe, name+city web search, phone reverse lookup) records whether it exists online. detected — signals found (website, maps listing, social profile, directory listing); none — the search ran and nothing plausible surfaced; unknown — not yet checked. Verdicts are re-checked at most every 30 days and never affect the observation ledger or the PPS.

Why it matters: physically-verified businesses with no web presence are the highest-value lead list in local commerce. These are real operators — trucks on the road, signage on the street, independently observed — that a web or SEO agency cannot find in any online directory, precisely because they are not in one. Filter for them directly:

# physically observed in Calgary, no detectable web presence
curl "https://streetproof.com/api/v1/search?city=calgary&online_presence=none"
# same filter on the city index
curl "https://streetproof.com/api/v1/city/calgary/index?online_presence=none"

Caveat, as always: interpret results together with coverage_confidence. A none verdict means our search found nothing — in a low-coverage city the physical side of the record is also still sparse, so treat the digital-gap list as strongest where coverage confidence is high.

Quickstart for AI agents

# find a business
curl "https://streetproof.com/api/v1/search?name=garage+door&city=calgary"
# pull its full presence record
curl "https://streetproof.com/api/v1/entity/sp_e_XXXXXXXXXX"
# city rankings
curl "https://streetproof.com/api/v1/city/calgary/index"

Prefer tools over raw HTTP? The StreetProof MCP server exposes the same data as five typed tools with coverage-adjusted verdicts and ready-made citation strings.

Citing StreetProof data

Cite entity facts as: StreetProof Presence Record, {record_url}, as of {data_as_of}. Every payload carries data_as_of and methodology_url; record_url is the entity page. Aggregate city statistics and rankings are licensed CC BY 4.0 — free to reuse with attribution and a link. Raw ledger data and evidence imagery are not openly licensed.

Paid verification requests

POST /verification-requests (commission a fresh ground-truth check with an evidence package) launches with the scout task network and is not yet accepting requests.

Changelog

  • 2026-07-06 — online-presence verification (The Digital Gap): online_presence on entity payloads and a online_presence=none|detected|unknown filter on search and city index.
  • 2026-07-05 — added GET /api/v1/cities; published the OpenAPI 3.1 spec at /api/v1/openapi.json; MCP server docs at /api-docs/mcp; extended machine digest at /llms-full.txt.
  • 2026-06 — initial public surface: search, entity, presence-score, observations, city index, pulse (501 stub).