API Documentation

outdoor4cast provides activity-specific weather risk scores for outdoor operations. All endpoints return JSON.

Quick Start

Get a risk score for construction work in Denver in under a minute.

# 1. Sign up and create an API key at https://outdoor4cast.com/auth/sign-up

# 2. Make your first request
curl "https://outdoor4cast.com/api/v1/risk?location=Denver,CO&activity=construction" \
  -H "x-api-key: od4c_YOUR_KEY_HERE"

# Response
{
  "location": { "name": "Denver, CO", "lat": 39.74, "lon": -104.99, "resolution_note": null },
  "generated_at": "2026-03-29T12:00:00.000Z",
  "forecast_hours": 24,
  "activity": "construction",
  "risk": {
    "overall": { "score": 2, "label": "Low", "color": "green" },
    "factors": { ... },
    "active_alerts": []
  },
  "premium": { "briefing": null, "alert_copy": null, "email_subject": null }
}

Authentication

All requests must include your API key in the x-api-key header.

curl "https://outdoor4cast.com/api/v1/risk?location=..." \
  -H "x-api-key: od4c_YOUR_KEY_HERE"

API keys are prefixed with od4c_. Generate and manage keys at your dashboard. Each key is shown only once at creation — store it securely.

Base URL & Versioning

https://outdoor4cast.com/api/v1/

The current API version is v1. Breaking changes will be released under a new version prefix with a migration period.

Rate Limits

Monthly request limits by plan:

PlanMonthly requestsActivitiesPremium output
Free5003
Builder10,0004
Professional100,000All 17
Business1,000,000All 17

When you exceed your limit, requests return 429 RATE_LIMIT_EXCEEDED. Limits reset on a rolling monthly basis.

GET /api/v1/risk

Returns a weather risk score for a location and activity over a forecast window. Available on all plans.

Parameters

locationrequired
string
Location to query. Accepts many formats: city name (Denver), city + state (Denver, CO), ZIP code (84101), county (Salt Lake County, UT), lat/lon (39.74,-104.99), address (1600 Pennsylvania Ave NW, Washington DC), airport code (SLC or KSLC), or landmark / POI name (Zion National Park).
activityrequired
string
Activity profile ID. See Activities for available values and tier requirements.
hours
number
Forecast window in hours. Default 24, maximum 168 (7 days).
output
string
Set to full for AI-generated briefing, alert copy, and email subject line. Requires Professional tier or above. See Premium Output.

Example request

curl "https://outdoor4cast.com/api/v1/risk?location=Salt+Lake+City,UT&activity=skiing&hours=48" \
  -H "x-api-key: od4c_YOUR_KEY_HERE"

Example response

{
  "location": {
    "name": "Salt Lake City, UT",
    "lat": 40.76,
    "lon": -111.89,
    "resolution_note": null
  },
  "generated_at": "2026-03-29T12:00:00.000Z",
  "forecast_hours": 48,
  "activity": "skiing",
  "risk": {
    "overall": {
      "score": 4,           // 1 (low) – 5 (extreme)
      "label": "High",
      "color": "red"
    },
    "factors": {
      "wind":        { "score": 3, "label": "Moderate", "value": 28, "unit": "mph gust" },
      "cold_stress": { "score": 2, "label": "Low",      "value": 18, "unit": "°F" },
      "snow_ice":    { "score": 4, "label": "High",     "value": 8,  "unit": "in expected" },
      "visibility":  { "score": 3, "label": "Moderate", "value": 0.4,"unit": "mi" }
    },
    "active_alerts": [
      {
        "event": "Winter Storm Warning",
        "severity": "Extreme",
        "headline": "Heavy snow expected overnight...",
        "expires": "2026-03-30T06:00:00Z"
      }
    ]
  },
  "premium": {
    "briefing": null,       // populated when output=full (Professional+)
    "alert_copy": null,
    "email_subject": null
  }
}

GET /api/v1/alerts

Returns active NWS weather alerts for a location. Available on all plans.

Parameters

locationrequired
string
Location to query. Same format as /risk.

Example request

curl "https://outdoor4cast.com/api/v1/alerts?location=Miami,FL" \
  -H "x-api-key: od4c_YOUR_KEY_HERE"

Example response

{
  "location": { "name": "Miami, FL", "lat": 25.77, "lon": -80.19 },
  "retrieved_at": "2026-03-29T12:00:00.000Z",
  "alerts": [
    {
      "event": "Rip Current Statement",
      "severity": "Moderate",
      "headline": "Dangerous rip currents expected at area beaches.",
      "description": "...",
      "instruction": "...",
      "expires": "2026-03-30T00:00:00Z"
    }
  ]
}

