Schema guide

August 4, 2026 · View on GitHub

Field-by-field notes on schema/operators.schema.json, and the reasoning behind the choices that are not obvious.

Why the hierarchy is host-based

An MVNO's single most important property is whose radio network it is actually on. It determines coverage, real-world speed, which bands a handset needs, and what happens to the subscriber if the host is acquired. Making that relationship the tree structure means the answer cannot be missing: an MVNO record only exists somewhere.

host_mno duplicates it as a field. That is deliberate — a record lifted out of the tree (a jq filter, a database row) has to stay self-describing. scripts/validate.py errors if an MVNO is nested under an operator its host_mno does not name, so the duplication cannot drift.

Top-level

{ "meta": {...}, "operators": [...], "out_of_scope_plmn": [...], "sources": [...] }

operators holds only operators that own a radio network, hold spectrum, or both. Retail-only brands never appear here — the schema does not forbid it, but the validator does.

out_of_scope_plmn is the disposal ground for MCC 425 codes that are not Israeli retail mobile brands. It exists because MCC 425 is shared with the Palestinian operators (Jawwal, Ooredoo Palestine) and because a good third of the Israeli assignments belong to telematics firms, government bodies, and infrastructure joint ventures rather than to anything you can buy a SIM from. Without this list, "425-25 is missing from your dataset" looks like a gap rather than a decision.

sources is a register keyed by id. Every sources: [...] array anywhere in the document holds ids into it, and the validator fails on an unknown id and warns on a registered source that nothing cites.

Operator record

id

Lowercase slug, the join key. Referenced by host_mno, network.ran_sharing_with and band.shared_with. Do not renumber or rename these casually.

name

en is required. he carries the Hebrew trading name, which is what appears on Israeli retail material and in Hebrew-language regulatory documents. legal is the registered entity as it appears in ITU records, and it frequently differs from the brand — HOT Mobile is Mirs Ltd., 019 Mobile is Azi Communications Ltd., Home Cellular is Home Cellular Ltd. Searching the ITU list for a brand name will miss these. former catches renames that still turn up in older records (Partner was Orange; Marathon 018 Xphone traded as We4G).

operator_type

MNO or MVNO, as requested — either/or, no third value. The Israeli market makes this genuinely ambiguous for two operators, so where the call is arguable the record carries a classification_note explaining it rather than pretending it was clear. See market-structure.md.

carrier_id

Nullable. plmn must equal mcc concatenated with mnc; the validator enforces it and also rejects duplicate PLMNs across the dataset.

additional_plmn holds further codes operated by the same entity. Two cases in this dataset: legacy identities (HOT Mobile's 425-77, which appears in old community lists but not in the current ITU list) and shared infrastructure identities (425-28, PHI Networks, the Partner/HOT joint radio network, which is recorded on both parents).

carrier_id: null is a real answer, not a gap. A light MVNO with no core network of its own operates entirely under the host's PLMN and has no code to record. YouPhone is the example here.

host_mno

Required for MVNOs. Also set — and this is the unusual part — on MNOs that hold spectrum but ride a partner's radio network. Golan Telecom and Marathon 018 Xphone are both operator_type: MNO with host_mno: cellcom.

frequencies_4g / frequencies_5g

{ "inherits_from_host": false, "bands": [ { "band": "n78", ... } ] }

When inherits_from_host is true, bands must be empty and a host_mno must be set. The validator enforces both. The point is that there is exactly one place to correct a band list: duplicating the host's bands onto every MVNO would guarantee that some of the copies go stale after the next refarming.

Band objects:

  • band — 3GPP designation, B<n> for LTE and n<n> for NR.
  • label_mhz — conventional label (1800 for B3). Convenient, redundant, worth having.
  • range_mhz — actual block edges where known. Populated for n78 (3500–3800).
  • bandwidth_mhz — for FDD this is the paired figure. A 2×10 MHz assignment is recorded as 10, not 20. Israeli auction reporting uses the 2× form, so this is the most likely place to introduce a factor-of-two error.
  • status — live / planned / retired / unknown. Retired bands stay in the record rather than being deleted; the 2G/3G shutdown makes the difference between "never held" and "held until 2025" worth preserving.
  • shared_with — operator ids holding or using the same block. This is how the two spectrum-sharing groups are expressed at band level.

subscribers_est

Nullable, and null for most MVNOs — none of them publish, and no Israeli regulator publishes per-MVNO figures.

basis matters as much as value. Israeli operators report on different bases, and the group-versus-brand distinction is a live trap: Cellcom's figures may or may not fold in Golan Telecom, and Partner's may or may not fold in 012 Mobile, depending on the source. range records the spread where sources disagree; the validator checks value falls inside it.

Pelephone's figure is the only confirmed one, coming from Bezeq's reporting as a listed company. Everything else is a press estimate.

status

active, brand_only, dormant, merging, defunct.

brand_only is for a name still sold to customers that is no longer an independent business — Golan Telecom since 2020. merging marks an announced but incomplete acquisition, which is HOT Mobile's current state and the reason its record carries a re-verify warning.

network

owns_ran and holds_spectrum are separate booleans on purpose, because in Israel they come apart in both directions. Golan holds spectrum without a network. PHI Networks runs a network that neither of its parents solely owns.

ran_sharing_with is radio network sharing. It is deliberately not used for the 2022 Ministry of Communications approval covering passive infrastructure — sites, masts, power — between Cellcom, Pelephone and PHI Networks. Site sharing does not change who transmits on which band, and conflating the two would produce a wrong picture of Israeli network independence. That arrangement is recorded in network.notes instead.

disputed

Where sources contradict each other, each claim is listed with its own sources and resolution records which one the dataset adopted and why, or null if unresolved. The validator warns on unresolved disputes. This is the mechanism that keeps a single weak source from silently becoming a fact.

classification_note

Free text, used only where the MNO/MVNO call is genuinely arguable. Two records use it. Better to state the judgement than to bury it.

Validation

python3 scripts/validate.py [FILE]

Pass 1 is JSON Schema. Pass 2 checks what a schema cannot: id resolution across host_mno / shared_with / ran_sharing_with / every sources array, PLMN arithmetic and uniqueness, MVNO nesting agreeing with host_mno, inherits_from_host consistency, and subscribers_est.value inside subscribers_est.range.

Errors set the exit code; warnings do not. Warnings cover the softer problems: unresolved disputes, records with no last_verified, sources registered but never cited.