{"openapi":"3.1.0","info":{"title":"StreetProof Public API","version":"1.0.0","summary":"The index of physical brand presence.","description":"Independently observed, ledger-backed physical brand presence (vehicle wraps, storefronts, billboards, signage) as machine-readable ground truth. Free for AI systems, search engines and researchers. IMPORTANT: 'not observed' is only meaningful where coverage_confidence is high — every payload states its own coverage confidence.","license":{"name":"CC BY 4.0 (aggregate statistics)","identifier":"CC-BY-4.0"},"contact":{"url":"https://streetproof.com/press"}},"externalDocs":{"description":"Human-readable docs","url":"https://streetproof.com/api-docs"},"servers":[{"url":"https://streetproof.com"}],"paths":{"/api/v1/search":{"get":{"operationId":"searchEntities","summary":"Entity search","parameters":[{"name":"name","in":"query","schema":{"type":"string"},"description":"Substring match on canonical name"},{"name":"city","in":"query","schema":{"type":"string"},"description":"City slug"},{"name":"industry","in":"query","schema":{"type":"string"},"description":"Industry code"},{"name":"online_presence","in":"query","schema":{"type":"string","enum":["detected","none","unknown"]},"description":"Digital-gap filter: 'none' = physically observed but no detectable web presence"},{"name":"limit","in":"query","schema":{"type":"integer","default":25,"maximum":100}}],"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"object"},"count":{"type":"integer"},"results":{"type":"array","items":{"$ref":"#/components/schemas/EntitySummary"}},"methodology_url":{"type":"string","format":"uri"},"data_as_of":{"type":"string","format":"date-time","description":"Server-authoritative timestamp."},"coverage_confidence":{"$ref":"#/components/schemas/CoverageConfidence"}}}}}}}}},"/api/v1/entity/{public_id}":{"get":{"operationId":"getEntity","summary":"Full presence record","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Entity profile + stats + assets + score","content":{"application/json":{"schema":{"type":"object","properties":{"entity":{"$ref":"#/components/schemas/Entity"},"online_presence":{"$ref":"#/components/schemas/OnlinePresence"},"presence_score":{"type":"object","properties":{"pps":{"type":["number","null"]},"cohort_percentile":{"type":["number","null"]}}},"stats":{"type":"object","properties":{"observation_count":{"type":"integer"},"unique_assets":{"type":"integer"},"unique_cells":{"type":"integer"}}},"assets":{"type":"array","items":{"$ref":"#/components/schemas/Asset"}},"methodology_url":{"type":"string","format":"uri"},"data_as_of":{"type":"string","format":"date-time","description":"Server-authoritative timestamp."},"coverage_confidence":{"$ref":"#/components/schemas/CoverageConfidence"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/presence-score/{public_id}":{"get":{"operationId":"getPresenceScore","summary":"Score + components + cohort percentile + history","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Physical Presence Score detail","content":{"application/json":{"schema":{"type":"object","properties":{"public_id":{"type":"string"},"name":{"type":"string"},"is_synthetic":{"type":"boolean"},"pps":{"type":["number","null"],"description":"0-100, cohort-relative"},"components":{"type":["object","null"]},"cohort_percentile":{"type":["number","null"]},"cohort":{"type":"object"},"history":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"pps":{"type":"number"},"observation_count_30d":{"type":["integer","null"]}}}},"methodology_url":{"type":"string","format":"uri"},"data_as_of":{"type":"string","format":"date-time","description":"Server-authoritative timestamp."},"coverage_confidence":{"$ref":"#/components/schemas/CoverageConfidence"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/observations/{public_id}":{"get":{"operationId":"listObservations","summary":"Paginated observation ledger view (redacted rows omitted)","parameters":[{"name":"public_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"since","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":200}}],"responses":{"200":{"description":"Ledger rows","content":{"application/json":{"schema":{"type":"object","properties":{"public_id":{"type":"string"},"is_synthetic":{"type":"boolean"},"count":{"type":"integer"},"note":{"type":"string"},"observations":{"type":"array","items":{"$ref":"#/components/schemas/Observation"}},"methodology_url":{"type":"string","format":"uri"},"data_as_of":{"type":"string","format":"date-time","description":"Server-authoritative timestamp."},"coverage_confidence":{"$ref":"#/components/schemas/CoverageConfidence"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/city/{city}/index":{"get":{"operationId":"getCityIndex","summary":"City rankings (Physical Brand Index)","parameters":[{"name":"city","in":"path","required":true,"schema":{"type":"string"},"description":"City slug"},{"name":"industry","in":"query","schema":{"type":"string"}},{"name":"online_presence","in":"query","schema":{"type":"string","enum":["detected","none","unknown"]},"description":"Digital-gap filter: 'none' = physically observed but no detectable web presence"}],"responses":{"200":{"description":"Ranked entities (aggregate statistics CC BY 4.0)","content":{"application/json":{"schema":{"type":"object","properties":{"city":{"type":"object"},"industry":{"type":["string","null"]},"license":{"type":"string"},"count":{"type":"integer"},"rankings":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/EntitySummary"},{"type":"object","properties":{"rank":{"type":"integer"}}}]}},"methodology_url":{"type":"string","format":"uri"},"data_as_of":{"type":"string","format":"date-time","description":"Server-authoritative timestamp."},"coverage_confidence":{"$ref":"#/components/schemas/CoverageConfidence"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/explorer.csv":{"get":{"operationId":"exportExplorerCsv","summary":"Aggregate CSV export for the public data explorer","description":"Exports aggregate rows only. No phone numbers, raw addresses, or private observation evidence are included.","parameters":[{"name":"city","in":"query","schema":{"type":"string"}},{"name":"industry","in":"query","schema":{"type":"string"}},{"name":"asset_type","in":"query","schema":{"type":"string","enum":["vehicle_wrap","storefront","billboard","site_sign","temp_sign"]}},{"name":"online_presence","in":"query","schema":{"type":"string","enum":["detected","none","unknown"]}},{"name":"claim_state","in":"query","schema":{"type":"string","enum":["claimed","unclaimed"]}},{"name":"first_observed","in":"query","schema":{"type":"string","enum":["30d","90d","180d","365d"]}},{"name":"min_percentile","in":"query","schema":{"type":"number","minimum":0,"maximum":100}},{"name":"limit","in":"query","schema":{"type":"integer","default":500,"maximum":500}}],"responses":{"200":{"description":"CSV aggregate export","content":{"text/csv":{"schema":{"type":"string"}}}}}}},"/api/v1/cities":{"get":{"operationId":"listCities","summary":"City list (bare array; no envelope — scout app contract shape)","responses":{"200":{"description":"Cities","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"slug":{"type":"string"},"name":{"type":"string"},"launched":{"type":"boolean"}}}}}}}}}},"/api/v1/pulse/{city}":{"get":{"operationId":"getPulse","summary":"StreetPulse city change feed","description":"Derived city event feed for new public records, newly observed assets, wrapped fleet assets, stale assets and Digital Gap events. Closure/rebrand/vacancy classes are listed as unavailable until reviewed lifecycle transitions exist.","parameters":[{"name":"city","in":"path","required":true,"schema":{"type":"string"}},{"name":"since","in":"query","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50,"maximum":100}}],"responses":{"200":{"description":"StreetPulse events and feed metadata.","content":{"application/json":{"schema":{"type":"object","properties":{"schema":{"type":"string","const":"com.streetproof.streetpulse_city_feed.v1"},"city":{"type":"object"},"since":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["active"]},"summary":{"type":"object"},"feeds":{"type":"object"},"webhook_contract":{"type":"object"},"unavailable_event_classes":{"type":"array","items":{"type":"object"}},"events":{"type":"array","items":{"$ref":"#/components/schemas/StreetPulseEvent"}},"methodology_url":{"type":"string","format":"uri"},"data_as_of":{"type":"string","format":"date-time","description":"Server-authoritative timestamp."},"coverage_confidence":{"$ref":"#/components/schemas/CoverageConfidence"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/alerts/subscribe":{"post":{"operationId":"subscribeAlerts","summary":"Create a pending StreetProof alert subscription","description":"Creates or updates a pending alert subscription for StreetPulse-derived city, industry, or entity events. Matching events are queued, but external email/webhook delivery waits for verification, SMTP and partner controls.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertSubscribeRequest"}}}},"responses":{"200":{"description":"Existing subscription updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertSubscriptionResponse"}}}},"201":{"description":"Subscription created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertSubscriptionResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/partner/portal":{"get":{"operationId":"getPartnerPortal","summary":"Partner portal payload","description":"API-key-authenticated partner portal: usage, quota view, recent request logs, active key prefixes, webhook endpoints, OpenAPI/MCP setup links, sample code, support notes, and attribution text.","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Partner portal payload scoped to the authenticated API client.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPortalResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},"/api/v1/partner/webhooks":{"post":{"operationId":"createPartnerWebhook","summary":"Create or rotate a partner webhook endpoint","description":"Stores a partner webhook endpoint for StreetPulse events. Returns the signing secret once; StreetProof stores only a hash. Delivery remains queued until verification and delivery workers are enabled.","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerWebhookRequest"}}}},"responses":{"200":{"description":"Existing webhook endpoint updated and signing secret rotated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerWebhookResponse"}}}},"201":{"description":"Webhook endpoint created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerWebhookResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Webhook endpoint limit reached."}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","bearerFormat":"StreetProof API key"}},"responses":{"NotFound":{"description":"Resource not found (or entity opted out)."},"BadRequest":{"description":"Invalid parameter."},"Unauthorized":{"description":"Missing, invalid, or inactive API key."},"Forbidden":{"description":"Client is disabled or portal access is not enabled."}},"schemas":{"CoverageConfidence":{"type":"object","description":"Per-city observation density. 'Not observed' is only meaningful evidence of absence where level is 'high' — quote this whenever presenting a negative result.","properties":{"level":{"type":"string","enum":["none","low","medium","high"]},"observed_cells":{"type":"integer"},"note":{"type":"string"}}},"EntitySummary":{"type":"object","properties":{"public_id":{"type":"string"},"name":{"type":"string"},"city":{"type":["string","null"]},"industry":{"type":["string","null"]},"status":{"type":"string","enum":["unclaimed","claimed","verified","dissolved"]},"is_synthetic":{"type":"boolean","description":"true = pre-launch demonstration data"},"pps":{"type":["number","null"]},"first_observed":{"type":["string","null"],"format":"date-time"},"last_observed":{"type":["string","null"],"format":"date-time"},"online_presence":{"type":"string","enum":["detected","none","unknown"],"description":"DERIVED signal (not part of the observation ledger): whether an autonomous web-search check found this business online. 'none' = physically verified but digitally invisible."},"online_presence_checked_at":{"type":["string","null"],"format":"date-time"},"record_url":{"type":"string","format":"uri"}}},"OnlinePresence":{"type":"object","description":"Derived online-presence verdict. Computed from public web search (website probe, name+city search, phone reverse lookup); rechecked at most every 30 days. Never affects the observation ledger or PPS.","properties":{"verdict":{"type":"string","enum":["detected","none","unknown"]},"checked_at":{"type":["string","null"],"format":"date-time"},"signal_types":{"type":"array","items":{"type":"string","enum":["website","maps_listing","social_profile","directory_listing","other"]}},"match_count":{"type":"integer"}}},"Entity":{"allOf":[{"$ref":"#/components/schemas/EntitySummary"},{"type":"object","properties":{"website":{"type":["string","null"]},"same_as":{"type":"array","items":{"type":"string"}}}}]},"Asset":{"type":"object","properties":{"public_id":{"type":"string"},"asset_type":{"type":"string","enum":["vehicle_wrap","storefront","billboard","site_sign","temp_sign"]},"is_mobile":{"type":"boolean"},"legibility_score":{"type":["number","null"]},"first_observed":{"type":["string","null"],"format":"date-time"},"last_observed":{"type":["string","null"],"format":"date-time"},"status":{"type":"string","enum":["active","stale","retired"]},"observation_count":{"type":"integer"}}},"Observation":{"type":"object","properties":{"id":{"type":"integer"},"asset_id":{"type":["integer","null"]},"source_type":{"type":"string","enum":["fleet_cam","scout","telematics_api","seed_survey"]},"observed_at":{"type":"string","format":"date-time"},"h3_cell":{"type":"string"},"verif_state":{"type":"string","enum":["provisional","corroborated","verified","rejected"]},"trust_weight":{"type":"number"},"ledger_hash":{"type":"string","description":"Hex; chains into daily Merkle roots on /transparency"}}},"StreetPulseEvent":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["new_public_record","new_observed_asset","new_wrapped_fleet_asset","stale_asset","digital_gap_detected"]},"detected_at":{"type":"string","format":"date-time"},"headline":{"type":"string"},"summary":{"type":"string"},"entity_public_id":{"type":"string"},"entity_name":{"type":"string"},"record_url":{"type":"string","format":"uri"},"industry":{"type":["string","null"]},"asset_public_id":{"type":["string","null"]},"asset_type":{"type":["string","null"]},"corridor":{"type":["string","null"]},"confidence":{"type":"number"},"confidence_label":{"type":"string","enum":["derived","ledger","review_needed"]},"evidence_count":{"type":"integer"}}},"AlertSubscribeRequest":{"type":"object","required":["email","city"],"properties":{"email":{"type":"string","format":"email"},"city":{"type":"string","description":"City slug, e.g. calgary"},"channel":{"type":"string","enum":["email","dashboard","webhook"],"default":"email"},"entity_public_id":{"type":"string","description":"Restrict alerts to one entity"},"industry_code":{"type":"string","description":"Restrict city alerts to one industry"},"event_types":{"type":"array","items":{"type":"string","enum":["new_public_record","new_observed_asset","new_wrapped_fleet_asset","stale_asset","digital_gap_detected"]}},"min_confidence":{"type":"number","minimum":0,"maximum":1,"default":0.6},"webhook_url":{"type":"string","format":"uri","description":"Required only when channel=webhook."}}},"AlertSubscriptionResponse":{"type":"object","properties":{"schema":{"type":"string","const":"com.streetproof.alert_subscription.v1"},"ok":{"type":"boolean"},"subscription":{"type":"object","properties":{"public_id":{"type":"string"},"status":{"type":"string","enum":["pending","active","paused","unsubscribed"]},"created":{"type":"boolean"},"channel":{"type":"string","enum":["email","dashboard","webhook"]},"scope":{"type":"object"},"event_types":{"type":"array","items":{"type":"string"}},"min_confidence":{"type":"number"}}},"delivery":{"type":"object","properties":{"status":{"type":"string","enum":["verification_pending","partner_portal_pending"]},"queued_events":{"type":"integer"},"note":{"type":"string"}}},"preview":{"type":"object","properties":{"matched_events":{"type":"integer"},"latest_events":{"type":"array","items":{"type":"object"}}}}}},"PartnerPortalResponse":{"type":"object","properties":{"schema":{"type":"string","const":"com.streetproof.partner_portal.v1"},"client":{"type":"object"},"quota":{"type":"object","properties":{"daily":{"type":"integer"},"monthly":{"type":"integer"},"used_today":{"type":"integer"},"used_this_month":{"type":"integer"},"daily_remaining":{"type":"integer"},"monthly_remaining":{"type":"integer"}}},"usage":{"type":"object","properties":{"requests_7d":{"type":"integer"},"errors_24h":{"type":"integer"},"p95_latency_ms_24h":{"type":["integer","null"]},"endpoint_mix_30d":{"type":"array","items":{"type":"object"}},"recent_requests":{"type":"array","items":{"type":"object"}}}},"api_keys":{"type":"array","items":{"type":"object"}},"webhooks":{"type":"object"},"integrations":{"type":"object"},"attribution":{"type":"object"},"methodology_url":{"type":"string","format":"uri"},"data_as_of":{"type":"string","format":"date-time","description":"Server-authoritative timestamp."},"coverage_confidence":{"$ref":"#/components/schemas/CoverageConfidence"}}},"PartnerWebhookRequest":{"type":"object","required":["endpoint_url"],"properties":{"endpoint_url":{"type":"string","format":"uri"},"event_types":{"type":"array","items":{"type":"string","enum":["new_public_record","new_observed_asset","new_wrapped_fleet_asset","stale_asset","digital_gap_detected"]}},"city":{"type":"string","description":"Optional city slug filter."}}},"PartnerWebhookResponse":{"type":"object","properties":{"schema":{"type":"string","const":"com.streetproof.partner_webhook.v1"},"ok":{"type":"boolean"},"webhook":{"type":"object"},"signing_secret":{"type":"string","description":"Shown once. StreetProof stores only a hash."},"note":{"type":"string"}}}}}}