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- Installation
- Command Line
- Quick Start
- Free vs Pro
- Options
- Response
- Error Handling
- Connections
- License
Add this line to your application's Gemfile:
gem 'ipapi-rb'Then execute:
bundle installOr install it directly:
gem install ipapi-rbThe 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 outputSet your Pro API key via environment variable for HTTPS and unlimited requests:
export IPAPI_API_KEY=your_api_keyThe 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.queryFor 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 )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' )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 |
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'
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"result.isp # => "Google LLC"
result.org # => "Google Public DNS"
result.as_number # => "AS15169 Google LLC"
result.as_name # => "GOOGLE"
result.reverse # => "dns.google"result.mobile # => false
result.proxy # => false
result.hosting # => trueresult.success? # => true (status == 'success')
result.failed? # => false (status == 'fail')
result.mobile? # => false
result.proxy? # => false
result.hosting? # => true
result.coordinates # => [39.03, -77.5]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..."
endAPI 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
endCommon 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 |
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 connectionOr pass it directly to a request:
request = IpApi::QueryRequest.new(
api_key: ENV[ 'IPAPI_API_KEY' ],
connection: connection
)The gem is available as open source under the terms of the MIT License.