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:
| Plan | Monthly requests | Activities | Premium output |
|---|---|---|---|
| Free | 500 | 3 | — |
| Builder | 10,000 | 4 | — |
| Professional | 100,000 | All 47 | ✓ |
| Business | 1,000,000 | All 47 | ✓ |
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
locationrequiredDenver), 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).activityrequiredstartsat, satnight, sun, sunnight, mon…frinight, tonight, today), an ISO date (2026-04-12 → 06:00 local), an ISO datetime (2026-04-12T14:00-06:00), or an integer hours from now (72).endwindow. ISO date defaults to 23:59 local.windowend. Defaults to 24 when start is set, 1 for current conditions.outputdata — raw weather periods + risk score (Builder+). ai — risk score + AI briefing, alert copy, email subject (Professional+). full — raw weather + risk + AI briefing (Professional+). Omit for risk score only. See Output Modes.Example request
# Current conditions (next 1 hour) curl "https://outdoor4cast.com/api/v1/risk?location=Salt+Lake+City,UT&activity=construction" \ -H "x-api-key: od4c_YOUR_KEY_HERE" # Named period curl "https://outdoor4cast.com/api/v1/risk?location=Denver,CO&activity=hiking&start=sat" \ -H "x-api-key: od4c_YOUR_KEY_HERE" # 48-hour window starting 72 hours from now curl "https://outdoor4cast.com/api/v1/risk?location=Miami,FL&activity=beach_volleyball&start=72&window=48" \ -H "x-api-key: od4c_YOUR_KEY_HERE" # Raw weather data + risk score (Builder+) curl "https://outdoor4cast.com/api/v1/risk?location=Denver,CO&activity=hiking&start=sat&output=data" \ -H "x-api-key: od4c_YOUR_KEY_HERE" # Full output with AI briefing (Professional+) curl "https://outdoor4cast.com/api/v1/risk?location=Denver,CO&activity=hiking&start=sat&output=full" \ -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-04-03T12:00:00.000Z",
"forecast_hours": 24,
"activity": "skiing",
"window_start": "2026-04-05T06:00:00-06:00",
"window_end": "2026-04-06T06:00:00-06:00",
"window_label": "Saturday",
"short_forecast": "Partly Cloudy",
"risk": {
"summary": {
"peak": { "score": 68, "level": "HIGH", "at": "2026-04-05T14:00:00-06:00" },
"average": { "score": 42, "level": "MODERATE" },
"recommendation": "DELAY",
"recommendation_note": "Peak risk HIGH at Sat Apr 5, 2pm. 34 mph gusts exceed Skiing / Snowboarding thresholds."
},
"factors": {
// Peak-period factors (as_of = peak period startTime)
"wind": { "score": 75, "value": "34 mph gusts", "exceeds_threshold": true },
"cold_stress": { "score": 10, "value": "18°F wind chill","exceeds_threshold": false },
"visibility": { "score": 60, "value": "0.4 mi", "exceeds_threshold": true },
"as_of": "2026-04-05T14:00:00-06:00"
},
"windows": [
{
"start": "2026-04-05T06:00:00-06:00", "end": "2026-04-05T07:00:00-06:00",
"level": "LOW", "score": 18,
"weather": {
"temperature_f": 62, "wind_speed_mph": 8, "wind_gust_mph": 12,
"humidity_pct": 42, "dewpoint_c": 8.1, "precip_pct": 5,
"wind_chill_f": 60, "wbgt_celsius": 18.2, "visibility_mi": 10.0,
"ceiling_ft": null, "sky_cover_pct": 20, "uv_index": 4,
"thunder_prob_pct": 0, "wave_height_ft": null, "haines_index": null,
"lightning_level": 0
}
// weather present only when output=data or output=full (Builder+)
},
{ "start": "2026-04-05T07:00:00-06:00", "end": "2026-04-05T08:00:00-06:00", "level": "MODERATE", "score": 35 },
// ... one entry per hour in the window
{ "start": "2026-04-05T14:00:00-06:00", "end": "2026-04-05T15:00:00-06:00", "level": "HIGH", "score": 68 }
],
"safe_windows": ["Sat Apr 5, 6am–8am", "Sat Apr 5, 10pm–6am"],
"danger_windows": ["Sat Apr 5, 12pm–4pm"],
"acclimatization_flag": false
},
"premium": {
"briefing": null, // populated when output=ai or 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/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", "roofing", "landscaping", "utilities", "survey",
"events", "sports", "golf", "photography", "hiking", "skiing",
"cycling", "climbing", "surfing", "agriculture", "forestry",
"fire_crew", "logistics", "trucking", "aviation_small",
"boating", "fishing", "marine_logistics",
"stargazing", "running", "trail_running", "camping", "hunting",
"beach", "outdoor_fitness", "concert_festival", "outdoor_dining",
"hot_air_balloon", "paragliding", "skydiving", "helicopter",
"kayaking", "whitewater", "open_water_swim",
"cross_country_ski", "snowmobile", "ice_fishing",
"crane_operation", "window_washing", "pipeline",
"solar_farm", "concrete_work"
]
}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
activityrequiredthresholdsrequiredThreshold fields
wind_gust_mphprecip_pcttemp_min_fvisibility_milightning_thresholdwave_height_ftsky_cover_pct_thresholduv_index_thresholdceiling_ft_thresholdthunder_prob_pct_thresholdExample 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.
| ID | Name | Minimum tier |
|---|---|---|
| construction | Construction / General | free |
| hiking | Hiking / Trail | free |
| events | Outdoor Events | free |
| landscaping | Landscaping | builder |
| agriculture | Agriculture / Farming | builder |
| roofing | Roofing | professional |
| utilities | Utilities / Linework | professional |
| survey | Land Survey | professional |
| forestry | Forestry / Logging | professional |
| fire_crew | Wildfire / Fire Crew | professional |
| logistics | Logistics / Delivery | professional |
| trucking | Trucking / CDL | professional |
| crane_operation | Crane Operation | professional |
| window_washing | High-Rise Window Washing | professional |
| pipeline | Pipeline / Field Inspection | professional |
| solar_farm | Solar Farm / Panel Installation | professional |
| concrete_work | Concrete Pouring / Finishing | professional |
| sports | Outdoor Sports / Practice | professional |
| golf | Golf | professional |
| photography | Outdoor Photography / Film | professional |
| skiing | Skiing / Snowboarding | professional |
| cycling | Cycling / Mountain Biking | professional |
| climbing | Rock Climbing | professional |
| running | Running / Road Race | professional |
| trail_running | Trail Running | professional |
| camping | Camping / Backpacking | professional |
| hunting | Hunting / Field Sports | professional |
| beach | Beach / Swimming | professional |
| outdoor_fitness | Outdoor Fitness / Training | professional |
| concert_festival | Concert / Festival | professional |
| outdoor_dining | Outdoor Dining / Patio | professional |
| stargazing | Stargazing / Astronomy | professional |
| aviation_small | Small Aircraft / Drone | professional |
| hot_air_balloon | Hot Air Balloon | professional |
| paragliding | Paragliding / Hang Gliding | professional |
| skydiving | Skydiving / BASE Jumping | professional |
| helicopter | Helicopter Operations | professional |
| surfing | Surfing / Paddle Sports | professional |
| boating | Boating / Sailing | professional |
| fishing | Fishing (Recreational) | professional |
| marine_logistics | Marine / Commercial Vessel | professional |
| kayaking | Kayaking / Canoeing | professional |
| whitewater | Whitewater Rafting | professional |
| open_water_swim | Open Water Swimming | professional |
| cross_country_ski | Cross-Country Skiing | professional |
| snowmobile | Snowmobile / Snow Machine | professional |
| ice_fishing | Ice Fishing | professional |
Risk Response Schema
The top-level response and risk object:
// Top-level response fields
{
"location": { "name": string, "lat": number, "lon": number, "resolution_note": string | null },
"generated_at": string, // ISO 8601
"forecast_hours": number,
"activity": string,
"window_start": string, // ISO 8601 — start of scored window
"window_end": string, // ISO 8601 — end of scored window
"window_label": string, // e.g. "Saturday" — only when start= is a named period or ISO date
"short_forecast": string, // e.g. "Partly Cloudy" — only when start= is a named period or ISO date
"risk": { ... },
"premium": { ... }
}
// risk object
"risk": {
"summary": {
"peak": { "score": number, "level": "LOW"|"MODERATE"|"HIGH"|"VERY_HIGH"|"EXTREME", "at": string },
"average": { "score": number, "level": "LOW"|"MODERATE"|"HIGH"|"VERY_HIGH"|"EXTREME" },
"recommendation": "PROCEED" | "CAUTION" | "DELAY" | "CANCEL",
"recommendation_note": string // human-readable explanation of peak risk drivers
},
"factors": {
// Peak-period factor scores — only active factors for the activity are included
"wind": { "score": number, "value": string, "exceeds_threshold": boolean },
"heat_stress": { "score": number, "value": string, "exceeds_threshold": boolean },
"cold_stress": { "score": number, "value": string, "exceeds_threshold": boolean },
"precipitation":{ "score": number, "value": string, "exceeds_threshold": boolean },
"snow_ice": { "score": number, "value": string, "exceeds_threshold": boolean },
"lightning": { "score": number, "value": string, "exceeds_threshold": boolean },
"visibility": { "score": number, "value": string, "exceeds_threshold": boolean },
"fire_weather": { "score": number, "value": string, "exceeds_threshold": boolean },
"waves": { "score": number, "value": string, "exceeds_threshold": boolean },
"sky_cover": { "score": number, "value": string, "exceeds_threshold": boolean },
"uv_index": { "score": number, "value": string, "exceeds_threshold": boolean },
"thunder_prob": { "score": number, "value": string, "exceeds_threshold": boolean },
"ceiling": { "score": number, "value": string, "exceeds_threshold": boolean },
"as_of": string // ISO 8601 — startTime of the peak-risk period
},
"windows": [
// One entry per hourly period in the window
{ "start": string, "end": string, "level": string, "score": number, "weather?": WeatherConditions }
// weather present when output=data or output=full (Builder+)
],
"safe_windows": string[], // e.g. ["Sat Apr 5, 6am–9am", "Sat Apr 5, 8pm–6am"]
"danger_windows": string[], // e.g. ["Sat Apr 5, 12pm–4pm"]
"acclimatization_flag": boolean
}The resolution_note on the location object is populated for precision-sensitive activities (aviation, marine) to note that weather data uses a ~2.5km grid.
Output Modes
The output parameter controls how much detail is returned. Omit it for a risk score only (available on all plans).
| output= | What you get | Min tier |
|---|---|---|
| (omitted) | Risk score, summary, factors, safe/danger windows | Free |
| data | Risk score + raw weather object on each window entry | Builder |
| ai | Risk score + AI briefing, alert copy, email subject | Professional |
| full | Risk score + raw weather + AI briefing | Professional |
AI briefing (output=ai or output=full)
Add output=ai or output=full 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&start=sat&output=ai" \ -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_KEYRATE_LIMIT_EXCEEDEDUPGRADE_REQUIREDPREMIUM_REQUIREDMISSING_PARAMINVALID_ACTIVITYINVALID_BODYLOCATION_NOT_FOUNDWEATHER_UNAVAILABLEINTERNAL_ERRORCode 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 [email protected] or sign in to your dashboard to manage your keys.