Skip to content

API documentation

Last updated View as MarkdownAgent index

The StormTrust data service provides a versioned read boundary. Consumers do not depend on ingestion jobs, D1 tables, R2 keys, or Queue messages.

Deployed data read API

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/status

The 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.

Versioning

The deployed read contract uses:

/v1/

Backward-incompatible changes require a new major API version or a governed compatibility path.

Authentication

Client authentication may include tenant API tokens, OAuth for partner applications, and signed service credentials. The OpenAPI document declares the final schemes.

Storm endpoints

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}/reports

Weather endpoints

GET /v1/weather/sources
GET /v1/weather/sources/{source}
GET /v1/weather/source-health
GET /v1/weather/products
GET /v1/weather/alerts
GET /v1/weather/reports

The tenant API should not expose provider-specific details unnecessarily.

Property endpoints

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}/activities

Impact endpoints

GET /v1/impacts
GET /v1/impacts/{impactId}

Common filters include storm, minimum hail, confidence, geography, property type, priority, and eligibility.

Monitoring endpoints

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}/acknowledge

Action plan endpoints

GET  /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}/assignments

Field operations endpoints

GET  /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/outcomes

CRM endpoints

GET  /v1/leads
POST /v1/leads

GET  /v1/contacts
POST /v1/contacts

GET  /v1/opportunities
POST /v1/opportunities

GET  /v1/activities
POST /v1/activities

Campaign endpoints

GET  /v1/campaigns
POST /v1/campaigns
GET  /v1/campaigns/{campaignId}
POST /v1/campaigns/{campaignId}/approve
POST /v1/campaigns/{campaignId}/activate
GET  /v1/campaigns/{campaignId}/performance

Activation enforces authorization and eligibility.

Report endpoints

POST /v1/reports
GET  /v1/reports
GET  /v1/reports/{reportId}
GET  /v1/reports/{reportId}/manifest
POST /v1/reports/{reportId}/share

Pagination

Collection endpoints use one pagination strategy. Cursor pagination is preferable for large mutable collections:

{
	"data": [],
	"page": {
		"next": "cursor_abc"
	}
}

Errors

Errors use stable machine-readable codes:

{
	"error": {
		"code": "campaign_not_eligible",
		"message": "The campaign contains ineligible audience members.",
		"details": {},
		"requestId": "req_123"
	}
}

Idempotency

Mutations with expensive or externally visible side effects support idempotency. Examples include report generation, campaign creation, external sends, imports, and webhook replay.

Webhooks

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.ready

Webhook envelopes carry stable identity and versioning:

{
	"id": "evt_123",
	"type": "storm.revised",
	"version": "1",
	"createdAt": "2026-08-16T19:22:00Z",
	"tenantId": "tenant_123",
	"data": {}
}