itu-e164
itu-e164 is a dependency-free Ruby utility for strict, auditable validation of
canonical geographic-area numbers against Recommendation ITU-T E.164 (02/2026).
It is deliberately not a Rails validator and does not contact a carrier.
Installation
Add the gem to your bundle:
gem "itu-e164"
Then run bundle install.
Usage
require "itu/e164"
result = ITU::E164.check("+393331234567")
result.conformant? # => true
result.country_code # => "39"
result.national_number # => "3331234567"
result.category # => :geographic
result.standard_version # => "02/2026"
result.dataset_version # => "itu-t-e164-2026-07-15"
For a boolean:
ITU::E164.conformant?("+393331234567") # => true
For exception-based control flow:
result = ITU::E164.check!("+393331234567")
begin
ITU::E164.check!("0039 333 123 4567")
rescue ITU::E164::InvalidNumber => error
error.result.error_codes # => [:invalid_representation]
end
The accepted representation is intentionally strict: a String containing +
followed by ASCII decimal digits. Spaces, punctuation, 00, URI parameters, and
extensions are rejected. Normalize user input before this boundary and store
extensions separately.
Existing validation layers
The result is designed to be consumed without an Active Record dependency:
result = ITU::E164.check(value)
unless result.conformant?
errors.add(:phone_number, result.errors.map(&:message).join(", "))
end
With Twilio Verify, use this gem before sending a verification:
result = ITU::E164.check(candidate)
return validation_failure(result.errors) unless result.conformant?
twilio_verify(candidate)
The responsibilities stay separate:
itu-e164checks canonical representation, E.164 length and field structure, and the assigned geographic country-code snapshot.- Twilio Verify checks whether a user controls a reachable endpoint.
Exact scope
For profile: :geographic (the only profile in 0.1), a conformant result means:
- the input is canonical leading-plus notation;
- the E.164 digit sequence contains at most 15 digits;
- it starts with an assigned one-, two-, or three-digit geographic country code;
- at least one digit remains as the national (significant) number.
This is the complete E.164-level structure for the geographic category. E.164 leaves national destination-code and subscriber-number details to national numbering authorities.
Accordingly, this gem does not claim that:
- the national number range is allocated or currently active;
- the number is mobile, SMS-capable, reachable, or owned by a user;
- a national trunk prefix was correctly removed;
- one of E.164's seven non-geographic categories satisfies its service-specific numbering recommendation.
Assigned non-geographic country codes are recognized, but fail the geographic
profile with :profile_mismatch. Spare or unknown codes fail with
:country_code_unassigned.
Results and errors
ITU::E164.check always returns an immutable ITU::E164::Result. Invalid input
has one or more immutable ITU::E164::ValidationError values:
result = ITU::E164.check("+80012345678")
result.conformant? # => false
result.category # => :global_service
result.error_codes # => [:profile_mismatch]
result.to_h
Current error codes are:
:not_a_string:invalid_representation:too_long:country_code_unassigned:missing_national_number:profile_mismatch
Branch on error codes, not English messages.
Versioning and updates
The recommendation version and assignment dataset are exposed separately because a stable numbering structure can coexist with changing assignments. See SOURCES.md for provenance and the update procedure.
License
The gem is available under the MIT License.