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.
- Features
- Installation
- Requirements
- Quick Start
- API Reference
- Error Handling
- Rate Limits
- Configuration
- Contributing
- License
- Links
- 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
gem install xposedornotOr add to your Gemfile:
gem 'xposedornot'Then run:
bundle install- Ruby 3.0 or higher
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.'
endclient = XposedOrNot::Client.new(api_key: nil, **options)See Configuration for all available options.
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_riskGet 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)"
endParameters:
| 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 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}"
endGet 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_pastesCheck 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.'
endThe 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 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) |
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.
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' }
)| 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 |
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
# 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 rubocopMIT - see the LICENSE file for details.
Made with care by XposedOrNot