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
- Email Breach Check -- Query the free or Plus API for email exposures
- Breach Listing -- List all known breaches with optional domain filtering
- Breach Analytics -- Detailed summaries, metrics, and paste data for an email
- Password Check -- k-anonymity via Keccak-512; the full password never leaves the client
- Async/Await -- Built on
reqwestandtokiofor non-blocking I/O - Rate Limiting -- Automatic client-side throttling (1 req/sec for the free API)
- Retry Logic -- Exponential backoff on HTTP 429 responses
- Configurable -- Builder pattern for timeout, retries, custom headers, and API key
Installation
Or add it directly to your Cargo.toml:
[]
= "1.0"
Requirements
- Rust 1.70 or higher
- A tokio async runtime (the crate depends on
tokiofor rate limiting and timing)
Quick Start
use Client;
async
API Reference
Constructor
use Client;
let client = builder
.timeout_secs
.max_retries
.build?;
See Configuration for all builder options.
Methods
check_email(email)
Check if an email address has been exposed in any data breaches.
When the client has an API key, the Plus API is used and returns detailed breach records. Without an API key the free API returns a simple list of breach names.
// Free API
let client = builder.build?;
let result = client.check_email.await?;
println!;
// Plus API -- returns detailed breach records
let client = builder
.api_key
.build?;
let result = client.check_email.await?;
println!;
Returns: EmailCheckResult -- an enum with Free(FreeEmailCheckResponse) or Plus(PlusEmailCheckResponse) variants depending on whether an API key is configured.
get_breaches(domain)
List all known data breaches, optionally filtered by domain.
// Get all breaches
let all = client.get_breaches.await?;
// Filter by domain
let filtered = client.get_breaches.await?;
for breach in &filtered.exposed_breaches
Returns: BreachListResponse containing a Vec<BreachRecord> with fields:
breach_id-- Unique identifierbreached_date-- Date of the breachdomain-- Associated domainindustry-- Industry categoryexposed_data-- Types of data exposedexposed_records-- Number of records exposedverified-- Whether the breach is verified
breach_analytics(email)
Get detailed breach analytics for an email address, including breach summaries, metrics, and paste exposures.
let analytics = client.breach_analytics.await?;
println!;
println!;
println!;
println!;
Returns: BreachAnalyticsResponse with fields:
exposed_breaches-- Breach detailsbreaches_summary-- Aggregated summarybreach_metrics-- Analytical metricspastes_summary-- Paste summaryexposed_pastes-- List of paste exposures
check_password(password)
Check if a password has been seen in known breaches. The password is hashed locally using Keccak-512 and only the first 10 hex characters of the digest are sent to the API (k-anonymity). The full password never leaves the client.
let result = client.check_password.await?;
println!;
Returns: PasswordCheckResponse with a search_pass_anon field containing:
anon-- The anonymous hash portionchar-- Character composition breakdown (e.g.,"D:3;A:8;S:0;L:11")count-- Number of times the password has been seen
Error Handling
All methods return Result<T, xposedornot::Error>. Use pattern matching on the Error enum to handle specific failure modes:
use ;
let client = builder.build?;
match client.check_email.await
Error Variants
| Variant | Description |
|---|---|
Validation |
Invalid input (e.g., malformed email, empty password) |
RateLimit |
API rate limit exceeded (HTTP 429) |
NotFound |
Resource not found (HTTP 404) |
Authentication |
Invalid or missing API key (HTTP 401/403) |
Network |
Connection or transport error (wraps reqwest::Error) |
Api |
Unexpected API response or server error |
Rate Limits
The XposedOrNot free API has the following rate limits:
- 2 requests per second
- 50-100 requests per hour
- 100-1000 requests per day
The client enforces client-side rate limiting at 1 request per second for the free API. When an API key is configured (Plus API), client-side throttling is disabled.
Server-side 429 responses are retried automatically with exponential backoff (1s, 2s, 4s, ...) up to max_retries attempts.
Configuration
Use the builder pattern to customize the client:
use Client;
let client = builder
.api_key // Enable Plus API
.timeout_secs // Request timeout (default: 30s)
.max_retries // Retry attempts on 429 (default: 3)
.base_url // Override free API base URL
.header // Add custom headers
.build?;
Builder Options
| Method | Default | Description |
|---|---|---|
api_key(key) |
None |
API key for Plus API; disables client-side rate limiting |
timeout_secs(secs) |
30 |
Request timeout in seconds |
max_retries(n) |
3 |
Max retry attempts on HTTP 429 |
base_url(url) |
https://api.xposedornot.com |
Free API base URL |
plus_base_url(url) |
https://plus-api.xposedornot.com |
Plus API base URL |
password_base_url(url) |
https://passwords.xposedornot.com/api |
Password API base URL |
header(name, value) |
-- | Add a custom header to every request |
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
# Build
# Run tests
# Run clippy
# Format
License
MIT -- see the LICENSE file for details.
Links
- XposedOrNot Website
- API Documentation
- crates.io Package
- docs.rs Documentation
- GitHub Repository
- XposedOrNot API Repository