# Indonesia phone numbers: format, mobile prefixes, validation and messaging rules

> Indonesian numbers: the +62 format, why mobiles have 9 to 12 digits, the 08XX prefixes, tested validation code, no mobile porting, and Komdigi's 2026 SIM registration rules.

Canonical: https://mobilevalidate.com/blog/indonesia-phone-number-format · Last updated: 2026-11-04

![A +62 chip over island clusters drawn as stacked strokes of different lengths along a dashed equator, a ladder of 9, 10, 11 and 12 digit rows all marked valid, an ID card and a face tile beside a SIM marked 3, and a porting swap marked no.](https://mobilevalidate.com/images/blog/indonesia-phone-number-format.svg)

*Indonesian mobile numbers vary in length, and each SIM is registered by ID and face.*


By MobileValidate team (https://mobilevalidate.com/about) · Published: 2026-11-04 · Category: Guides · Tags: Indonesia, Phone validation, E.164, MNP, SMS, Compliance

Indonesian numbers use the country code +62. Mobile numbers have 9 to 12 digits after the code and start with 81–83 or 85–89 (08XX… when dialled at home); in E.164 they look like +62 812 XXXX XXXX. Because we found no mobile number portability in force, the 08XX block still points to the operator it was allocated to, and every prepaid SIM must be registered to its holder's identity, now with face recognition under a 2026 regulation.

This guide is part of our [phone numbers by country](/blog/phone-numbers-by-country) series. The tables are generated from libphonenumber's metadata, our [MNP atlas](/datasets/mnp-atlas-2026) and our public catalog. Example numbers are masked with X. The website of the Ministry of Communication and Digital Affairs (Komdigi, formerly Kominfo) refused requests from our server, so we read the regulations in its official legal database (JDIH) on 2026-09-27. Regulatory powers sit with the ministry: the telecom regulatory body BRTI was dissolved by Presidential Regulation 112 of 2020 ([JDIH](https://jdih.komdigi.go.id/produk_hukum/view/id/817/t/peraturan-presiden-nomor-112-tahun-2020)). This is a summary, not legal advice.

## What does an Indonesian phone number look like?

A mobile number is written `08XX-XXXX-XXXX` at home: the trunk prefix `0`, an operator code starting with `8`, then the subscriber number. From abroad it is `+62 8XX XXXX XXXX`. Landlines use an area code such as `21` for Jakarta.

<!-- country-data:ID:format:start -->
<!-- generated by apps/web/scripts/gen-country-guide-data.mjs (libphonenumber metadata 9.0.39 via libphonenumber-js 1.13.13); edit the script, not this table -->

| Item | Value |
|---|---|
| Country calling code | `+62` |
| International call prefix (dialling out) | `00[89]` (pattern: more than one prefix is used) |
| Trunk prefix (dialling at home) | `0` |
| Mobile: digits after +62 | 9–12 |
| Fixed line: digits after +62 | 7–11 |
| Toll-free: digits after +62 | 8–17 |
| Premium rate: digits after +62 | 10 |
| Shared cost: digits after +62 | 10 |
| Universal access (UAN): digits after +62 | 7, 10 |
| Mobile, national format (masked) | `081X-XXX-XXX` |
| Mobile, international (masked) | `+62 81X XXX XXX` |
| Mobile, E.164 (masked) | `+6281XXXXXXX` |
| Fixed line, national format (masked) | `(023X) XXXXXXXX` |
| Fixed line, international (masked) | `+62 23X XXXXXXXX` |
| Fixed line, E.164 (masked) | `+6223XXXXXXXXX` |
<!-- country-data:ID:format:end -->

Two things stand out. The mobile length is a range, 9 to 12 digits after `+62`, and Indonesia dials out through operator-specific international prefixes (the metadata's pattern is `00[89]`), not a plain `00`. Store only the E.164 form (`+628…`).

### Why the length varies

Indonesia's national numbering plan, part of the 2018 Fundamental Technical Plan (Permenkominfo 14/2018), allocates each cellular operator a three-digit national destination code starting with `8`. It then leaves the subscriber number to the operator: each operator decides how many digits its numbers have, up to the maximum length of an E.164 number ([Permenkominfo 14/2018](https://jdih.komdigi.go.id/produk_hukum/view/id/620/t/peraturan-menteri-komunikasi-dan-informatika-nomor-14-tahun-2018-tanggal-2-oktober-2018)). So `0812-345-678` and `0812-3456-7890` both have valid lengths. Any check that expects one fixed length will reject valid customers.

## Which prefixes are mobile numbers?

The generator counted every number of 9 to 12 digits that libphonenumber's mobile pattern for `ID` accepts:

<!-- country-data:ID:prefixes:start -->
<!-- generated by apps/web/scripts/gen-country-guide-data.mjs (exact count over the mobile pattern, libphonenumber metadata 9.0.39); edit the script, not this table -->

| National prefix | International | Share of the block that is mobile (9–12-digit numbers) | 3-digit sub-blocks that aren't fully mobile |
|---|---|---|---|
| `081` | `+62 81` | 100% | — |
| `082` | `+62 82` | 100% | — |
| `083` | `+62 83` | 100% | — |
| `085` | `+62 85` | 100% | — |
| `086` | `+62 86` | 100% | — |
| `087` | `+62 87` | 100% | — |
| `088` | `+62 88` | 100% | — |
| `089` | `+62 89` | 100% | — |
<!-- country-data:ID:prefixes:end -->

Every block from `081` to `089` is fully mobile except `084`, which the metadata doesn't treat as mobile. `080` isn't mobile either: `0807` is a universal access (UAN) range, as row 10 of the tests shows.

## How do I validate an Indonesian number in code?

Use a libphonenumber port with full metadata and the default region `ID`. Because Indonesians dial out with operator codes, the library doesn't strip a plain `00`, so turn a typed `0062…` into `+62…` first.

**JavaScript** (`npm install libphonenumber-js`):

```js
import { parsePhoneNumberFromString } from "libphonenumber-js/max";

/** "0812-…", "+62 812 …", "0062 812 …" → E.164 for an Indonesian mobile, or null. Length varies: 9–12 digits after +62. */
export function normalizeId(raw) {
  // Indonesia dials out with 00X codes (the metadata knows 008 and 009), so a plain "00" isn't stripped.
  const input = String(raw).trim().replace(/^00(?=\s*62)/, "+");
  const phone = parsePhoneNumberFromString(input, "ID");
  return phone?.isValid() && phone.country === "ID" && phone.getType() === "MOBILE" ? phone.number : null;
}
```

**Python** (`pip install phonenumbers`):

```python
import re

import phonenumbers
from phonenumbers import NumberParseException, PhoneNumberFormat, PhoneNumberType


def normalize_id(raw: str) -> str | None:
    """E.164 for an Indonesian mobile, or None. 9 to 12 digits after +62 are all valid lengths."""
    raw = re.sub(r"^00(?=\s*62)", "+", raw.strip())
    try:
        n = phonenumbers.parse(raw, "ID")
    except NumberParseException:
        return None
    if (not phonenumbers.is_valid_number(n) or phonenumbers.region_code_for_number(n) != "ID"
            or phonenumbers.number_type(n) != PhoneNumberType.MOBILE):
        return None
    return phonenumbers.format_number(n, PhoneNumberFormat.E164)
```

We ran both on 2026-09-27 (libphonenumber-js 1.13.13 with metadata 9.0.39, Python phonenumbers 9.0.40). Both returned an E.164 number for rows 1 to 5 and row 7 below, and nothing for the rest. The last column is the bare library, without the `00` rewrite. The shape regex column tests the pattern most tutorials give:

<!-- country-data:ID:tests:start -->
<!-- generated by apps/web/scripts/gen-country-guide-data.mjs (libphonenumber-js 1.13.13, region ID); edit the script, not this table -->

| # | Case | Input (masked) | Shape regex `^(?:\+62\|0062\|0)?8\d{8,11}$` | libphonenumber (`ID`) |
|---|---|---|---|---|
| 1 | National, with trunk prefix | `081X-XXX-XXX` | passes | valid, `MOBILE` |
| 2 | International, with spaces | `+62 81X XXX XXX` | passes | valid, `MOBILE` |
| 3 | International dialling prefix 00 | `0062 81X-XXX-XXX` | passes | invalid |
| 4 | E.164 | `+6281XXXXXXX` | passes | valid, `MOBILE` |
| 5 | Dashes and brackets | `(081X) XXX-XXX` | passes | valid, `MOBILE` |
| 6 | One digit short | `081XXXXXX` | fails | invalid |
| 7 | One digit too many | `081XXXXXXXX` | passes | valid, `MOBILE` |
| 8 | Mobile shape, unused block 080 | `080XXXXXXX` | passes | invalid |
| 9 | Fixed line | `(023X) XXXXXXXX` | fails | valid, `FIXED_LINE` |
| 10 | Universal access (UAN) range | `080X X XXX XXX` | passes | valid, `UAN` |
<!-- country-data:ID:tests:end -->

Read row 7 carefully: "one digit too many" is still a valid Indonesian mobile, because a longer number is a legal length in the same block. Length alone can't tell you a number is wrong here; only the block and the range of lengths can. Row 10 is the regex's blind spot: `0807` has the mobile shape but is a UAN range. More languages are in our [Python](/blog/phone-number-validation-python) and [JavaScript](/blog/phone-number-validation-javascript) guides.

## Does number portability change the carrier?

Not as far as we can find. The 2018 numbering plan describes number portability, the ability to change operator and keep the number, and says it will be introduced in stages under a separate ministerial regulation outside the plan. On 2026-09-27 we found no regulation introducing mobile number portability in Komdigi's legal database, and we found none announced by 2026-11-03; and the 2021 telecommunications regulation (Permenkominfo 5/2021) doesn't mention it. That is why our atlas has no Indonesian row:

<!-- country-data:ID:mnp:start -->
<!-- generated by apps/web/scripts/gen-country-guide-data.mjs (MNP atlas 2026); edit the script, not this table -->

Our [MNP atlas](/datasets/mnp-atlas-2026) has no verified row for Indonesia yet.
<!-- country-data:ID:mnp:end -->

So, unlike most countries in our [MNP atlas](/blog/mobile-number-portability-atlas), the `08XX` block does mostly map to the network that serves the number today. Treat that as a finding dated 2026-11-03, not a guarantee: a range can still change hands, for example when operators merge, and regulations change. If the operator matters for routing or fraud rules, a lookup is still the reliable answer.

Numbers do get reused. The numbering plan requires at least 60 calendar days between a number being given up and being handed to a new subscriber. Our post on [number recycling and list decay](/blog/number-recycling-and-list-decay) explains why old lists go stale.

## Which messaging apps and channels reach people?

SMS reaches every active mobile. For WhatsApp, Meta prices Indonesia as its own market, and Indonesia was the first of the 18 markets that now have an authentication-international rate. Meta charges that rate to eligible businesses based in another country that send one-time passwords to Indonesian numbers, once they send more than 750,000 messages outside customer service windows in a moving 30-day period to such countries ([Meta pricing](https://developers.facebook.com/docs/whatsapp/pricing), read on 2026-11-03). Our [WhatsApp OTP vs SMS OTP](/blog/whatsapp-otp-vs-sms-otp-cost) post shows how to compare cost per verified user.

We found no primary source for app usage shares in Indonesia that we could verify, so we don't quote any. Check which apps your own opted-in customers use and route from that, with SMS as the fallback. Our [channel-by-country guide](/blog/choosing-a-messaging-channel-by-country) shows the method.

## What are the rules for SMS, sender IDs and OTP?

These summarise Komdigi's regulations as we read them in JDIH on 2026-09-27. Not legal advice; ask counsel how they apply to you.

### SIM registration with NIK and face recognition (2026)

Komdigi Regulation 7 of 2026 on registering cellular subscribers, set on 19 January 2026, replaced the registration articles of Permenkominfo 5/2021 ([Permenkomdigi 7/2026](https://jdih.komdigi.go.id/produk_hukum/view/id/1001/t/peraturan-menteri-komunikasi-dan-digital-nomor-7-tahun-2026)):

- **Know your customer.** Operators must apply KYC to registration and are responsible for the validity of each registration, using biometric technology.
- **Identity.** Indonesian citizens register with their population identity number (NIK) and face recognition. Foreigners register with a passport or a permanent or temporary residence permit (KITAP or KITAS).
- **Inactive starter packs.** SIM cards must be sold inactive, by everyone who sells them, until they are registered.
- **Three prepaid numbers per identity per operator.** Exceptions cover M2M and IoT, operator testing, and organisations; numbers registered beyond three under an exception must go through an operator outlet.
- **Check your numbers.** Operators must offer a way to check which numbers are registered to an identity.
- **Transition.** For six months after the regulation was promulgated, self-registration could still use the NIK and family card number. That transition ended in July 2026. Numbers registered before it stay valid.

### Marketing SMS: an opt-out the operator must offer

Permenkominfo 5/2021 (chapter XIV, articles 176 to 181) covers marketing SMS sent by mobile operators, their partners and content providers ([Permenkominfo 5/2021](https://jdih.komdigi.go.id/produk_hukum/view/id/768/t/peraturan-menteri-komunikasi-dan-informatika-nomor-5-tahun-2021)):

- they must offer every mobile subscriber the option to refuse marketing SMS, and send the information about that option;
- they may not send marketing SMS to a subscriber who refuses; read literally, article 180 also bars it where the subscriber has made no choice;
- violations are sanctioned and published on the ministry's website.

These rules were not replaced in 2026, and they stay in force.

### Sender IDs

We found no Komdigi register of alphanumeric sender names for business SMS comparable to Saudi Arabia's or the UAE's. Operators and aggregators set their own requirements by contract, so ask your SMS provider what it needs for Indonesian routes.

### What that means for OTP

A one-time passcode the user asked for isn't a marketing SMS. Keep it that way: no offers or promotional links, a sender your provider has set up for transactional traffic, and no marketing to numbers collected for verification unless the person opted in.

## What changed recently?

The rows for `ID` and `+62` in our [numbering-plan changes dataset](/datasets/numbering-plan-changes-2019-2026), built from libphonenumber's release notes:

<!-- country-data:ID:changes:start -->
<!-- generated by apps/web/scripts/gen-country-guide-data.mjs (rows of content/datasets/numbering-plan-changes-2019-2026); edit the script, not this table -->

| Change named in the release notes (2019-01-08 to 2026-09-23) | Releases |
|---|---:|
| Numbering-plan metadata (validation, lengths, types) | 3 |
| Alternate formatting | 1 |
| Short numbers | 1 |
| Original-carrier prefix data | 1 |
| All | 6 |

Latest numbering-plan updates for `ID`: 2024-09-04 (v8.13.45), 2020-10-07 (v8.12.11), 2019-04-02 (v8.10.9).
<!-- country-data:ID:changes:end -->

The numbering metadata for `ID` last changed in September 2024 (v8.13.45), so a library updated since then knows today's lengths and blocks. The rules changed more recently: the 2026 registration regulation with face recognition, and Komdigi Regulation 7 of 2025 on embedded SIMs (eSIM).

## What can MobileValidate check for Indonesian numbers?

Generated from our public catalog:

<!-- country-data:ID:coverage:start -->
<!-- generated by apps/web/scripts/gen-country-guide-data.mjs (public catalog https://api.mobilevalidate.com/v1/services, fetched 2026-11-03); edit the script, not this table -->

Catalog data as of 2026-11-03.

| Check | Accepts Indonesia numbers | Notes |
|---|---|---|
| Format and country (every lookup) | Yes | Each number is parsed first; an invalid number returns `invalid_number` and is never billed. |
| Carrier lookup (beta) | Yes | Line type and current network where data exists; no data means `unknown`, not billed. Real time and bulk. |
| US/CA carrier lookup (premium) | No (US, CA only) | Answers `unsupported_country` for other countries, not billed. |
| Live network status (HLR) | Yes | Live reachability, porting, roaming (true or false) and current network; `unknown` is free. Real time and bulk. |
| Number portability (MNP) | Yes | Ported or not ported, and the current network code; `unknown` is free. Real time and bulk. |
| Spam reputation | Limited access | All countries except sanctioned ones; report coverage is strongest in North America and Europe. |
| Messaging apps | Yes: WhatsApp, Telegram, Viber*, Signal*, iMessage*, RCS*, LINE*, Zalo*, Botim*, Facebook Messenger* | Registered, not registered or unknown; unknown is free. |
| Social networks | Yes: Facebook, Instagram, Threads, X (Twitter), TikTok*, Snapchat* | Not for Indonesia numbers: LinkedIn (US, IN only). |
| Online accounts (Apple, Amazon, Microsoft, Netflix) | Yes: Apple, Amazon, Microsoft, Netflix | Registered, not registered or unknown; unknown is free. |

\* bulk jobs only. The live list is at [`GET /v1/services`](https://api.mobilevalidate.com/v1/services).
<!-- country-data:ID:coverage:end -->

A lookup returns network and registration facts. It never returns a subscriber's name, NIK or address.

Here is a practical flow for verification: normalise with `normalize_id()`, then one real-time lookup ranks the channels to try. It uses the public sandbox key `mv_test_publicSandboxn9ZgneuhR1B9CRfKG3fulym` and our [test values](/docs/test-values), which are UK drama numbers because the sandbox accepts only those. With a live key, pass the output of `normalize_id()`. We ran it on 2026-09-27 with Python 3.12 and requests 2.31, and re-checked the sandbox answers on 2026-11-03.

```python title="id_channels.py"
import os

import requests  # pip install requests

API = "https://api.mobilevalidate.com/v1/lookup"
KEY = os.environ["MOBILEVALIDATE_API_KEY"]
APPS = ["whatsapp", "telegram"]  # in the order you prefer them


def channels(e164: str) -> list[str]:
    """Channels to try for one Indonesian mobile, best first. SMS always comes last as the fallback."""
    r = requests.post(API, headers={"Authorization": f"Bearer {KEY}"}, timeout=15,
                      json={"numbers": [e164], "checks": [*APPS, "carrier"], "wait": 5})
    r.raise_for_status()
    checks = r.json()["results"][0]["checks"]
    carrier = checks["network.carrier"]
    if carrier["status"] == "completed" and carrier["attributes"]["line_type"] != "mobile":
        return []  # not a mobile line: ask the user for another number
    found = [a for a in APPS if checks[f"{a}.registered"]["status"] == "completed"
             and checks[f"{a}.registered"]["registered"]]
    return [*found, "sms"]


for n in ["+447700900001", "+447700900002", "+447700900003"]:
    print(n, channels(n))
```

| Test value | Sandbox answer | Printed |
|---|---|---|
| `+447700900001` | WhatsApp and Telegram registered, carrier `line_type: "mobile"` | `['whatsapp', 'telegram', 'sms']` |
| `+447700900002` | neither app, carrier unknown (`NO_DATA`) | `['sms']` |
| `+447700900003` | everything unknown (`UPSTREAM_TIMEOUT`) | `['sms']` |

An unknown answer never removes SMS and is never billed. The same lookup with curl:

```bash
curl https://api.mobilevalidate.com/v1/lookup \
  -H "Authorization: Bearer $MOBILEVALIDATE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"numbers": ["+447700900001"], "checks": ["whatsapp", "telegram", "carrier"], "wait": 5}'
```

See [WhatsApp number check](/services/whatsapp-number-check), [Telegram number check](/services/telegram-number-check) and [carrier lookup](/services/carrier-lookup) for the fields, and [pricing](/pricing) for prices.

## What are the key takeaways?

- Indonesian mobiles are `+62 8` plus 8 to 11 more digits; the length is set per operator, so accept 9 to 12 digits after `+62`.
- The live blocks are `081`–`083` and `085`–`089`; `0807` is a UAN range, not mobile.
- Rewrite a typed `0062` to `+62` before parsing: Indonesians dial out with operator codes.
- We found no mobile number portability in force (2026-11-03), so the block usually shows the serving operator.
- Prepaid SIMs are registered with NIK and face recognition, at most three per identity per operator, and operators must let subscribers refuse marketing SMS.

Platform, regulator and company names are used descriptively. MobileValidate is not affiliated with any of them.

## Sources

1. [Peraturan Menteri Komunikasi dan Informatika Nomor 14 Tahun 2018 tentang Rencana Dasar Teknis (Fundamental Technical Plan) Telekomunikasi Nasional (2 October 2018)](https://jdih.komdigi.go.id/produk_hukum/view/id/620/t/peraturan-menteri-komunikasi-dan-informatika-nomor-14-tahun-2018-tanggal-2-oktober-2018) — Ministry of Communication and Digital Affairs (Komdigi, formerly Kominfo), JDIH legal database, 2018
2. [Peraturan Menteri Komunikasi dan Digital Nomor 7 Tahun 2026 tentang Registrasi Pelanggan Jasa Telekomunikasi melalui Jaringan Bergerak Seluler (19 January 2026)](https://jdih.komdigi.go.id/produk_hukum/view/id/1001/t/peraturan-menteri-komunikasi-dan-digital-nomor-7-tahun-2026) — Ministry of Communication and Digital Affairs (Komdigi), JDIH legal database, 2026
3. [Peraturan Menteri Komunikasi dan Informatika Nomor 5 Tahun 2021 tentang Penyelenggaraan Telekomunikasi (chapter XIV: marketing SMS)](https://jdih.komdigi.go.id/produk_hukum/view/id/768/t/peraturan-menteri-komunikasi-dan-informatika-nomor-5-tahun-2021) — Ministry of Communication and Digital Affairs (Komdigi, formerly Kominfo), JDIH legal database, 2021
4. [Peraturan Presiden Nomor 112 Tahun 2020 (dissolution of bodies including the Badan Regulasi Telekomunikasi Indonesia, BRTI)](https://jdih.komdigi.go.id/produk_hukum/view/id/817/t/peraturan-presiden-nomor-112-tahun-2020) — Ministry of Communication and Digital Affairs (Komdigi), JDIH legal database, 2020
5. [WhatsApp Business Platform pricing and authentication-international rates](https://developers.facebook.com/docs/whatsapp/pricing) — Meta for Developers, 2026
6. [libphonenumber PhoneNumberMetadata.xml (region ID) and release notes](https://github.com/google/libphonenumber/blob/master/resources/PhoneNumberMetadata.xml) — libphonenumber project (Apache License 2.0), 2026

## Frequently asked questions

### How many digits is an Indonesian mobile number?

Between 9 and 12 digits after the country code +62, so 10 to 13 digits when written nationally with the leading 0. The length varies because each operator sets the length of the numbers in its own 08XX block.

### What is the Indonesia country code for WhatsApp and international use?

+62. Drop the leading 0: 0812-XXXX-XXXX becomes +62 812 XXXX XXXX. Store that E.164 form and use it everywhere.

### Can Indonesians keep their mobile number when they change operator?

We found no mobile number portability in force. The 2018 national numbering plan says portability is introduced in stages under a separate ministerial regulation, and we found no such regulation for mobile numbers in Komdigi's legal database on 2026-09-27.

### How is a prepaid SIM registered in Indonesia?

Under Komdigi Regulation 7 of 2026, Indonesians register with their population identity number (NIK) plus face recognition, and foreigners with a passport or residence permit. Each operator may register at most three prepaid numbers per identity, with exceptions for IoT, testing and organisations.

### Can a lookup tell me who owns an Indonesian number?

No. The NIK and biometric data used to register a SIM stay with the operators. A MobileValidate lookup returns network and registration facts, never a name, NIK or address.
