The StormTrust data service provides a versioned read boundary. Consumers do not depend on ingestion jobs, D1 tables, R2 keys, or Queue messages.
The canonical OpenAPI specification ↗
defines the deployed read contract. The website exposes allowlisted GET and
HEAD routes. StormTrust Workers can use the same contract through a service
binding to stormtrust-data.
GET /openapi.json
GET /v1/places/search?q={query}
GET /v1/storm-events
GET /v1/storm-events/{eventId}/revisions
GET /v1/storm-events/{eventId}/manifest
GET /v1/storm-events/{eventId}/revisions/{revisionId}/manifest
GET /v1/storm-events/{eventId}/frames/{productId}/{frameId}.png
GET /v1/storm-events/{eventId}/stream
GET /v1/data/statusThe stream route upgrades to WebSocket. StormStreamMessage in the specification
defines the JSON stream.ready and storm.revision.ready messages. The
x-websocket-messages extension connects those schemas to the route; it is a
local documentation convention, not standard OpenAPI transport modeling. A text
ping receives a plain text pong. Notices prompt authoritative reads and do
not guarantee complete history or delivery of every publication.
Revision lists return the latest bounded subset in ascending publication
sequence, which can differ from observation order when corrections arrive.
DataProductStatus defines the existing snake_case status fields and their null
semantics. It reports latest discovered assets across live and benchmark events,
not evaluated freshness or completeness. See polling and triggers.
The source specification is org/apps/data/openapi.json. Data-service contract
tests validate actual Worker HTTP bodies and WebSocket messages against its
JSON Schemas, including malformed-payload rejection and late-correction order.
The service does not expose discovery, backfill, ingestion, or storage-control
routes through the website. Legacy /api/ and /mrms/ paths remain temporary
compatibility aliases.
The deployed read contract uses:
/v1/Backward-incompatible changes require a new major API version or a governed compatibility path.
Client authentication may include tenant API tokens, OAuth for partner applications, and signed service credentials. The OpenAPI document declares the final schemes.
GET /v1/storms
GET /v1/storms/{stormId}
GET /v1/storms/{stormId}/revisions
GET /v1/storms/{stormId}/revisions/{revision}
GET /v1/storms/{stormId}/evidence
GET /v1/storms/{stormId}/timeline
GET /v1/storms/{stormId}/swaths
GET /v1/storms/{stormId}/impacts
GET /v1/storms/{stormId}/reportsGET /v1/weather/sources
GET /v1/weather/sources/{source}
GET /v1/weather/source-health
GET /v1/weather/products
GET /v1/weather/alerts
GET /v1/weather/reportsThe tenant API should not expose provider-specific details unnecessarily.
GET /v1/properties
POST /v1/properties/search
GET /v1/properties/{propertyId}
GET /v1/properties/{propertyId}/impacts
GET /v1/properties/{propertyId}/weather-history
GET /v1/properties/{propertyId}/reports
GET /v1/properties/{propertyId}/activitiesGET /v1/impacts
GET /v1/impacts/{impactId}Common filters include storm, minimum hail, confidence, geography, property type, priority, and eligibility.
GET /v1/monitors
POST /v1/monitors
GET /v1/monitors/{monitorId}
PATCH /v1/monitors/{monitorId}
DELETE /v1/monitors/{monitorId}
GET /v1/alerts
GET /v1/alerts/{alertId}
POST /v1/alerts/{alertId}/acknowledgeGET /v1/action-plans
POST /v1/action-plans
GET /v1/action-plans/{planId}
POST /v1/action-plans/{planId}/approve
GET /v1/action-plans/{planId}/zones
GET /v1/action-plans/{planId}/assignmentsGET /v1/territories
POST /v1/territories
GET /v1/assignments
POST /v1/assignments
POST /v1/visits
GET /v1/visits/{visitId}
POST /v1/inspections
POST /v1/evidence
POST /v1/outcomesGET /v1/leads
POST /v1/leads
GET /v1/contacts
POST /v1/contacts
GET /v1/opportunities
POST /v1/opportunities
GET /v1/activities
POST /v1/activitiesGET /v1/campaigns
POST /v1/campaigns
GET /v1/campaigns/{campaignId}
POST /v1/campaigns/{campaignId}/approve
POST /v1/campaigns/{campaignId}/activate
GET /v1/campaigns/{campaignId}/performanceActivation enforces authorization and eligibility.
POST /v1/reports
GET /v1/reports
GET /v1/reports/{reportId}
GET /v1/reports/{reportId}/manifest
POST /v1/reports/{reportId}/shareCollection endpoints use one pagination strategy. Cursor pagination is preferable for large mutable collections:
{
"data": [],
"page": {
"next": "cursor_abc"
}
}Errors use stable machine-readable codes:
{
"error": {
"code": "campaign_not_eligible",
"message": "The campaign contains ineligible audience members.",
"details": {},
"requestId": "req_123"
}
}Mutations with expensive or externally visible side effects support idempotency. Examples include report generation, campaign creation, external sends, imports, and webhook replay.
Representative events include:
storm.created
storm.revised
storm.ended
impact.created
impact.updated
monitor.triggered
alert.created
action_plan.created
action_plan.approved
assignment.created
assignment.completed
inspection.completed
campaign.created
campaign.approved
campaign.activated
lead.created
opportunity.created
outcome.recorded
report.readyWebhook envelopes carry stable identity and versioning:
{
"id": "evt_123",
"type": "storm.revised",
"version": "1",
"createdAt": "2026-08-16T19:22:00Z",
"tenantId": "tenant_123",
"data": {}
}