NotebookIntermediate. Receive-only; no licence or transmitting equipment needed.

Join transmitters to catalog records

No single database holds both what a satellite transmits and where it is. This notebook joins SatNOGS DB to OrbitalWiki on the NORAD catalog number, charts the bands you could actually receive, and ends at a real TLE.

radiotransmitterssatnogsjoinslicensing
Runtime
30 min
API requests
7

Download

Jupyter notebook, 20 cells, 15 KBDownload the notebook

.ipynb file. Nothing executes until you run it.

Anonymous callers share 50 requests per day per network. A free account raises that to 1,000 per day. Each notebook states what one full run costs.

How to run it

  1. 1Install the packages listed above, for example: pip install requests pandas matplotlib
  2. 2Open Jupyter (jupyter lab) with the downloaded .ipynb, or upload it to any hosted notebook service.
  3. 3Run the cells top to bottom. No API key is needed; add one in the first cell if you want the higher limit.

What you will learn

  • Join two independently maintained datasets on a key neither of them owns.
  • Convert transmitter frequencies into amateur bands using stated thresholds rather than a supplied label.
  • Separate "the transmitter is believed to work" from "you will hear it".
  • Comply with both licences at once when redistributing a joined dataset, including a share-alike one.

Before you start

  • pandas joins and value counts.
  • No amateur radio licence and no receiver required; this notebook only reads data.

Python packages

pip install requests pandas matplotlib

Which data

Six amateur spacecraft (25544, 43017, 27607, 39444, 40967, 44909) joined against SatNOGS DB, which is a separate project with its own quota and its own licence. OrbitalWiki has no public transmitter endpoint, so the notebook goes to that upstream directly rather than pretending one exists.

Endpoints it calls

Every request the notebook makes, and why. Nothing here is illustrative: these are the calls it runs.

  • GET /api/v1/satellites/{norad_cat_id}The catalog record for each of six amateur spacecraft.
  • GET /api/v1/satellites/{norad_cat_id}/tleCurrent reconstructed two-line elements, to hand off to a pass prediction.
/api/v1/openapi.json →

From the notebook

Excerpts copied verbatim from the file. A test fails if the notebook changes and these do not.

code
def band_of(hz):
    """Band name from a frequency in hertz. None when outside the modelled range."""
    if hz is None or hz <= 0:
        return None
    mhz = hz / 1e6
    if mhz < 30:
        return "HF"
    if mhz < 300:
        return "VHF"
    if mhz < 1000:
        return "UHF"
markdown
The join key is the NORAD catalog number, and it is the right key precisely because neither project owns it: it is assigned by the US Space Force and both databases inherit it. Joining on *name* would fail immediately, because OrbitalWiki calls one of these `SAUDISAT 1C (SO-50)` and the amateur community calls it `SO-50`.

What you end up with

  • A joined table of 60-odd transmitter rows carrying orbit, mode, downlink in MHz and band.
  • A bar chart of active transmitters by band, dominated by VHF and UHF for a reason the notebook explains.
  • A freshness table showing when each transmitter record was last confirmed by a human.
  • A real TLE with its epoch, and the two limits on what a pass prediction can promise.

How to cite

Both licences travel with the joined table: "Transmitter data from SatNOGS DB contributors (CC BY-SA 4.0), joined to OrbitalWiki catalog records (ODbL-1.0) on NORAD catalog number, retrieved 2026-08-04." Share-alike is the obligation people forget.

Sources