Effective Immediately

Use of the Weatherstem API that we deem outside of best practices will result in immediate suspension of access to the API.

Add Weatherstem data to your web pages and applications using its Application Programming Interface.

The API is easy to use. You just need knowledge of:

Also, take a look at our Media Usage Guidelines.

We have a lesson about using the API in our curriculum repository.

You also need an API key which you get automatically when you register with Weatherstem.

The Weatherstem API Endpoint

All calls to the Weatherstem API are made to: https://api.weatherstem.com/api

Calling the API

Your API call can be made in any language and will include a JSON object communicating the data you want.

The call can be made via HTTP POST or GET (and JSONP is supported).

API calls can retrieve either current or historical data.

To make a call for data to the Weatherstem API, you have to send a request in the form of a JSON object.

The JSON object is passed as a String to the Weatherstem API in one of three ways:

  1. As the message body of an HTTP POST
  2. As a parameter named input of an HTTP POST
  3. As a URI-encoded parameter named input of an HTTP GET (include a parameter named callback for JSONP)

Example JSON string for current data

	"api_key" : "### your API key ###" , 
	"stations" : ["fsu@leon.weatherstem.com"]

Example JSON string for historic data (single point)

	"api_key" : "### your API key ###" , 
	"stations" : ["fsu@leon.weatherstem.com"],
	"at" : "2014-05-08 10:00:00"

Example JSON string for historic data (range)

	"api_key" : "### your API key ###" , 
	"stations" : [ "fsu@leon.weatherstem.com" ],
	"from" : "2014-05-08 10:00:00",
	"to" : "2014-05-08 10:10:00",
	"sensors" : [ "Thermometer" , "Hygrometer" , "Anemometer" ],

Example JSON string to list all stations in domain

	"api_key" : "### your API key ###"


  • The items in the stations array are the IDs of the stations whose data you want to pull.
  • A station ID can be determined from its web address, for example, a station of https://leon.weatherstem.com/fsu has an ID of fsu@leon.weatherstem.com.
  • In a historical lookup, if you omit the to property, the current date and time will be used.

Calls to the API return a JSON structure.

Example current data

The call
	"api_key" : "### your API key ###" , 
	"stations" : ["fsu@leon.weatherstem.com"]
The response

Example historic data

The call
	"api_key" : "### your API key ###" , 
	"stations" : ["fsu@leon.weatherstem.com"],
	"from" : "2014-04-01 18:00:00",
	"to" : "2014-04-01 18:20:00",
	"sensors" : ["Thermometer","Hygrometer","Anemometer"]	
The response

ActionScript 3

