0.0
The project is in a healthy, maintained state
A Ruby gem for interacting with the XposedOrNot API to check email breaches, password exposure, and breach analytics. Supports both the free and commercial Plus API.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

~> 2.0
~> 1.3
 Project Readme

XposedOrNot

xposedornot

Official Ruby SDK for the XposedOrNot API
Check if your email has been exposed in data breaches

Gem Version License: MIT Ruby Version


Note: This SDK uses the free public API from XposedOrNot.com - a free service to check if your email has been compromised in data breaches. Visit the XposedOrNot website to learn more about the service and check your email manually.


Table of Contents

  • Features
  • Installation
  • Requirements
  • Quick Start
  • API Reference
    • check_email
    • get_breaches
    • breach_analytics
    • check_password
  • Error Handling
  • Rate Limits
  • Configuration
  • Contributing
  • License
  • Links

Features

  • Simple API - Easy-to-use methods for checking email breaches and password exposure
  • Detailed Analytics - Get breach details, risk scores, and metrics
  • Password Safety - Check password exposure using k-anonymity (only a hash prefix is sent)
  • Error Handling - Custom error classes for different scenarios
  • Configurable - Timeout, retries, custom headers, and Plus API support
  • Secure - HTTPS enforced, input validation, no sensitive data logging

Installation

gem install xposedornot

Or add to your Gemfile:

gem 'xposedornot'

Then run:

bundle install

Requirements

  • Ruby 3.0 or higher

Quick Start

require 'xposedornot'

client = XposedOrNot::Client.new

# Check if an email has been breached
result = client.check_email('test@example.com')

if result.breached?
  puts "Email found in #{result.breaches.length} breaches:"
  result.breaches.each { |breach| puts "  - #{breach}" }
else
  puts 'Good news! Email not found in any known breaches.'
end

API Reference

Constructor

client = XposedOrNot::Client.new(api_key: nil, **options)

See Configuration for all available options.

Methods

check_email(email)

Check if an email address has been exposed in any data breaches. When an API key is configured, uses the Plus API for detailed results including breach_id and password_risk. Otherwise, uses the free API.

# Free API
client = XposedOrNot::Client.new
result = client.check_email('user@example.com')
puts result.breached?   # => true / false
puts result.breaches     # => ["Breach1", "Breach2"]

# Plus API (detailed results)
client = XposedOrNot::Client.new(api_key: 'your-api-key')
result = client.check_email('user@example.com')
puts result.breaches.first.breach_id
puts result.breaches.first.password_risk

get_breaches(domain:)

Get a list of all known data breaches, optionally filtered by domain.

# Get all breaches
breaches = client.get_breaches

# Filter by domain
adobe_breaches = client.get_breaches(domain: 'adobe.com')

breaches.each do |breach|
  puts "#{breach.breach_id} - #{breach.domain} (#{breach.exposed_records} records)"
end

Parameters:

Parameter Type Description
domain String Optional. Filter breaches by domain

Returns: Array<Models::Breach> with properties such as breach_id, breached_date, domain, industry, exposed_data, exposed_records, and verified.

breach_analytics(email)

Get detailed breach analytics for an email address, including breach summaries, metrics, and paste exposures.

analytics = client.breach_analytics('user@example.com')

puts analytics.breaches_details.length
puts analytics.breaches_summary
puts analytics.breach_metrics
puts analytics.exposed_pastes

check_password(password)

Check if a password has been exposed in data breaches. The password is hashed locally using Keccak-512 and only the first 10 hex characters of the digest are sent to the API, preserving anonymity via k-anonymity.

result = client.check_password('mypassword')

if result.exposed?
  puts "This password has been seen #{result.count} time(s) in breaches!"
else
  puts 'Password not found in any known breaches.'
end

Error Handling

The library provides custom error classes for different scenarios:

begin
  result = client.check_email('test@example.com')
rescue XposedOrNot::ValidationError => e
  puts "Invalid input: #{e.message}"
rescue XposedOrNot::RateLimitError
  puts 'Rate limited. Try again later.'
rescue XposedOrNot::NotFoundError
  puts 'Email not found in any breaches.'
rescue XposedOrNot::AuthenticationError
  puts 'Invalid API key.'
rescue XposedOrNot::NetworkError => e
  puts "Network error: #{e.message}"
rescue XposedOrNot::APIError => e
  puts "API error (#{e.status}): #{e.message}"
end

Error Classes

Error Class Description
XposedOrNotError Base error class for all errors
ValidationError Invalid input (e.g., malformed email, blank password)
RateLimitError API rate limit exceeded (HTTP 429)
NotFoundError Resource not found (HTTP 404)
AuthenticationError Authentication failed (HTTP 401/403)
NetworkError Network connectivity issues or timeouts
APIError General API error (exposes .status for the HTTP code)

Rate Limits

The XposedOrNot API has the following rate limits:

  • 2 requests per second
  • 50-100 requests per hour
  • 100-1000 requests per day

The client includes automatic retry with exponential backoff for 429 responses and built-in client-side throttling (1 request per second) for the free API.

Configuration

client = XposedOrNot::Client.new(
  api_key:        'your-api-key',  # Optional. Enables Plus API access
  timeout:        15,              # Request timeout in seconds (default: 30)
  max_retries:    5,               # Max retries on 429 responses (default: 3)
  custom_headers: { 'X-Custom' => 'value' }
)

Configuration Options

Option Type Default Description
api_key String nil API key for Plus API access
base_url String https://api.xposedornot.com Base URL for the free API
plus_base_url String https://plus-api.xposedornot.com Base URL for the Plus API
passwords_base_url String https://passwords.xposedornot.com/api Base URL for the password API
timeout Integer 30 Request timeout in seconds
max_retries Integer 3 Max retry attempts on 429 responses
custom_headers Hash {} Custom headers for all requests

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Setup

# Clone the repository
git clone https://github.com/XposedOrNot/XposedOrNot-Ruby.git
cd XposedOrNot-Ruby

# Install dependencies
bundle install

# Run tests
bundle exec rspec

# Run linter
bundle exec rubocop

License

MIT - see the LICENSE file for details.

Links


Made with care by XposedOrNot