Making HTTP Requests in Ruby

· 4 min read · Updated March 7, 2026 · beginner
http net::http api scripting rest

Ruby comes with a powerful standard library for making HTTP requests: Net::HTTP. Whether you’re fetching data from an API, downloading files, or sending data to a webhook, Net::HTTP has you covered—no external gems required.

This guide walks you through common HTTP operations in Ruby, perfect for automation scripts and DevOps tasks.

Setting Up Your Request

Every HTTP request in Net::HTTP starts with creating a connection object. You’ll typically specify the host and port:

require 'net/http'
require 'uri'

uri = URI('https://api.github.com/users')
http = Net::HTTP.new(uri.host, uri.port)

For HTTPS, enable SSL:

http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_PEER

The verify_mode setting controls SSL certificate verification. Use VERIFY_PEER for production (validates certificates) or VERIFY_NONE for development with self-signed certificates.

Making GET Requests

GET is the most common HTTP method—used to retrieve data. Here’s how to fetch data from an API:

require 'net/http'
require 'uri'
require 'json'

uri = URI('https://api.github.com/users/ruby')
response = Net::HTTP.get_response(uri)

puts response.code        # => "200"
puts response.message    # => "OK"
puts response.body       # => JSON string with user data

For more control, use the request object directly:

require 'net/http'
require 'uri'

uri = URI('https://api.github.com/users/ruby')
request = Net::HTTP::Get.new(uri)

request['Accept'] = 'application/vnd.github.v3+json'
response = http.request(request)

data = JSON.parse(response.body)
puts data['login']    # => "ruby"

The Net::HTTP.get_response method is a convenience shortcut that creates the request automatically. For adding headers or fine-tuned control, create the request object explicitly.

Making POST Requests

POST requests send data to a server—useful for creating resources, submitting forms, or sending JSON to an API:

require 'net/http'
require 'uri'
require 'json'

uri = URI('https://httpbin.org/post')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request.body = JSON.generate({ name: 'Ruby', type: 'language' })

response = http.request(request)
puts response.code    # => "200"
puts response.body    # => Echoed JSON response

The request object gives you full control over the HTTP method, headers, and body. Use JSON.generate to convert a Ruby hash to a JSON string.

Working with Headers

Headers provide metadata about your request. Common headers include:

request = Net::HTTP::Get.new(uri)

# Authentication
request['Authorization'] = 'Bearer YOUR_TOKEN'

# Content type
request['Content-Type'] = 'application/json'

# Accept response format
request['Accept'] = 'application/json'

# Custom headers
request['X-Custom-Header'] = 'MyValue'

response = http.request(request)

Headers are case-insensitive in HTTP, but Ruby uses the capitalization you provide. Stick to the standard formats shown above for compatibility.

Handling Responses

Net::HTTP provides several ways to work with responses:

response = http.request(request)

# Check status code
if response.code == '200'
  puts 'Success!'
end

# Parse JSON response
data = JSON.parse(response.body)

# Read response header
puts response['Content-Type']    # => "application/json"

# Response object methods
puts response.content_type
puts response.content_length
puts response['Set-Cookie']

The response object provides access to the status code via code (string) or integer_code (integer), the message via message, and the body via body.

Error Handling

Network requests can fail—servers go down, timeouts happen, SSL errors occur. Always handle exceptions:

require 'net/http'
require 'uri'

def fetch_url(url)
  uri = URI(url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  http.open_timeout = 5    # Connection timeout
  http.read_timeout = 10   # Read timeout
  
  request = Net::HTTP::Get.new(uri)
  
  begin
    response = http.request(request)
    case response
    when Net::HTTPSuccess
      response.body
    when Net::HTTPRedirection
      # Follow redirect
      fetch_url(response['Location'])
    else
      puts "Error: #{response.code} #{response.message}"
      nil
    end
  rescue Net::OpenTimeout => e
    puts "Connection timeout: #{e.message}"
    nil
  rescue Net::ReadTimeout => e
    puts "Read timeout: #{e.message}"
    nil
  rescue OpenSSL::SSL::SSLError => e
    puts "SSL error: #{e.message}"
    nil
  rescue SocketError => e
    puts "DNS or connection error: #{e.message}"
    nil
  end
end

Key timeouts to set:

  • open_timeout — seconds to wait when connecting
  • read_timeout — seconds to wait for data after connected

Practical Examples

Downloading a File

require 'net/http'
require 'uri'

uri = URI('https://example.com/large-file.zip')
response = Net::HTTP.get_response(uri)

if response.code == '200'
  File.write('large-file.zip', response.body)
  puts 'File downloaded successfully!'
end

Checking API Availability

require 'net/http'
require 'uri'

def api_healthy?(url)
  uri = URI("#{url}/health")
  response = Net::HTTP.get_response(uri)
  response.code == '200'
end

puts api_healthy?('https://api.example.com')    # => true or false

Sending Webhook Notifications

require 'net/http'
require 'uri'
require 'json'

def send_webhook(url, payload)
  uri = URI(url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  
  request = Net::HTTP::Post.new(uri)
  request['Content-Type'] = 'application/json'
  request.body = JSON.generate(payload)
  
  http.request(request)
end

send_webhook('https://hooks.example.com/notify', 
  { event: 'deploy', status: 'success', service: 'my-app' })

Query String Parameters

require 'net/http'
require 'uri'

# Build URL with query parameters
params = { page: 1, per_page: 50, sort: 'desc' }
uri = URI('https://api.example.com/items')
uri.query = URI.encode_www_form(params)

response = Net::HTTP.get_response(uri)

The encode_www_form method properly encodes query parameters, handling special characters and multiple values.

When to Use Net::HTTP

Net::HTTP is ideal for:

  • Simple API calls in scripts
  • Automation and DevOps tasks
  • Learning how HTTP works
  • Lightweight integrations with no dependencies

For more complex needs, consider these gems:

  • Faraday — unified interface with multiple adapters (Net::HTTP, HTTPClient, Patron)
  • HTTParty — convenient DSL for REST APIs with automatic JSON parsing
  • RestClient — simple Ruby-like HTTP client interface

Summary

Ruby’s Net::HTTP library gives you everything needed for HTTP scripting:

  • Simple GET and POST requests
  • Full control over headers and body
  • SSL/TLS support for secure connections
  • Proper error handling for production scripts
  • No external dependencies required

Start with require 'net/http' and you’re ready to make HTTP requests from any Ruby script.