package {

	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import JSON;
	public class Weatherstem {
		public function Weatherstem() {
			var obj:Object = { api_key : "### your API key ###", stations : ["fsu@leon.weatherstem.com"] };
			var jsonString:String = JSON.stringify(obj);
			var loader:URLLoader = new URLLoader();
			var request:URLRequest = new URLRequest("//api.weatherstem.com/api");
			request.method = URLRequestMethod.POST;
			var vars:URLVariables = new URLVariables();
			vars.input = jsonString;
			request.data = vars;
		private function handler(event:Event):void {	
			var loader:URLLoader = URLLoader(event.target);
			var jsonString:String = loader.data as String;
			var obj = JSON.parse(jsonString);


 curl -X POST https://leon.weatherstem.com/api \
      --data-urlencode 'input={"api_key":"### your API key ###","stations":["fsu@leon.weatherstem.com"]}'


using System.Net.Http;

using (var client = new HttpClient())
    var values = new List<KeyValuePair<string, string>>();
    values.Add(new KeyValuePair<string, string>("input", "{'stations':['fsu@leon.weatherstem.com'],'api_key':'### your API key ###'}"));

    var content = new FormUrlEncodedContent(values);

    var response = await client.PostAsync("https://api.weatherstem.com/api", content);

    var responseString = await response.Content.ReadAsStringAsync();


package main
func main() {
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify : true},
	client := &http.Client{Transport: tr}
	apiUrl := "https://api.weatherstem.com/api"
	vars := (`{"api_key":"### your API key ###","stations":["fsu@leon.weatherstem.com"]}`)
	b := strings.NewReader(vars)
	resp, err := client.Post(apiUrl, "application/json", b)
	if err != nil {
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	fmt.Printf("%s\n", string(body))


package com.weatherstem;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class Weatherstem {
	private final String USER_AGENT = "Mozilla/5.0";
	public static void main(String[] args) throws Exception {
		Weatherstem http = new Weatherstem();
	// HTTP POST request
	private void sendPost() throws Exception {
		String url = "https://api.weatherstem.com/api";
		URL obj = new URL(url);
		HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
		//add reuqest header
		con.setRequestProperty("User-Agent", USER_AGENT);
		con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
 		String urlParameters = "input={api_key:'### your API key ###',stations:['fsu@leon.weatherstem.com']}";
		// Send post request
		DataOutputStream wr = new DataOutputStream(con.getOutputStream());
		int responseCode = con.getResponseCode();
		BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
		String inputLine;
		StringBuffer response = new StringBuffer();
		while ((inputLine = in.readLine()) != null) {
		//print result


	type: "POST",
	url: "//" + api + ".weatherstem.com/api",
	data: JSON.stringify({ api_key : "### your API key ###", stations : ["fsu@leon.weatherstem.com"] }),
	dataType: "json",
	success: function(responseData, textStatus, jqXHR) {
		if (responseData.error) {
			return alert('An error was encountered: ' + responseData.error);
	error: function(responseData, textStatus, errorThrown) {
		alert(responseData + ':' + errorThrown);


		<title>JSONP Example</title>
		<!-- input param is a URI escaped JSON string -->
		<script src="//api.weatherstem.com/api?input=%7B%22stations%22%3A%5B%22fsu@leon.weatherstem.com%22%5D%2C%22api_key%22%3A%22### your API key ###%22%7D&callback=myCallback"></script>
			function myCallback(data) {
				var objString = unescape(data);

Objective C

// send the request.  Your class must be a NSURLConnectionDelegate

    // json data...
    NSData* postData= [@"{\"api_key\": \"### your API key ###\",\"stations\": [\"fsu@leon.weatherstem.com\"]}" dataUsingEncoding:NSUTF8StringEncoding];
    NSString *tString = @"https://api.weatherstem.com/api";
    NSURL* url = [NSURL URLWithString:tString];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"POST"];
    [request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:postData];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
    [connection start];

// initialize the buffer
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    _responseData = [[NSMutableData alloc] init];

// fill the buffer
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [_responseData appendData:data];

// put the result in a dictionary and send it to the console
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSError *localError = nil;
    NSDictionary *parsedObject = [NSJSONSerialization JSONObjectWithData:_responseData options:0 error:&localError];
    NSLog( @"%@", parsedObject );




use strict;
use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
my $ua = LWP::UserAgent->new();
my $url = 'https://api.weatherstem.com/api';

my $vars = { input => '{"stations":["fsu@leon.weatherstem.com"],"api_key":"### your API key ###"}'};

my $req = POST $url, $vars;
my $content = $ua->request($req)->content;


$url = 'https://api.weatherstem.com/api';
$vars = array(
	"stations"    => array("fsu@leon.weatherstem.com"),
	"api_key"     =>"### your API key ###"
$options = array(
	'http'    => array(
	'method'    => 'POST',
	'content'   => json_encode( $vars ),
	'header'    =>  "Content-Type: application/json\r\n" .
					"Accept: application/json\r\n"
$context  = stream_context_create( $options );
$result = file_get_contents( $url, false, $context );
$response = json_decode( $result );


import urllib2,json

url = 'https://api.weatherstem.com/api'
indata = {'api_key':'### your API key ###','stations':['fsu@leon.weatherstem.com']}

request = urllib2.Request(url)
outdata = json.dumps(indata)
response = urllib2.urlopen(request,outdata)

print json.load(response)


#!/usr/bin/env ruby
require 'uri'
require 'json'
require 'net/http'
require 'net/https'
uri             = URI.parse("https://api.weatherstem.com/api")
https           = Net::HTTP.new(uri.host, uri.port)
https.use_ssl   = true
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
@vars    = {
    "api_key"   => "### your API key ###",
    "stations"  => ["fsu@leon.weatherstem.com"]
req = Net::HTTP::Post.new(uri.path, initheader = {'Content-Type' => 'application/json'})
.body = @vars
response = https.request(req)
puts "Response #{response.code} #{response.message}: #{response.body}"


public class Weatherstem : NSObject {

	public static func get_data(url:String, params _params:[String:String]?, handler:(String?) -> ()) {
		let nsurl:NSURL = NSURL(string : url)!
		let session:NSURLSession = NSURLSession.sharedSession()
		request.HTTPMethod = "POST"
		request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
		var params:String = ""
		if let _params = _params {
			for(key,value) in _params {
				params += key + "=" + value + "&"
			if params != "" {
				params = String(params.characters.dropLast())
		request.HTTPBody = params.dataUsingEncoding(NSUTF8StringEncoding)
		let task = session.dataTaskWithRequest(request) {
			(let data:NSData?, let response:NSURLResponse?, let error:NSError?) in
			guard error == nil else {
			var data_string:NSString = ""
			if let data = data {
				data_string = NSString(data: data, encoding: NSUTF8StringEncoding)!
				return handler(data_string as String)


let json:String = "{'api_key','### your API key ###','stations':['fsu@leon.weatherstem.com']}"
let params:[String:String] = ["input":json]

Weatherstem.get_data("https://api.weatherstem.com/api",params:params, handler:{
	(data:String?) -> () in

The Weatherstem JavaScript component (based on JQuery) is a way to add current data to your page with no programming.


<!DOCTYPE html>
		<title>The temperature</title>
		<!-- JQuery is required for the Weatherstem component to work -->
		<script src="//code.jquery.com/jquery-latest.min.js"></script>
		<!-- Weatherstem API component must be included AFTER JQuery include -->
		<script src="//static.weatherstem.com/api.min.js"></script>
		<!-- You must include your API key -->
		<meta name="Weatherstem-api-key" content="### your API key ###"/>
		<!-- This sets the station scope for the page -->
		<meta name="Weatherstem-station" content="leon/fsu"/>
		<!-- data-sensor can be the value of any supported sensor -->
		The current temperature is <span data-sensor="Thermometer"></span>° F.


  • You can download the source of the component and modify it at will.
  • The station scope set in the META tag is of the form domain handle/station handle, for example, leon/fsu.
  • If the station's web address, for instance is, https://leon.weatherstem.com/fsu, the scope would be leon/fsu
  • The station scope can also be set to random which pulls data from a random a station in the Weatherstem network, closest which pulls data from the station closest to the user in the Weatherstem network, and assigned which will look for a cookie named station and use it as the station to pull data from
  • The component includes a public Weatherstem.get() method which accepts a handler function as input and will return to it the latest data from the station in scope.
  • The component also includes a public Weatherstem.update() method which updates the data from the station in scope. By default, this method is called every 60 seconds but you can call it manually anytime.
  • Any element with a data-sensor attribute will have its child contents replaced by the current reading from the specified sensor. Values can be implemented for dynamically added elements by calling Weatherstem.update().