Returns an empty alerts array when no alerts are active. Alert data is sourced from the National Weather Service and cached hourly.

GET /api/v1/settings/thresholds

Returns the custom risk thresholds currently set on your API key, plus all available activity IDs. Requires Professional tier or above.

Example request

curl "https://outdoor4cast.com/api/v1/settings/thresholds" \
  -H "x-api-key: od4c_YOUR_KEY_HERE"

Example response

{
  "custom_thresholds": {
    "construction": {
      "wind_gust_mph": 35,
      "precip_pct": 50
    }
  },
  "available_activities": [
    "construction", "landscaping", "hiking", "events", "skiing",
    "cycling", "climbing", "surfing", "agriculture", "forestry",
    "fire_crew", "logistics", "trucking", "aviation_small",
    "boating", "fishing", "marine_logistics"
  ]
}

PUT /api/v1/settings/thresholds

Saves custom risk thresholds for a specific activity on your API key. These override the default thresholds when scoring risk for that activity. Requires Professional tier or above.

Request body

activityrequired
string
Activity profile ID to customize. Must be a valid activity ID.
thresholdsrequired
object
Key-value pairs of threshold names and numeric values. Only include fields you want to override — unspecified fields use the activity default.

Threshold fields

wind_gust_mph
number
Wind gust speed in mph that triggers elevated risk
precip_pct
number
Precipitation probability % threshold
temp_min_f
number
Minimum temperature in °F below which risk increases
visibility_mi
number
Visibility in miles below which risk increases
lightning_threshold
number
Lightning flash count per hour (where applicable)
wave_height_ft
number
Wave height in feet (marine/water industries only)

Example request

curl -X PUT "https://outdoor4cast.com/api/v1/settings/thresholds" \
  -H "x-api-key: od4c_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "activity": "construction",
    "thresholds": {
      "wind_gust_mph": 35,
      "precip_pct": 50
    }
  }'

Example response

{
  "activity": "construction",
  "thresholds": { "wind_gust_mph": 35, "precip_pct": 50 },
  "message": "Custom thresholds saved"
}

Activities

Pass the ID string in the activity parameter. Access depends on your plan tier.

IDNameMinimum tier
constructionConstruction / General Contractorfree
hikingHiking / Trail Runningfree
eventsOutdoor Eventsfree
landscapingLandscaping / Grounds Maintenancebuilder
agricultureAgriculture / Farmingbuilder
skiingSkiing / Snowboardingprofessional
cyclingCycling / Mountain Bikingprofessional
climbingRock Climbingprofessional
surfingSurfing / Paddle Sportsprofessional
forestryForestry / Loggingprofessional
fire_crewWildfire / Fire Crewprofessional
logisticsLogistics / Deliveryprofessional
truckingTrucking / CDLprofessional
aviation_smallSmall Aircraft / Droneprofessional
boatingBoating / Sailingprofessional
fishingFishing (Recreational)professional
marine_logisticsMarine / Commercial Vesselprofessional

Risk Response Schema

The risk object in the /risk response:

"risk": {
  "overall": {
    "score": 1 | 2 | 3 | 4 | 5,
    "label": "Low" | "Moderate" | "High" | "Very High" | "Extreme",
    "color": "green" | "yellow" | "orange" | "red" | "purple"
  },
  "factors": {
    // Only factors relevant to the activity are included
    "wind":        { "score": number, "label": string, "value": number, "unit": "mph gust" },
    "heat_stress": { "score": number, "label": string, "value": number, "unit": "°F feels-like" },
    "cold_stress": { "score": number, "label": string, "value": number, "unit": "°F" },
    "precipitation":{ "score": number, "label": string, "value": number, "unit": "% chance" },
    "snow_ice":    { "score": number, "label": string, "value": number, "unit": "in expected" },
    "lightning":   { "score": number, "label": string, "value": number, "unit": "flashes/hr" },
    "visibility":  { "score": number, "label": string, "value": number, "unit": "mi" },
    "fire_weather":{ "score": number, "label": string, "value": number, "unit": "index" },
    "waves":       { "score": number, "label": string, "value": number, "unit": "ft" }
  },
  "active_alerts": [
    {
      "event": string,
      "severity": "Minor" | "Moderate" | "Severe" | "Extreme",
      "headline": string,
      "description": string,
      "instruction": string | null,
      "expires": string   // ISO 8601
    }
  ]
}

