Docs
Introduction
Weather Machine is an easy to use, universal adapter for the world’s most powerful forecast APIs.
You can use the Weather Machine with a simple JSON request, or use GraphQL for conditional fetching of specific data points.
How it works
Dark Sky’s single-response JSON format set the standard for developer friendliness: you could make just one request and get all the forecast info you need. Most other data providers require hitting multiple API endpoints and collating the responses to get similar results.
Weather Machine makes those other providers work like Dark Sky. It automatically fetches data from multiple endpoints in parallel, leveraging an advanced forecast-aware caching system to increase speed and reduce data usage along the way. The upstream responses are then collated, and each data point is run through a unit conversion layer. Finally, the data is returned as a single, well-formatted JSON response.
If you need more flexibility, all of the same systems are in place for our GraphQL API. With this approach, you’ll be able to fully customize the response format using GraphQL’s aliases, fragments, and variables. The GraphQL interface also supports conditional fetching, which means you only request the data points you need, without sacrifing the benefits of parallelization, unit conversion, and caching.
Regardless of which interface you choose, Weather Machine gives you one straightforward way to access forecasts from the world’s most powerful weather data providers, without needing to build custom implementations for each one. It’ll save you time, money, and provide a better level of service for your customers.
JSON API
There are two ways to access the JSON API.
First, a drop-in compatible /forecast
URL where the apiKey
, latitude
, and longitude
are part of the path, just like Dark Sky:
https://weathermachine.io/forecast/abc123/41.87,-87.62
Second, an /api
URL where all options are provided as query params:
https://weathermachine.io/api?apiKey=abc123&lat=41.87&lon=-87.62
Query Parameters
apiKey
requiredlat
requiredlon
requiredsource
optionalaccuweather
aeris_weather
apple_weather
custom_weather
foreca
mock
defaultopen_weather
pirate_weather
the_weather_company
tomorrow_io
visual_crossing
weatherbit
output
optionalbase
defaultfull
units
optionalus
defaultsi
ca
uk
m
Unit options
us
default, United StatesprecipAccumulation
inprecipIntensity
inhrpressure
mbtemperature
fvisibility
miwindSpeed
mph
si
InternationalprecipAccumulation
cmprecipIntensity
mmhrpressure
hpatemperature
cvisibility
kmwindSpeed
ms
ca
CanadaprecipAccumulation
cmprecipIntensity
mmhrpressure
hpatemperature
cvisibility
kmwindSpeed
kmh
uk
United KingdomprecipAccumulation
cmprecipIntensity
mmhrpressure
hpatemperature
cvisibility
miwindSpeed
mph
m
MetricprecipAccumulation
cmprecipIntensity
mmrpressure
mbtemperature
cvisibility
mwindSpeed
kmh
Unit option overrides
precipAccumulation
in
inchescm
centimeters
precipIntensity
inhr
inches per hourmmhr
millimeters per hour
pressure
mb
millibarshpa
hectopascalskpa
kilopascalsinhg
inches of mercurymmhg
millimeters of mercury
temperature
f
fahrenheitc
celsiusk
kelvin
visibility
mi
mileskm
kilometersm
meters
windSpeed
mph
miles per hourms
meters per secondkmh
kilometers per hourkn
knotsbft
beaufort
Here’s an example request where we’re fetching data from accuweather
using us
units, and overriding windSpeed
to be returned in knots
:
https://weathermachine.io/forecast/abc123/41.87,-87.62?source=accuweather&units=us&windSpeed=kn
Here’s the equivalent, using the /api
endpoint:
https://weathermachine.io/api?apiKey=abc123&lat=41.87&lon=-87.62&source=accuweather&units=us&windSpeed=kn
GraphQL API
Because GraphQL requests specify the fields to be returned, our system can optimize and minimize the number of requests made to the upstream data sources. And since data sources typically charge per request, our conditional fetching system reduces data transfer, increases speed, and saves you money.
The easiest way to explore the GraphQL API is with a web-based client like GraphiQL:
From here, you can browse the schema and make requests. Here’s an example query where the arguments match the JSON examples above:
query {
weather(
apiKey: "abc123",
lat: 41.87,
lon: -87.62,
source: accuweather,
units: us,
windSpeed: kn
) {
currently {
temperature
windSpeed
}
daily {
data {
temperatureMax
temperatureMin
}
}
}
}
When you’re ready to integrate with your app, you can select a GraphQL client and use the endpoint here:
https://weathermachine.io/graphql
Response Format
Both the JSON and GraphQL API return data in the same Dark Sky compatible format.
If you’re using the JSON API, you can request full
output, which will include additional data points where available such as aqi
and pollen
. If you’re using the GraphQL API, you can request only the fields you need.
latitude
longitude
timezone
source
currently
apparentTemperature
aqi
fullcloudCover
dewPoint
humidity
icon
pressure
pressureTrend
fullsummary
time
temperature
uvIndex
visibility
windBearing
windGust
windSpeed
minutely
summary
data
precipIntensity
precipType
time
hourly
summary
data
apparentTemperature
cloudCover
dewPoint
humidity
icon
precipAccumulation
precipIntensity
precipProbability
precipType
pressure
summary
temperature
time
uvIndex
visibility
windBearing
windGust
fullwindSpeed
daily
summary
data
apparentTemperatureMax
apparentTemperatureMin
aqi
fullcloudCover
dewPoint
humidity
icon
moonPhase
moonPhaseName
fullpollenGrass
fullpollenTree
fullpollenWeed
fullprecipAccumulation
precipIntensity
precipProbability
precipType
pressure
summary
sunriseTime
sunsetTime
temperatureMax
temperatureMin
time
uvIndex
visibility
windBearing
windSpeed
alerts
title
description
detailsUrl
fullsource
full
Data Properties
latitude
float- the latitude requested
longitude
float- the longitude requested
timezone
string- IANA timezone for the location requested, e.g.
America/Chicago
- IANA timezone for the location requested, e.g.
source
string- data source name, e.g.
AccuWeather
- data source name, e.g.
currently
object- current weather conditions
minutely
object- minute-by-minute forecast,
base
is limited to60
minutes,full
is unbounded
- minute-by-minute forecast,
hourly
object- hour-by-hour forecast,
base
is limited to48
hours,full
is unbounded
- hour-by-hour forecast,
daily
object- day-by-day forecast,
base
is limited to8
days,full
is unbounded
- day-by-day forecast,
alerts
array- severe weather alerts
- If there are no alerts,
base
omits this property andfull
returns an empty array
Data Blocks
(minutely
, hourly
, daily
)
summary
string- human-readable summary of the period
data
array- data points for the period, in time order
Data Points
apparentTemperature
float- apparent ("feels like") temperature
apparentTemperatureMax
float- maximum apparent temperature
apparentTemperatureMin
float- minimum apparent temperature
aqi
integer- US EPA Air Quality Index, between
0
and500
, inclusive
- US EPA Air Quality Index, between
apparentTemperatureMax
float- maximum apparent temperature
apparentTemperatureMin
float- minimum apparent temperature
cloudCover
float- percentage of the sky covered by clouds, between
0
and1
, inclusive. (e.g.0.75
)
- percentage of the sky covered by clouds, between
dewPoint
float- dew point temperature
humidity
float- percentage of relative humidity (e.g.
0.50
)
- percentage of relative humidity (e.g.
icon
string- machine-readable summary, suitable for selecting an icon for display
clear-day
clear-night
cloudy
fog
partly-cloudy-day
partly-cloudy-night
rain
sleet
snow
wind
moonPhase
float- fractional part of the lunation number for the day
moonPhaseName
string- machine-readable name of the moon phase
New
Waxing Crescent
First Quarter
Waxing Gibbous
Full
Waning Gibbous
Last Quarter
Waning Crescent
pollenGrass
integer- level of grass pollen, between
0
and5
, inclusive
- level of grass pollen, between
pollenTree
integer- level of tree pollen, between
0
and5
, inclusive
- level of tree pollen, between
pollenWeed
integer- level of weed pollen, between
0
and5
, inclusive
- level of weed pollen, between
precipAccumulation
float- amount of snowfall accumulation
precipIntensity
float- amount of liquid water, per hour
- to calculate the total rainfall for a day, multiply the
daily
value by24
precipProbability
float- percentage probability of precipitation occurring (e.g.
0.35
)
- percentage probability of precipitation occurring (e.g.
precipType
string- type of precipitation occurring
rain
sleet
snow
pressure
float- air pressure
pressureTrend
string- air pressure trend
falling
rising
steady
summary
string- human-readable summary
sunriseTime
integer- UNIX local timestamp of when the sun will rise
sunsetTime
integer- UNIX local timestamp of when the sun will set
temperature
float- air temperature
temperatureMax
float- maximum temperature
temperatureMin
float- minimum temperature
time
integer- UNIX local timestamp at the current time, or top of the period
uvIndex
integer- UV index
visibility
float- average visibility
windBearing
integer- direction the wind is coming from in degrees
windGust
float- wind gust speed
windSpeed
float- wind speed
Alerts
title
string- brief description
description
string- detailed description
detailsUrl
string- link to additional details
source
string- source name for use in attribution
Additional Info
By default, we allow up to 2 seconds for a data source to respond before throwing a timeout error. However, note that we monitor p99 origin latency and may increase timeouts on a per-source basis up to 5 seconds.
Some data points may not be available from all sources, and will return null
when missing. If a source doesn’t provide the location’s timezone it will be fetched from GeoNames
or TimeZoneDB
.
We don’t yet support all of the data points and options provided by Dark Sky. However, the features we do support are fully compatible with Dark Sky, and we intend to expand support over time. If you need a data point or option that we haven’t covered yet, please get in touch!
Handling Errors
The JSON API typically returns an HTTP 200 OK
response, but may return different HTTP status codes and responses if something goes wrong:
200
OK- success
400
Bad Request- invalid parameters, e.g. invalid source, disabled source, or invalid options
401
Unauthorized- invalid Weather Machine API Key
407
Proxy Authentication Required- invalid source credentials
429
Too Many Requests- source rate limit error
500
Internal Server Error- something went wrong with the Weather Machine
502
Bad Gateway- source data error
504
Gateway Timeout- source timeout
Note that the GraphQL API will always return a 200 OK
response unless there’s a 500 Internal Server Error
. For a successful response, the data
object will contain the requested fields. In the case of an error or timeout, the data
object will be null
and the errors
object will contain description matching the JSON API.
{
"data": null,
"errors": [{ "message": "Gateway Timeout: source timeout" }]
}
Authentication
To begin using the Weather Machine, sign up for an account and visit the Dashboard to view your API key:
You’ll use your API key to authenticate requests so they’re associated with your account. Your API key can be provided in a few different ways:
- JSON API
https://weathermachine.io/forecast/abc123
https://weathermachine.io/api?apiKey=abc123
- GraphQL API
query { weather(apiKey: "abc123") }
- HTTP Header
Authorization: Bearer abc123
The HTTP Header method works for both the JSON and GraphQL APIs.
Adding Sources
When you’re getting started, you can experiment with the "Mock" source, which returns static data. When you’re ready to use real data sources, you’ll need to enable them on your account:
If you’re already using a weather data provider for your application, simply add your data provider’s credentials to your Weather Machine account.
If you don’t have a data provider yet, you’ll need to sign up for one first and then add it to your Weather Machine account.
Rest assured that your credentials are encrypted, never accessed without your prior authorization, and never shared between accounts.
Monitoring Usage
You can monitor your usage and cache hit ratio across all sources, or drill down to individual sources by month and day. Usage data is updated every 15 minutes.
Weather Machine caches the responses received from data sources into static time buckets. For example, we cache hourly
data until the end of the current hour. The logic works as follows:
currently and alerts (max: 15 minutes)
- beginning of current hour + a sliding 15 minute "bucket"
- (
:00
,:15
,:30
,:45
)
minutely (max: 1 minute)
- beginning of current minute + 1 minute
hourly (max: 1 hour)
- beginning of current hour + 1 hour
daily (max: 3 hours)
- beginning of the current day + a sliding 3 hour "bucket"
- (
00:
,03:
,06:
,09:
,12:
,15:
,18:
,21:
)
weekly (max: 1 week)
- current time + 1 week
By default, latitude and longitude are rounded to 3 decimal places to optimally balance cacheability and accuracy. This allows for precision of approximately 111 meters, 365 feet, or about the size of a city block.
Weather Machine’s caching system is designed to be fast, effective, and fair to both our customers and data sources. All data caches are segmented by customer, and customers can only access data from their own cache.
Data Attribution
You’re not required to provide attribution to Weather Machine, but it’s always appreciated. Simply link to weathermachine.io and feel free to use the logo at the top of this page.
Most weather data sources have strict attribution requirements, so make sure to review their terms of service. We do our best to provide relevant links on the source pages where possible, but of course you’ll need to abide by any terms you’ve agreed to with them.
Contact Us
We’re excited to share Weather Machine with you, and we’re just getting started. Please let us know if you have any questions or comments. Missing a data point? Missing a data source? Want to work with us? Please don’t hesitate to get in touch.