Project

ipapi-rb

0.0
No release in over 3 years
The IpApi gem implements a lightweight interface to the IP-API.com geolocation API. IP-API provides location and network information for any IP address or domain name in JSON format. This gem supports both the free endpoint (rate-limited, HTTP only) and the Pro endpoint (unlimited, HTTPS) with automatic endpoint selection based on API key presence.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 1.9
~> 5.25
~> 6.3

Runtime

 Project Readme

IpApi

The IpApi gem provides a Ruby interface to the IP-API.com geolocation API, enabling IP address and domain lookups to retrieve location, network, and connection information.

require 'ip_api'

response = IpApi.query( '8.8.8.8' )
if response.success?
  result = response.result
  puts "#{ result.city }, #{ result.country }"  # => "Ashburn, United States"
  puts result.isp                                # => "Google LLC"
  puts result.coordinates                        # => [39.03, -77.5]
end

Table of Contents

  • Installation
  • Command Line
  • Quick Start
  • Free vs Pro
  • Options
    • Fields
    • Language
  • Response
    • Location Fields
    • Network Fields
    • Connection Fields
    • Helper Methods
  • Error Handling
  • Connections
  • License

Installation

Add this line to your application's Gemfile:

gem 'ipapi-rb'

Then execute:

bundle install

Or install it directly:

gem install ipapi-rb

Command Line

The gem includes an ipapi command for quick lookups from the terminal:

ipapi 8.8.8.8
ipapi google.com
ipapi                           # Look up your own IP
ipapi -f country,city 8.8.8.8   # Specific fields only
ipapi -l de 8.8.8.8             # German localization
ipapi -j 8.8.8.8                # Raw JSON output

Set your Pro API key via environment variable for HTTPS and unlimited requests:

export IPAPI_API_KEY=your_api_key

Quick Start

The simplest way to use the gem is through the module-level convenience method:

require 'ip_api'

# Query an IP address
response = IpApi.query( '8.8.8.8' )
if response.success?
  result = response.result
  puts result.country       # => "United States"
  puts result.city          # => "Ashburn"
  puts result.isp           # => "Google LLC"
  puts result.hosting?      # => true
end

# Query a domain
response = IpApi.query( 'google.com' )

# Query your own IP (no argument)
response = IpApi.query

For more control, instantiate request objects directly:

request = IpApi::QueryRequest.new( api_key: ENV[ 'IPAPI_API_KEY' ] )

options = IpApi::QueryOptions.build do
  fields [ :country, :city, :isp, :proxy, :hosting ]
  lang :de
end

response = request.submit( '8.8.8.8', options )

Free vs Pro

The gem automatically selects the appropriate endpoint based on whether an API key is configured:

Feature Free Pro
Endpoint http://ip-api.com https://pro.ip-api.com
SSL/HTTPS No Yes
Rate Limit 45 requests/minute Unlimited
Commercial Use No Yes
# Free (no API key)
response = IpApi.query( '8.8.8.8' )

# Pro (with API key)
IpApi.api_key ENV[ 'IPAPI_API_KEY' ]
response = IpApi.query( '8.8.8.8' )

# Or pass directly to request
request = IpApi::QueryRequest.new( api_key: 'your-key' )
response = request.submit( '8.8.8.8' )

Options

Fields

Control which fields are returned to reduce bandwidth:

options = IpApi::QueryOptions.build do
  fields [ :status, :country, :city, :lat, :lon ]
end

response = IpApi.query( '8.8.8.8', options )

Available fields (use snake_case in Ruby):

Field Description
:status Request status (success or fail)
:message Error message (when status is fail)
:query IP address used for the query
:continent Continent name
:continent_code Two-letter continent code
:country Country name
:country_code ISO 3166-1 alpha-2 country code
:region Region/state short code
:region_name Region/state full name
:city City name
:district District (subdivision of city)
:zip Zip/postal code
:lat Latitude
:lon Longitude
:timezone Timezone identifier
:offset UTC offset in seconds
:currency National currency code
:isp ISP name
:org Organization name
:as AS number and organization
:as_name AS name
:reverse Reverse DNS (can delay response)
:mobile Mobile connection flag
:proxy Proxy/VPN/Tor flag
:hosting Hosting/datacenter flag

Language

Localize the country, region_name, and city fields:

options = IpApi::QueryOptions.build do
  lang :de  # German
end

response = IpApi.query( '8.8.8.8', options )
puts response.result.country  # => "Vereinigte Staaten"

Supported languages: :en, :de, :es, :fr, :ja, :ru, :'pt-BR', :'zh-CN'


Response

Location Fields

result = response.result

result.continent        # => "North America"
result.continent_code   # => "NA"
result.country          # => "United States"
result.country_code     # => "US"
result.region           # => "VA"
result.region_name      # => "Virginia"
result.city             # => "Ashburn"
result.district         # => nil
result.zip              # => "20149"
result.lat              # => 39.03
result.lon              # => -77.5
result.timezone         # => "America/New_York"
result.offset           # => -18000
result.currency         # => "USD"

Network Fields

result.isp              # => "Google LLC"
result.org              # => "Google Public DNS"
result.as_number        # => "AS15169 Google LLC"
result.as_name          # => "GOOGLE"
result.reverse          # => "dns.google"

Connection Fields

result.mobile           # => false
result.proxy            # => false
result.hosting          # => true

Helper Methods

result.success?         # => true (status == 'success')
result.failed?          # => false (status == 'fail')

result.mobile?          # => false
result.proxy?           # => false
result.hosting?         # => true

result.coordinates      # => [39.03, -77.5]

Error Handling

The API returns errors in two ways:

HTTP errors (rate limiting):

response = IpApi.query( '8.8.8.8' )

unless response.success?
  error = response.result
  puts error.error_type         # => :rate_limit_error
  puts error.error_description  # => "The rate limit has been exceeded..."
end

API errors (invalid query, private IP):

response = IpApi.query( '192.168.1.1' )

if response.success?
  result = response.result
  if result.failed?
    puts result.message  # => "private range"
  end
end

Common API error messages:

Message Description
private range IP is in a private network range
reserved range IP is in a reserved range
invalid query Invalid IP or domain

Connections

The gem uses Faraday for HTTP requests. To customize the connection:

connection = Faraday.new do | faraday |
  faraday.response :logger
  faraday.adapter :net_http
end

IpApi.connection connection

Or pass it directly to a request:

request = IpApi::QueryRequest.new(
  api_key: ENV[ 'IPAPI_API_KEY' ],
  connection: connection
)

License

The gem is available as open source under the terms of the MIT License.