The resolution_note on the location object is populated for precision-sensitive industries (aviation, marine) to note that weather data uses a ~2.5km grid.

Premium Output

Add output=full to a /risk request to receive an AI-generated briefing alongside the risk score. Requires Professional tier or above.

curl "https://outdoor4cast.com/api/v1/risk?location=Denver,CO&activity=construction&output=full" \
  -H "x-api-key: od4c_YOUR_KEY_HERE"

The premium object in the response is populated:

"premium": {
  "briefing": "Moderate risk for outdoor construction today. Wind gusts to 28 mph expected
               between 2–6 PM. Morning work is clear; consider suspending crane operations
               and elevated work after midday.",
  "alert_copy": "⚠️ Wind Advisory in effect 2 PM–8 PM. Secure loose materials.",
  "email_subject": "Construction Risk Update: Moderate — Denver CO, March 29"
}

Briefings are cached for 6 hours per location/activity combination to minimize latency.

Custom Thresholds

Professional and Business subscribers can override the default risk thresholds for any activity to match their specific operational requirements. Thresholds are stored on your API key and applied automatically on every /risk request.

For example, a construction company that operates safely up to 35 mph gusts (vs. the default 25 mph) can set a custom threshold so wind only elevates risk at their actual operational limit:

# Set custom wind threshold for construction
curl -X PUT "https://outdoor4cast.com/api/v1/settings/thresholds" \
  -H "x-api-key: od4c_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{"activity": "construction", "thresholds": {"wind_gust_mph": 35}}'

# Subsequent /risk calls now use wind_gust_mph: 35 for this key
curl "https://outdoor4cast.com/api/v1/risk?location=Denver,CO&activity=construction" \
  -H "x-api-key: od4c_YOUR_KEY_HERE"

Error Codes

All errors return JSON with an error object:

{
  "error": {
    "code": "UPGRADE_REQUIRED",
    "message": "Builder tier supports: construction, landscaping, agriculture, events. Upgrade to Professional for all activities.",
    "docs": "https://outdoor4cast.com/docs#UPGRADE_REQUIRED"
  }
}
INVALID_API_KEY
401
Missing, invalid, or deactivated API key.
RATE_LIMIT_EXCEEDED
429
Monthly request limit reached for your plan. Resets on your billing cycle date.
UPGRADE_REQUIRED
403
The requested activity or feature requires a higher plan tier.
PREMIUM_REQUIRED
403
output=full requires Professional tier or above.
MISSING_PARAM
422
A required query parameter is missing.
INVALID_ACTIVITY
422
The activity ID is not recognized.
INVALID_BODY
422
Request body is not valid JSON (PUT /settings/thresholds).
LOCATION_NOT_FOUND
422
The location could not be geocoded. Try a more specific location string.
WEATHER_UNAVAILABLE
503
The NWS weather data service is temporarily unavailable. Retry after a short delay.
INTERNAL_ERROR
500
An unexpected server-side error occurred. Contact support if it persists.

Code Examples

JavaScript / fetch

const response = await fetch(
  'https://outdoor4cast.com/api/v1/risk?location=Denver,CO&activity=construction',
  { headers: { 'x-api-key': 'od4c_YOUR_KEY_HERE' } }
);
const data = await response.json();

if (!response.ok) {
  console.error(data.error.code, data.error.message);
} else {
  console.log(`Risk: ${data.risk.overall.label} (${data.risk.overall.score}/5)`);
}

Python

import httpx

resp = httpx.get(
    "https://outdoor4cast.com/api/v1/risk",
    params={"location": "Denver, CO", "activity": "construction"},
    headers={"x-api-key": "od4c_YOUR_KEY_HERE"},
)
resp.raise_for_status()
data = resp.json()
print(f"Risk: {data['risk']['overall']['label']} ({data['risk']['overall']['score']}/5)")

Node.js (full workflow)

import { createClient } from '@/lib/outdoor4cast'; // example wrapper

const client = createClient({ apiKey: process.env.OUTDOOR4CAST_API_KEY });

// Get risk score
const risk = await client.risk({ location: 'Denver, CO', activity: 'construction' });

// Get active alerts
const alerts = await client.alerts({ location: 'Denver, CO' });

// Set custom thresholds (Professional+)
await client.setThresholds({
  activity: 'construction',
  thresholds: { wind_gust_mph: 35, precip_pct: 50 },
});

Need help?

Email support@outdoor4cast.com or sign in to your dashboard to manage your keys.