Hellio Messaging - Official Ruby SDK
Ruby client for the Hellio Messaging API v1:
SMS, OTP (SMS / email / voice), Voice broadcasts, Number Lookup (HLR),
Email Verification, Pricing, Balance, and Webhooks. It uses only
the Ruby standard library (net/http and json), so there are no runtime
dependencies.
Install
gem install hellio-messaging
Or with Bundler, add to your Gemfile:
gem "hellio-messaging"
then run bundle install.
Configure
Generate a token in your dashboard (Settings -> API -> Generate API token), then create a client. You can pass values directly or set environment variables.
require "hellio"
client = Hellio::Client.new(
token: "your-token-here",
default_sender: "HellioSMS"
)
Environment variables are read as fallbacks when an option is omitted:
HELLIO_BASE_URL=https://api.helliomessaging.com/v1
HELLIO_API_TOKEN=your-token-here
HELLIO_DEFAULT_SENDER=HellioSMS
client = Hellio::Client.new # reads HELLIO_API_TOKEN, HELLIO_BASE_URL, HELLIO_DEFAULT_SENDER
Optional constructor options: base_url (defaults to
https://api.helliomessaging.com/v1), timeout (seconds, default 30), and
http (a custom HTTP adapter, mainly for tests).
Every call returns the decoded JSON as a Hash with string keys (payloads are
under the "data" key). Non-2xx responses raise a typed error (see below).
Usage
# Account
client.balance # {"data" => {"balance" => "195.0000", "available" => "194.65", ...}}
client.pricing("GH") # optional ISO-2 country filter
# SMS (recipients: string, comma list, or array)
client.sms("233241234567", "Hello!")
client.sms(["233241234567", "233201234567"], "Hi all", sender: "HellioSMS")
client.(1024) # delivery status
client.campaign(1024) # campaign summary
# OTP - sender (Sender ID) is REQUIRED for sms/voice and must be approved on your account.
# Optional length (4-10 digits) and expiry (minutes). Returns status "queued".
client.otp("233241234567", sender: "HellioSMS") # SMS
client.otp("233241234567", sender: "HellioSMS", channel: "voice") # Voice (TTS reads the code)
client.otp("233241234567", sender: "HellioSMS", length: 6, expiry: 10)
client.otp("user@example.com", channel: "email") # Email (no sender)
client.verify("233241234567", "123456") # true / false
client.verify_otp("user@example.com", "123456", channel: "email") # full response
# Voice broadcast - text (we TTS it) or a hosted audio_url
client.voice("233241234567", "HELLIO", text: "Your code is 1 2 3 4")
client.voice(["233241234567"], "HELLIO", audio_url: "https://cdn.example.com/promo.mp3")
# Number lookup (HLR) - async; poll results
client.lookup(["233241234567"])
client.lookups
client.lookup_result(5)
# Email verification
client.verify_email(["user@gmail.com", "bad@nodomain.invalid"])
# Webhooks (receive delivery reports)
client.create_webhook("https://your-app.com/hooks/hellio", events: ["message.delivered", "message.failed"])
client.webhooks
client.delete_webhook(1)
Recipient inputs (sms, voice, lookup, verify_email) accept a single
string, a comma-separated string, or an array. They are normalized to a list
before the request is sent.
Error handling
Non-2xx responses raise typed errors (all subclass Hellio::Error). Each error
carries status_code and the parsed response body; ValidationError also
exposes field-level details through #errors.
| Error | Status |
|---|---|
Hellio::InvalidApiTokenError |
401 |
Hellio::InsufficientBalanceError |
402 |
Hellio::ValidationError (#errors) |
422 |
Hellio::RateLimitError |
429 |
Hellio::Error |
other |
begin
client.sms("233241234567", "Hi")
rescue Hellio::InsufficientBalanceError => e
# top up
rescue Hellio::ValidationError => e
e.errors # field-level messages
e.status_code # 422
e.response # full parsed body
end
Rate limit: 120 requests/minute per token.
Development
bundle install
bundle exec rake spec
Tests use RSpec and WebMock to mock the HTTP layer.
License
MIT. See LICENSE.