Mobile, landline or VoIP: line types at signup
Every numbering plan divides its numbers into ranges and gives each range a line type: mobile, fixed line, toll-free, premium rate, VoIP and a few more. The range of a number is known the moment it is typed, without a call or a message. That is enough to refuse numbers that cannot receive a code or that cost money to reach. It is not enough to know who holds a number, or whether it is in service.
What the plans set apart
| Line type | Plans with such ranges, of 245 | A common choice at signup | Why |
|---|---|---|---|
mobile | 244 | accept | Receives text messages and calls. |
fixedLineOrMobile | 18 | accept | The plan cannot tell the two apart from the number; refusing would refuse every ordinary +1 number. |
fixedLine | 245 | refuse for a text, accept for a call | Most fixed lines cannot receive a text message. |
voip | 96 | your choice | Numbers in these ranges are cheap to obtain in quantity; many real people also have one. |
tollFree | 184 | refuse | The called party pays; rarely the line of the person signing up. |
premiumRate | 150 | refuse | A call or message to it costs the sender and earns the holder. |
sharedCost | 53 | refuse | Part of the cost of a call falls on the caller. |
personalNumber | 59 | refuse | A forwarding number, not a line: in the United Kingdom, 070 personal numbers look like 07 mobile numbers. |
pager | 23 | refuse | A one-way paging service. |
uan | 63 | refuse | A universal access number: one number for an organisation, routed to its lines. |
voicemail | 15 | refuse | Reaches a mailbox, not a person. |
VoIP ranges exist in 96 plans, among them France, the United Kingdom, Japan and Australia. Elsewhere VoIP services use ordinary geographic or mobile-range numbers, so a VoIP pattern only catches the ranges a plan sets aside.
+1: one pattern for mobile and fixed line
In Canada, Guam, the Northern Mariana Islands, Puerto Rico, the U.S. Virgin Islands and the United States, the mobile and fixed-line patterns are the same: area codes and exchanges serve both, so every ordinary number reads as fixedLineOrMobile. In 12 more plans, Chile, Denmark, the Dominican Republic, India, Jamaica, Mauritius, Mexico, Micronesia, St. Pierre & Miquelon, Tunisia, Uzbekistan and Wallis & Futuna, some ranges serve both. For +1 the allocation records go further: each central office code (the first six digits) is allocated to a carrier with a line type. The United States has 205,075 such codes on record, among them 101,552 fixed line, 66,155 mobile, 31,266 VoIP, on the United States page. That is the original allocation: numbers move between carriers when they are ported.
The check
After parse, the line type is a field of the number. The addition below accepts mobile numbers and the +1 numbers that may be mobile; add voip or fixedLine to the list if you take them. With the United Kingdom, the United States and France loaded:
| Number | Line type | Accepted at signup |
|---|---|---|
| +44 7400 123456 | mobile | yes |
| +44 121 234 5678 | fixedLine | no |
| +44 56 1234 5678 | voip | no |
| +44 901 234 5678 | premiumRate | no |
| +44 70 1234 5678 | personalNumber | no |
| +1 201-555-0123 | fixedLineOrMobile | yes |
| +1 900-234-5678 | premiumRate | no |
| +1 500-234-5678 | personalNumber | no |
| +33 6 12 34 56 78 | mobile | yes |
| +33 1 23 45 67 89 | fixedLine | no |
| +33 9 12 34 56 78 | voip | no |
| +33 891 12 34 56 | premiumRate | no |
Add it at the end of phone.mjs, the file from the JavaScript guide:
// Line types a signup takes: mobile, and the +1 numbers whose ranges serve both. Add voip or fixedLine if you take them.
const SIGNUP_TYPES = new Set(['mobile', 'fixedLineOrMobile'])
export const acceptAtSignup = (n) => SIGNUP_TYPES.has(n.type)Add it at the end of phone.py, the file from the Python guide:
# Line types a signup takes: mobile, and the +1 numbers whose ranges serve both. Add voip or fixedLine if you take them.
SIGNUP_TYPES = frozenset({"mobile", "fixedLineOrMobile"})
def accept_at_signup(number: PhoneNumber) -> bool:
return number.type in SIGNUP_TYPESAdd it inside the class in Phone.java, the file from the Java guide:
/** Line types a signup takes: mobile, and the +1 numbers whose ranges serve both. Add voip or fixedLine if you take them. */
public static final List<String> SIGNUP_TYPES = List.of("mobile", "fixedLineOrMobile");
public static boolean acceptAtSignup(PhoneNumber n) {
return SIGNUP_TYPES.contains(n.type());
}Add it at the end of phone.go, the file from the Go guide:
// SignupTypes are the line types a signup takes: mobile, and the +1 numbers whose ranges serve both.
// Add "voip" or "fixedLine" if you take them.
var SignupTypes = []string{"mobile", "fixedLineOrMobile"}
// AcceptAtSignup reports whether n's line type is one of SignupTypes.
func AcceptAtSignup(n Number) bool { return slices.Contains(SignupTypes, n.Type) }Add it inside the class in Phone.php, the file from the PHP guide:
/** Line types a signup takes: mobile, and the +1 numbers whose ranges serve both. Add voip or fixedLine if you take them. */
public const SIGNUP_TYPES = ['mobile', 'fixedLineOrMobile'];
public static function acceptAtSignup(array $number): bool
{
return in_array($number['type'], self::SIGNUP_TYPES, true);
}Add it inside the module in phone.rb, the file from the Ruby guide:
# Line types a signup takes: mobile, and the +1 numbers whose ranges serve both. Add voip or fixedLine if you take them.
SIGNUP_TYPES = %w[mobile fixedLineOrMobile].freeze
def self.accept_at_signup?(number)
SIGNUP_TYPES.include?(number.type)
endAdd it inside the class in Phone.cs, the file from the C# guide:
/// <summary>Line types a signup takes: mobile, and the +1 numbers whose ranges serve both. Add voip or fixedLine if you take them.</summary>
public static readonly string[] SignupTypes = { "mobile", "fixedLineOrMobile" };
public static bool AcceptAtSignup(PhoneNumber n) => SignupTypes.Contains(n.Type);Add it in src/phone.rs, before the tests, the file from the Rust guide:
/// Line types a signup takes: mobile, and the +1 numbers whose ranges serve both. Add voip or fixedLine if you take them.
pub const SIGNUP_TYPES: &[&str] = &["mobile", "fixedLineOrMobile"];
pub fn accept_at_signup(n: &PhoneNumber) -> bool {
SIGNUP_TYPES.contains(&n.kind)
}Sources: National numbering plans, ITU-T E.164 (ITU); North American Numbering Plan Administrator (NANPA); Canadian Numbering Administrator (CNAC). Plans as published on 2026-10-25.