apiddress
Official Ruby SDK for the APIddress email validation API.
- Zero runtime gem dependencies (stdlib
net/httponly) - Ruby 3.0+, immutable
Datavalue objects, fully type-documented - Automatic retry with backoff on
429and5xx(batch creation is never retried)
Install
gem install apiddress
Or add to your Gemfile:
gem "apiddress"
Quickstart
require "apiddress"
client = Apiddress::Client.new(ENV["APIDDRESS_API_KEY"])
result = client.validate_email("ada@stripe.com")
puts result.status # => "valid"
puts result.score # => 0.98
Configuration
client = Apiddress::Client.new(
"YOUR_API_KEY",
base_url: "https://api.apiddress.com", # default
timeout: 10, # per-request timeout (seconds), default 10
max_retries: 2, # retries on 429/5xx, default 2
)
Usage
Validate one email
result = client.validate_email(
"john@company.com",
check_smtp: false, # default
allow_role_based: true, # server default
)
# result.status: "valid" | "invalid" | "risky" | "disposable" | "unknown"
# result.suggestion: "john@gmail.com" for typo-like addresses, else nil
# result.checks: Apiddress::ValidationChecks (syntax, domain_exists, mx, smtp, ...)
A malformed value (e.g. "not-an-email") is a verdict, not an error: you get
status == "invalid" with reason == "invalid_syntax".
Validate up to 100 emails synchronously
response = client.validate_emails(["a@example.com", "b@example.com"])
puts response.count
response.results.each { |r| puts "#{r.email} #{r.status}" }
Batch jobs (up to 5000 emails)
batch = client.create_batch(
emails,
callback_url: "https://yourapp.com/webhooks/apiddress", # optional
)
done = client.wait_for_batch(
batch.batch_id,
poll_interval: 1.0, # default
timeout: 60.0, # default
)
puts "#{done.status} #{done.results.length}"
# Or poll yourself:
status = client.get_batch(batch.batch_id)
wait_for_batch returns the terminal state ("completed" or "failed") —
check status before using results.
Account
profile = client.me # plan, limits, usage
usage = client.usage # current month
may = client.usage("2026-05") # specific month
health = client.health # no auth required
Error handling
Every failed request raises an Apiddress::Error:
require "apiddress"
begin
client.validate_email("john@company.com")
rescue Apiddress::Error => err
puts err.status # 429
puts err.code # "quota_exceeded"
puts err. # "Monthly request limit exceeded."
p err.details # {"requests_used"=>..., "requests_limit"=>...}
end
status |
code |
|---|---|
| 400 | invalid_request |
| 401 | unauthorized |
| 404 | not_found |
| 429 | quota_exceeded |
| 500 | internal_error |
| 0 | timeout (request or wait_for_batch timeout) |
Development
bundle install
# Unit tests (no network required):
ruby test/test_client.rb
# Integration tests need a live backend:
APIDDRESS_BASE_URL=http://localhost:3000 APIDDRESS_API_KEY=test_key_local_dev \
ruby test/test_client.rb
License
MIT