Google Apps Script makes it easy to add weather data to Google Sheets and other Google Workspace applications. Because Apps Script is based on JavaScript, you can call the Visual Crossing Weather API directly, parse the returned JSON weather data, and use the results in your spreadsheet or application.
In this tutorial, we’ll use the Visual Crossing Timeline Weather API to retrieve historical weather data using Google Apps Script. We’ll start with a simple request and then show how to use locations and dates stored in a Google Sheet.
What you’ll need
Before getting started, you’ll need:
- A Google account with access to Google Sheets and Apps Script
- A Visual Crossing Weather account
- Your Visual Crossing Weather API key
If you don’t already have a Visual Crossing Weather account, you can create one for free and obtain your API key from your account page.
Keep your API key private. We’ll use YOUR_API_KEY in the examples below as a placeholder for your actual key.
Building a historical weather API request
The Visual Crossing Timeline Weather API provides historical weather data, current conditions, and weather forecasts through the same API.
The basic URL for a historical weather request is:
https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/[location]/[date]?key=YOUR_API_KEY
For example, to request historical weather for Herndon, Virginia on August 1, 2026:
https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/Herndon%2C%20VA/2026-08-01?unitGroup=us&include=days&key=YOUR_API_KEY&contentType=json
You can test a Weather API URL by pasting it into your browser after replacing YOUR_API_KEY with your API key.
The response contains a JSON object with a days array. For a single-date request, the requested weather information is available in the first item:
data.days[0]
For example:
data.days[0].tempmax
data.days[0].tempmin
data.days[0].humidity
represent the day’s maximum temperature, minimum temperature, and average relative humidity.
You can also create and test requests using the Visual Crossing Weather Query Builder.
Writing your first Apps Script weather function
Let’s start with a simple Apps Script function that retrieves historical weather for a single location and date.
function fetchHistoricalWeather() {
var apiKey = "YOUR_API_KEY";
var location = "Herndon, VA";
var date = "2026-08-01";
var url =
"https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/" +
encodeURIComponent(location) + "/" +
date +
"?unitGroup=us&include=days&key=" +
encodeURIComponent(apiKey) +
"&contentType=json";
var response = UrlFetchApp.fetch(url);
var data = JSON.parse(response.getContentText());
var day = data.days[0];
Logger.log("Weather Results");
Logger.log("Date: " + day.datetime);
Logger.log("High Temperature: " + day.tempmax);
Logger.log("Low Temperature: " + day.tempmin);
Logger.log("Humidity: " + day.humidity);
}
The script performs three main tasks.
First, it builds the Timeline Weather API URL using the location, date, and API key.
var url =
"https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/" +
encodeURIComponent(location) + "/" +
date +
"?unitGroup=us&include=days&key=" +
encodeURIComponent(apiKey) +
"&contentType=json";
We use encodeURIComponent() for the location because addresses can contain spaces, commas, and other characters that need to be encoded when included in a URL.
Next, Apps Script’s UrlFetchApp.fetch() function sends the request to the Weather API:
var response = UrlFetchApp.fetch(url);
The Weather API returns JSON, which we convert to a JavaScript object using JSON.parse():
var data = JSON.parse(response.getContentText());
Finally, we retrieve the first daily weather record:
var day = data.days[0];
Individual weather elements can then be accessed directly:
day.tempmax
day.tempmin
day.humidity
The Timeline Weather API includes many additional weather elements including precipitation, wind speed, cloud cover, visibility, snow, solar radiation, weather conditions, and more.
Running the code in Google Apps Script
You can try the example from a Google Sheet.
Open your Google Sheet and select:
Extensions → Apps Script
Paste the code into the Apps Script editor and replace:
YOUR_API_KEY
with your Visual Crossing Weather API key.
Save the project and run the fetchHistoricalWeather function.
The first time you run the script, Google may ask you to authorize the script to make external requests.
After the function executes, the weather values will be written to the Apps Script execution log.
Making the weather request dynamic
Hard-coding the location and date is useful for a first example, but most applications need those values to change.
We can easily turn them into function parameters:
function getHistoricalWeather(location, date, apiKey) {
var url =
"https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/" +
encodeURIComponent(location) + "/" +
date +
"?unitGroup=us&include=days&key=" +
encodeURIComponent(apiKey) +
"&contentType=json";
var response = UrlFetchApp.fetch(url);
var data = JSON.parse(response.getContentText());
return data.days[0];
}
We can now retrieve weather for any location and date:
var weather = getHistoricalWeather(
"Washington, DC",
"2026-08-01",
"YOUR_API_KEY"
);
Logger.log(weather.tempmax);
Logger.log(weather.tempmin);
Logger.log(weather.precip);
The location can be a city, address, partial address, or latitude and longitude.
For example:
var location = "38.9697,-77.385";
Reading the location and date from Google Sheets
One of the most useful features of Apps Script is its integration with Google Sheets.
For example, suppose your sheet contains:
| Cell | Value |
|---|---|
| B2 | Herndon, VA |
| C2 | 8/1/2026 |
We can read those values and use them to create our weather request.
function fetchWeatherFromSheet() {
var sheet = SpreadsheetApp.getActiveSheet();
var location = sheet.getRange("B2").getValue();
var dateValue = sheet.getRange("C2").getValue();
var timeZone = SpreadsheetApp
.getActive()
.getSpreadsheetTimeZone();
var date = Utilities.formatDate(
dateValue,
timeZone,
"yyyy-MM-dd"
);
var apiKey = "YOUR_API_KEY";
var url =
"https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/" +
encodeURIComponent(location) + "/" +
date +
"?unitGroup=us&include=days&key=" +
encodeURIComponent(apiKey) +
"&contentType=json";
var response = UrlFetchApp.fetch(url);
var data = JSON.parse(response.getContentText());
var day = data.days[0];
sheet.getRange("D2").setValue(day.tempmax);
sheet.getRange("E2").setValue(day.tempmin);
sheet.getRange("F2").setValue(day.humidity);
sheet.getRange("G2").setValue(day.precip);
sheet.getRange("H2").setValue(day.conditions);
}
In this example:
B2contains the location.C2contains the requested date.D2receives the maximum temperature.E2receives the minimum temperature.F2receives humidity.G2receives precipitation.H2receives a description of the weather conditions.
You can change the cells and weather elements to match your own spreadsheet.
Requesting a historical date range
The Timeline Weather API can also retrieve multiple days in one request.
Instead of making a separate request for every day, add both a start date and end date to the URL:
/timeline/[location]/[start-date]/[end-date]
For example:
https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/Herndon%2C%20VA/2026-08-01/2026-08-07?unitGroup=us&include=days&key=YOUR_API_KEY&contentType=json
The resulting days array contains one entry for each day in the requested period.
We can loop through those days in Apps Script:
function fetchWeatherRange() {
var apiKey = "YOUR_API_KEY";
var location = "Herndon, VA";
var startDate = "2026-08-01";
var endDate = "2026-08-07";
var url =
"https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/" +
encodeURIComponent(location) + "/" +
startDate + "/" +
endDate +
"?unitGroup=us&include=days&key=" +
encodeURIComponent(apiKey) +
"&contentType=json";
var response = UrlFetchApp.fetch(url);
var data = JSON.parse(response.getContentText());
data.days.forEach(function(day) {
Logger.log(
day.datetime +
": high=" + day.tempmax +
", low=" + day.tempmin +
", precipitation=" + day.precip
);
});
}
Using a date range is generally preferable to making individual requests for each day when your application needs a continuous period of historical weather data.
Writing a date range to Google Sheets
We can extend the previous example to write the complete result into a spreadsheet.
function loadWeatherHistoryIntoSheet() {
var sheet = SpreadsheetApp.getActiveSheet();
var apiKey = "YOUR_API_KEY";
var location = "Herndon, VA";
var startDate = "2026-08-01";
var endDate = "2026-08-07";
var url =
"https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/" +
encodeURIComponent(location) + "/" +
startDate + "/" +
endDate +
"?unitGroup=us&include=days&key=" +
encodeURIComponent(apiKey) +
"&contentType=json";
var response = UrlFetchApp.fetch(url);
var data = JSON.parse(response.getContentText());
var rows = [
["Date", "Max Temp", "Min Temp", "Humidity", "Precip", "Conditions"]
];
data.days.forEach(function(day) {
rows.push([
day.datetime,
day.tempmax,
day.tempmin,
day.humidity,
day.precip,
day.conditions
]);
});
sheet
.getRange(1, 1, rows.length, rows[0].length)
.setValues(rows);
}
Rather than writing each individual cell separately, this example creates a two-dimensional array and writes the complete result to Google Sheets with a single setValues() operation.
This approach is particularly useful when retrieving larger amounts of historical weather data.
Requesting hourly historical weather
So far, we’ve requested daily weather using:
include=days
To retrieve hourly weather, change the request to:
include=hours
For example:
https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/Herndon%2C%20VA/2026-08-01?unitGroup=us&include=hours&key=YOUR_API_KEY&contentType=json
Hourly observations are stored within each day’s hours array:
var hours = data.days[0].hours;
hours.forEach(function(hour) {
Logger.log(
hour.datetime +
": temperature=" + hour.temp +
", precipitation=" + hour.precip
);
});
You can therefore use the same Apps Script techniques for both daily and hourly historical weather.
Requesting only the weather elements you need
The Timeline Weather API supports the elements parameter to control which weather variables are returned.
For example, if your application only needs the date, maximum temperature, minimum temperature, and precipitation, you can request:
&elements=datetime,tempmax,tempmin,precip
A complete request might therefore look like:
https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/Herndon%2C%20VA/2026-08-01/2026-08-07?unitGroup=us&include=days&elements=datetime,tempmax,tempmin,precip&key=YOUR_API_KEY&contentType=json
Limiting the result to the data your application actually uses can reduce response size and simplify processing.
Handling Weather API errors
For production scripts, it’s useful to check the HTTP response before attempting to process it.
For example:
var response = UrlFetchApp.fetch(url, {
muteHttpExceptions: true
});
var status = response.getResponseCode();
if (status !== 200) {
throw new Error(
"Weather API request failed (" +
status +
"): " +
response.getContentText()
);
}
var data = JSON.parse(response.getContentText());
This makes API errors easier to identify and prevents your script from attempting to process an unsuccessful response as weather data.
You may also want to validate spreadsheet inputs before sending the request. For example, check that the location is not empty and that the requested date is valid.
Keeping your API key outside your source code
Hard-coding an API key is convenient while testing, but you may prefer not to include the key directly in scripts that are shared with other users.
Google Apps Script’s PropertiesService can store configuration values such as an API key.
For example:
var apiKey = PropertiesService
.getScriptProperties()
.getProperty("VISUAL_CROSSING_API_KEY");
You can then store your Visual Crossing API key as a script property named:
VISUAL_CROSSING_API_KEY
This separates the API key from the main source code and makes the script easier to maintain.
Be aware of your Weather API usage
Visual Crossing plans include usage and request limits that should be followed when building automated applications.
Google Sheets scripts can generate a significant number of API requests if a request is made separately for every cell or row. Where practical, retrieve a continuous date range in one request rather than making a separate request for each date, and avoid repeatedly requesting weather data that your application has already retrieved and can reuse.
When processing many locations or large spreadsheets, consider how often your script runs and monitor your Visual Crossing account usage to ensure that the application remains within the limits of your account plan.
Using different unit systems
The examples in this article use:
unitGroup=us
The Timeline Weather API also supports other unit groups.
For example:
unitGroup=metric
can be used for metric weather values.
Choose the unit group that is appropriate for your application before processing the returned values.
Going further
Once you can retrieve Weather API data using Apps Script, you can use the same approach to build much more sophisticated Google Sheets applications.
For example, you can:
- Retrieve weather for locations listed in spreadsheet rows.
- Compare weather across different dates.
- Load hourly observations for detailed analysis.
- Add forecast or current weather data.
- Retrieve additional weather elements such as wind, snow, solar radiation, visibility, or cloud cover.
- Run scheduled Apps Script jobs to update weather data automatically.
- Build custom spreadsheet functions or menus around your weather workflow.
The Timeline Weather API uses the same basic request structure for historical weather, current conditions, and forecasts, so the techniques shown here can be reused across many different weather applications.
Summary
Google Apps Script provides a straightforward way to bring Visual Crossing Weather data into Google Sheets and other Google Workspace applications.
The basic process is:
- Build a Timeline Weather API request for your location and date or date range.
- Use
UrlFetchApp.fetch()to retrieve the weather data. - Parse the JSON response using
JSON.parse(). - Read daily or hourly weather values from the response.
- Write those values into your spreadsheet or use them elsewhere in your application.
From there, the location, dates, weather elements, and output can all be made dynamic to build weather-enabled spreadsheets and Google Workspace applications.
For the complete list of available options and weather elements, see the Visual Crossing Timeline Weather API documentation.
If you have questions about using Visual Crossing Weather with Google Apps Script, please visit the Visual Crossing support resources.

