Ruby applications can retrieve historical weather, current conditions, and forecast data directly from the Visual Crossing Timeline Weather API.
In this tutorial, we’ll use Ruby’s built-in Net::HTTP library to send a Weather API request, parse the returned JSON, and work with daily weather data.
The Visual Crossing Weather API provides programmatic access to historical, current, and forecast weather data. If you want to explore or download weather datasets without writing code, see Visual Crossing Weather Data.
To follow the examples, sign up for a free Visual Crossing account and obtain your Weather API key.
For the complete request and response reference, see the Timeline Weather API documentation.
What we’ll do
In this tutorial, we’ll:
- Create a Timeline Weather API request.
- Retrieve weather data using
Net::HTTP. - Verify the HTTP response before processing it.
- Parse the returned JSON using Ruby’s standard JSON library.
- Read daily weather values.
- Retrieve historical weather for a date range.
- Add current conditions and hourly weather.
No third-party Ruby gems are required.
Get your Weather API key
Your Visual Crossing Weather API key authenticates requests made by your application.
Rather than placing the key directly in your Ruby source code, we’ll read it from an environment variable:
api_key = ENV["VISUAL_CROSSING_API_KEY"]
if api_key.nil? || api_key.empty?
raise "VISUAL_CROSSING_API_KEY is not set"
end
On macOS or Linux, you can set the variable before running your script:
export VISUAL_CROSSING_API_KEY="YOUR_API_KEY"
On Windows PowerShell:
$env:VISUAL_CROSSING_API_KEY="YOUR_API_KEY"
Visual Crossing plans include usage and request limits, so applications should be designed to operate within the limits of the account plan being used.
Understanding the Timeline Weather API URL
The Timeline Weather API uses the following basic structure:
/timeline/[location]/[date1]/[date2]
Only the location is required.
A forecast request for Paris can use:
/timeline/Paris%2C%20France
A historical request for July 1, 2026 uses:
/timeline/Paris%2C%20France/2026-07-01
A historical date range uses:
/timeline/Paris%2C%20France/2026-07-01/2026-07-07
When dates are omitted, the API returns the available forecast data. When historical dates are supplied, it returns weather data for those dates.
Build the Weather API request
Ruby’s URI library can safely construct the request URL and query parameters.
Create a file named:
weather.rb
Then start with:
require "uri"
require "net/http"
require "json"
api_key = ENV["VISUAL_CROSSING_API_KEY"]
if api_key.nil? || api_key.empty?
raise "VISUAL_CROSSING_API_KEY is not set"
end
location = "Paris, France"
base_url =
"https://weather.visualcrossing.com/" \
"VisualCrossingWebServices/rest/services/timeline/" \
"#{URI.encode_www_form_component(location)}"
params = {
key: api_key,
unitGroup: "metric",
include: "days",
elements: "datetime,tempmax,tempmin,precip,precipprob,conditions",
contentType: "json"
}
uri = URI(base_url)
uri.query = URI.encode_www_form(params)
URI.encode_www_form_component() safely encodes a location such as:
Paris, France
before placing it in the URL.
URI.encode_www_form() then creates the query string from the Ruby hash.
Retrieve weather data using Net::HTTP
Now create the HTTPS request:
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.open_timeout = 10
http.read_timeout = 20
request = Net::HTTP::Get.new(uri)
response = http.request(request)
Setting:
http.use_ssl = true
enables HTTPS.
Ruby’s normal TLS certificate verification should remain enabled. You should not disable certificate verification simply to make an HTTPS request work.
We also configure connection and read timeouts:
http.open_timeout = 10
http.read_timeout = 20
so a network problem does not cause the application to wait indefinitely.
Check the HTTP response
Before parsing the Weather API result, check that the request was successful:
unless response.is_a?(Net::HTTPSuccess)
raise "Weather API request failed " \
"(#{response.code}): #{response.body}"
end
This makes problems such as invalid API keys, invalid parameters, usage-limit errors, or invalid locations easier to diagnose.
Parse the JSON response
Ruby’s standard json library can convert the Weather API response into Ruby hashes and arrays:
weather = JSON.parse(response.body)
The resolved location is available as:
weather["resolvedAddress"]
Daily weather records are stored in:
weather["days"]
For example:
puts "Weather for #{weather["resolvedAddress"]}"
weather["days"].each do |day|
puts "#{day["datetime"]}: " \
"#{day["conditions"]}, " \
"high #{day["tempmax"]}, " \
"low #{day["tempmin"]}"
end
Complete forecast example
Here is the complete Ruby example for retrieving daily forecast data:
require "uri"
require "net/http"
require "json"
api_key = ENV["VISUAL_CROSSING_API_KEY"]
if api_key.nil? || api_key.empty?
raise "VISUAL_CROSSING_API_KEY is not set"
end
location = "Paris, France"
base_url =
"https://weather.visualcrossing.com/" \
"VisualCrossingWebServices/rest/services/timeline/" \
"#{URI.encode_www_form_component(location)}"
params = {
key: api_key,
unitGroup: "metric",
include: "days",
elements: "datetime,tempmax,tempmin,precip,precipprob,conditions",
contentType: "json"
}
uri = URI(base_url)
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.open_timeout = 10
http.read_timeout = 20
request = Net::HTTP::Get.new(uri)
response = http.request(request)
unless response.is_a?(Net::HTTPSuccess)
raise "Weather API request failed " \
"(#{response.code}): #{response.body}"
end
weather = JSON.parse(response.body)
puts "Weather for #{weather["resolvedAddress"]}"
weather["days"].each do |day|
puts "#{day["datetime"]}: " \
"#{day["conditions"]}, " \
"high #{day["tempmax"]}, " \
"low #{day["tempmin"]}, " \
"precipitation probability #{day["precipprob"]}%"
end
Run the script using:
ruby weather.rb
Retrieve historical weather
The same Timeline Weather API can retrieve historical weather by adding dates to the URL path.
For example, to retrieve weather for Paris from July 1 through July 7, 2026:
require "uri"
require "net/http"
require "json"
api_key = ENV["VISUAL_CROSSING_API_KEY"]
if api_key.nil? || api_key.empty?
raise "VISUAL_CROSSING_API_KEY is not set"
end
location = "Paris, France"
start_date = "2026-07-01"
end_date = "2026-07-07"
encoded_location =
URI.encode_www_form_component(location)
base_url =
"https://weather.visualcrossing.com/" \
"VisualCrossingWebServices/rest/services/timeline/" \
"#{encoded_location}/#{start_date}/#{end_date}"
params = {
key: api_key,
unitGroup: "metric",
include: "days",
elements: "datetime,tempmax,tempmin,precip,humidity,conditions",
contentType: "json"
}
uri = URI(base_url)
uri.query = URI.encode_www_form(params)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.open_timeout = 10
http.read_timeout = 20
response =
http.request(
Net::HTTP::Get.new(uri)
)
unless response.is_a?(Net::HTTPSuccess)
raise "Weather API request failed " \
"(#{response.code}): #{response.body}"
end
weather = JSON.parse(response.body)
weather["days"].each do |day|
puts "#{day["datetime"]}: " \
"high #{day["tempmax"]}, " \
"low #{day["tempmin"]}, " \
"precipitation #{day["precip"]}, " \
"humidity #{day["humidity"]}"
end
The returned data uses the same days array as a forecast request, so the processing logic remains consistent.
If your main goal is to explore or download historical datasets rather than retrieve them in an application, see Visual Crossing Weather Data.
Retrieve a single historical date
For one date, include only the first date in the Timeline path:
start_date = "2026-07-01"
base_url =
"https://weather.visualcrossing.com/" \
"VisualCrossingWebServices/rest/services/timeline/" \
"#{encoded_location}/#{start_date}"
The API returns weather data for that date.
Make the location and dates dynamic
In a real application, you’ll usually get the location and dates from a user, configuration file, database, or another application component.
For example:
location = ARGV[0] || "Paris, France"
start_date = ARGV[1]
end_date = ARGV[2]
You can then build the path dynamically:
encoded_location =
URI.encode_www_form_component(location)
base_url =
"https://weather.visualcrossing.com/" \
"VisualCrossingWebServices/rest/services/timeline/" \
encoded_location
if start_date && !start_date.empty?
base_url += "/#{URI.encode_www_form_component(start_date)}"
end
if end_date && !end_date.empty?
base_url += "/#{URI.encode_www_form_component(end_date)}"
end
For example:
ruby weather.rb "New York, NY" 2026-07-01 2026-07-07
Add current conditions
The Timeline Weather API can return current conditions along with the forecast.
Change:
include: "days"
to:
include: "current,days"
Current conditions are then available as:
weather["currentConditions"]
For example:
current = weather["currentConditions"]
puts "Current temperature: #{current["temp"]}"
puts "Humidity: #{current["humidity"]}"
puts "Conditions: #{current["conditions"]}"
Retrieve hourly weather
To request hourly weather, use:
include: "hours"
or:
include: "days,hours"
Hourly weather is contained inside each daily record:
hours = weather["days"][0]["hours"]
For example:
hours.each do |hour|
puts "#{hour["datetime"]}: " \
"#{hour["temp"]}, " \
"#{hour["conditions"]}"
end
Request only the weather elements you need
The Timeline Weather API provides many weather fields.
Use the elements parameter to limit the response to the values your Ruby application needs.
For example:
elements: "datetime,tempmax,tempmin,conditions"
is sufficient for a simple daily forecast.
Other available values include weather elements such as:
temp
feelslike
humidity
dew
precip
precipprob
snow
snowdepth
windspeed
windgust
winddir
pressure
cloudcover
visibility
solarradiation
solarenergy
uvindex
conditions
icon
For the full list of request parameters and weather elements, see the Timeline Weather API documentation.
Using US or metric units
The examples in this article use metric units:
unitGroup: "metric"
For US units, use:
unitGroup: "us"
The selected unit group controls the units used for values such as temperature, precipitation, wind speed, and visibility.
Handling Weather API errors
Weather API requests can fail for reasons such as:
- Invalid API keys
- Invalid locations
- Invalid dates
- Invalid request parameters
- Account usage limits
- Network problems
- Connection timeouts
The examples in this article check the returned HTTP status:
unless response.is_a?(Net::HTTPSuccess)
raise "Weather API request failed " \
"(#{response.code}): #{response.body}"
end
When debugging a request, inspect both:
response.code
and:
response.body
because the response body often contains useful information about the problem.
Do not disable SSL certificate verification
Some older Ruby HTTP examples disable TLS certificate verification using code such as:
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
Do not use this approach.
Disabling certificate verification prevents Ruby from confirming that the HTTPS server is the expected server and removes an important part of TLS security.
A normal Net::HTTP HTTPS request should use certificate verification.
If an HTTPS request fails because of certificate problems, fix the local certificate store or runtime environment rather than disabling verification.
Going further
Once your Ruby application can retrieve Timeline Weather API data, the same approach can support:
- Historical weather analysis
- Current weather applications
- Hourly forecasts
- Daily forecasts
- Weather dashboards
- Rails applications
- Background jobs
- Command-line utilities
- Business applications
- Agricultural applications
- Travel and event applications
The Visual Crossing Weather API provides programmatic access to historical weather, current conditions, forecasts, alerts, and additional weather information.
If you want to search, explore, or download weather datasets without building an API integration, use Visual Crossing Weather Data.
If you haven’t created an account yet, sign up for a free Visual Crossing account.
For detailed request parameters and response fields, see the Timeline Weather API documentation.
Summary
Ruby’s standard library includes everything required to retrieve and process Visual Crossing Weather API data without installing additional gems.
The basic process is:
- Obtain a Visual Crossing Weather API key.
- Store the key outside the application source code.
- Build a Timeline Weather API URL using
URI. - Send the HTTPS request using
Net::HTTP. - Keep normal TLS certificate verification enabled.
- Check the HTTP status before processing the response.
- Parse the returned JSON using
JSON.parse(). - Read daily, hourly, or current weather values from the response.
Because the Timeline Weather API provides historical, current, and forecast weather through a consistent interface, the same Ruby integration can support a wide variety of weather-enabled applications.

