Postio Ruby SDK

Gem Version Ruby License: MIT

Ruby SDK for the Postio API — UK address, email, and phone validation. Backed by Royal Mail PAF and Ordnance Survey. Stdlib net/http only, zero runtime dependencies.

Install

gem install postio

Or in your Gemfile:

gem "postio", "~> 0.1"

Requires Ruby 3.1+.

30-second example

require "postio"

client = Postio::Client.new(api_key: "pk_live_...")  # or set POSTIO_API_KEY

result = client.address.search("downing street")
result.results.each do |hit|
  puts "#{hit.udprn}: #{hit.suggestion}"
end

puts "request id: #{result.meta.request_id}"

API

Method Returns
client.address.search(q, max_results:) AddressSearchEnvelope
client.address.postcode(postcode, max_results:) AddressPostcodeEnvelope
client.address.udprn(udprn) AddressUdprnEnvelope
client.email.validate(address) EmailEnvelope
client.phone.validate(number) PhoneEnvelope
client.connect ConnectSuccess

All response objects are immutable Data value classes (Ruby 3.2+). Field names are snake_case in Ruby; the API uses camelCase JSON.

Errors

Every non-2xx response raises a typed error. Postio::Error is the base.

begin
  client.address.postcode("not-a-postcode")
rescue Postio::ValidationError => e
  puts "#{e.status} #{e.error_code}: #{e.message} (request_id: #{e.request_id})"
rescue Postio::RateLimitError => e
  puts "rate limited; retry in #{e.retry_after} seconds"
end
Class HTTP
Postio::ValidationError 400 / 422
Postio::InvalidKeyError 401
Postio::OutOfCreditError 402
Postio::ForbiddenError 403
Postio::NotFoundError 404
Postio::RateLimitError 429 (#retry_after)
Postio::ServerError 5xx
Postio::TimeoutError local request timeout
Postio::ConnectionError transport error

Every error carries status, error_code, details, request_id, and the raw envelope.

Configuration

client = Postio::Client.new(
  api_key:  "pk_live_...",
  base_url: "https://api.postio.co.uk/v1",  # default
  timeout:  10,                              # seconds
  retries:  2,                               # 0 to disable
  headers:  { "x-tracking-id" => "..." }
)

Default retry policy: 2 retries on 408/409/429/5xx + network/timeout, exponential backoff with full jitter (0.5s → 8s cap).

Frameworks

The SDK is framework-agnostic. Cache one Postio::Client per process — it's safe for concurrent use under MRI / YJIT / Truffle.

Rails — initialiser:

# config/initializers/postio.rb
POSTIO = Postio::Client.new(api_key: Rails.application.credentials.postio_api_key)

License

MIT — see LICENSE.

Postio is a trading name of Onno Group Limited, registered in England & Wales (company no. 08622799). Registered office: Suite 22 Trym Lodge, 1 Henbury Road, Westbury-On-Trym, Bristol BS9 3HQ.