xposedornot
Official Ruby SDK for the XposedOrNot API
Check if your email has been exposed in data breaches
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
- 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, **)
See Configuration for all available options.
Methods
check_email(email, include_details: false)
Check if an email address has been exposed in any data breaches.
- Without API key: Uses the free API, returns
EmailBreachResponsewith breach names only. Passinclude_details: trueto request detailed breach information. - With API key: Uses the Plus API (
plus-api.xposedornot.com), returnsEmailBreachDetailedResponsewith full breach details (include_detailsis ignored - the Plus API is always queried with detailed results).
# 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:, breach_id:)
Get a list of all known data breaches, optionally filtered by domain or breach ID.
# Get all breaches
breaches = client.get_breaches
# Filter by domain
adobe_breaches = client.get_breaches(domain: 'adobe.com')
# Fetch a specific breach by ID
adobe = client.get_breaches(breach_id: 'Adobe')
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 |
breach_id |
String |
Optional. Fetch a specific breach by ID |
Returns: Array<Models::Breach> with properties such as breach_id, breached_date, domain, industry, exposed_data, exposed_records, and verified.
get_domain_breaches
Get breach information for domains verified against your API key (requires an API key with verified domains configured at console.xposedornot.com).
client = XposedOrNot::Client.new(api_key: 'your-api-key')
report = client.get_domain_breaches
puts report.domain_summary # Breach counts per domain
puts report.yearly_metrics # Breach counts by year
puts report.top10_breaches # Top 10 largest breaches
report.breaches_details.each do |record|
puts "#{record.email} #{record.domain} #{record.breach}"
end
breach_analytics(email, token: nil)
Get detailed breach analytics for an email address, including breach summaries, metrics, and paste exposures. Pass token to access sensitive breach data.
analytics = client.breach_analytics('user@example.com')
puts analytics.breaches_count # Number of breaches
puts analytics.breach_names # Names of breaches the email was found in
puts analytics.breaches_details.length
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.}"
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.}"
rescue XposedOrNot::APIError => e
puts "API error (#{e.status}): #{e.}"
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.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - 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