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
apiKeyrequiredlatrequiredlonrequiredsourceoptionalaccuweatheraeris_weatherapple_weathercustom_weatherforecamockdefaultopen_weatherpirate_weatherthe_weather_companytomorrow_iovisual_crossingweatherbit
outputoptionalbasedefaultfull
unitsoptionalusdefaultsicaukm
Unit options
usdefault, United StatesprecipAccumulationinprecipIntensityinhrpressurembtemperaturefvisibilitymiwindSpeedmph
siInternationalprecipAccumulationcmprecipIntensitymmhrpressurehpatemperaturecvisibilitykmwindSpeedms
caCanadaprecipAccumulationcmprecipIntensitymmhrpressurehpatemperaturecvisibilitykmwindSpeedkmh
ukUnited KingdomprecipAccumulationcmprecipIntensitymmhrpressurehpatemperaturecvisibilitymiwindSpeedmph
mMetricprecipAccumulationcmprecipIntensitymmrpressurembtemperaturecvisibilitymwindSpeedkmh
Unit option overrides
precipAccumulationininchescmcentimeters
precipIntensityinhrinches per hourmmhrmillimeters per hour
pressurembmillibarshpahectopascalskpakilopascalsinhginches of mercurymmhgmillimeters of mercury
temperatureffahrenheitccelsiuskkelvin
visibilitymimileskmkilometersmmeters
windSpeedmphmiles per hourmsmeters per secondkmhkilometers per hourknknotsbftbeaufort
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.
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.
latitudelongitudetimezonesourcecurrentlyapparentTemperatureaqifullcloudCoverdewPointhumidityiconpressurepressureTrendfullsummarytimetemperatureuvIndexvisibilitywindBearingwindGustwindSpeed
minutelysummarydataprecipIntensityprecipTypetime
hourlysummarydataapparentTemperaturecloudCoverdewPointhumidityiconprecipAccumulationprecipIntensityprecipProbabilityprecipTypepressuresummarytemperaturetimeuvIndexvisibilitywindBearingwindGustfullwindSpeed
dailysummarydataapparentTemperatureMaxapparentTemperatureMinaqifullcloudCoverdewPointhumidityiconmoonPhasemoonPhaseNamefullpollenGrassfullpollenTreefullpollenWeedfullprecipAccumulationprecipIntensityprecipProbabilityprecipTypepressuresummarysunriseTimesunsetTimetemperatureMaxtemperatureMintimeuvIndexvisibilitywindBearingwindSpeed
alertstitledescriptiondetailsUrlfullsourcefull
Data Properties
latitudefloat- the latitude requested
longitudefloat- the longitude requested
timezonestring- IANA timezone for the location requested, e.g.
America/Chicago
- IANA timezone for the location requested, e.g.
sourcestring- data source name, e.g.
AccuWeather
- data source name, e.g.
currentlyobject- current weather conditions
minutelyobject- minute-by-minute forecast,
baseis limited to60minutes,fullis unbounded
- minute-by-minute forecast,
hourlyobject- hour-by-hour forecast,
baseis limited to48hours,fullis unbounded
- hour-by-hour forecast,
dailyobject- day-by-day forecast,
baseis limited to8days,fullis unbounded
- day-by-day forecast,
alertsarray- severe weather alerts
- If there are no alerts,
baseomits this property andfullreturns an empty array
Data Blocks
(minutely, hourly, daily)
summarystring- human-readable summary of the period
dataarray- data points for the period, in time order
Data Points
apparentTemperaturefloat- apparent ("feels like") temperature
apparentTemperatureMaxfloat- maximum apparent temperature
apparentTemperatureMinfloat- minimum apparent temperature
aqiinteger- US EPA Air Quality Index, between
0and500, inclusive
- US EPA Air Quality Index, between
apparentTemperatureMaxfloat- maximum apparent temperature
apparentTemperatureMinfloat- minimum apparent temperature
cloudCoverfloat- percentage of the sky covered by clouds, between
0and1, inclusive. (e.g.0.75)
- percentage of the sky covered by clouds, between
dewPointfloat- dew point temperature
humidityfloat- percentage of relative humidity (e.g.
0.50)
- percentage of relative humidity (e.g.
iconstring- machine-readable summary, suitable for selecting an icon for display
clear-dayclear-nightcloudyfogpartly-cloudy-daypartly-cloudy-nightrainsleetsnowwind
moonPhasefloat- fractional part of the lunation number for the day
moonPhaseNamestring- machine-readable name of the moon phase
NewWaxing CrescentFirst QuarterWaxing GibbousFullWaning GibbousLast QuarterWaning Crescent
pollenGrassinteger- level of grass pollen, between
0and5, inclusive
- level of grass pollen, between
pollenTreeinteger- level of tree pollen, between
0and5, inclusive
- level of tree pollen, between
pollenWeedinteger- level of weed pollen, between
0and5, inclusive
- level of weed pollen, between
precipAccumulationfloat- amount of snowfall accumulation
precipIntensityfloat- amount of liquid water, per hour
- to calculate the total rainfall for a day, multiply the
dailyvalue by24
precipProbabilityfloat- percentage probability of precipitation occurring (e.g.
0.35)
- percentage probability of precipitation occurring (e.g.
precipTypestring- type of precipitation occurring
rainsleetsnow
pressurefloat- air pressure
pressureTrendstring- air pressure trend
fallingrisingsteady
summarystring- human-readable summary
sunriseTimeinteger- UNIX local timestamp of when the sun will rise
sunsetTimeinteger- UNIX local timestamp of when the sun will set
temperaturefloat- air temperature
temperatureMaxfloat- maximum temperature
temperatureMinfloat- minimum temperature
timeinteger- UNIX local timestamp at the current time, or top of the period
uvIndexinteger- UV index
visibilityfloat- average visibility
windBearinginteger- direction the wind is coming from in degrees
windGustfloat- wind gust speed
windSpeedfloat- wind speed
Alerts
titlestring- brief description
descriptionstring- detailed description
detailsUrlstring- link to additional details
sourcestring- 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 GeoTZ.
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:
200OK- success
400Bad Request- invalid parameters, e.g. invalid source, disabled source, or invalid options
401Unauthorized- invalid Weather Machine API Key
407Proxy Authentication Required- invalid source credentials
429Too Many Requests- source rate limit error
500Internal Server Error- something went wrong with the Weather Machine
502Bad Gateway- source data error
504Gateway 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/abc123https://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.