NotebookResearch methods, senior undergraduate and above.

Trace a catalog value to its source

Every field on a record is a claim by somebody. This notebook separates the fields that carry a citable source from the fields that do not, then finds two catalogs giving different answers to the same question and shows why both are right.

provenanceconfidencedata-qualitylicensingcitation
Runtime
25 min
API requests
7

Download

Jupyter notebook, 24 cells, 16 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

  • Read a claim: its typed value slot, its confidence, its source, and the record id inside that source.
  • Work out which fields on a record have no per-field source, and why that is not the same as unreliable.
  • Find a field where two sources disagree, and describe the disagreement instead of resolving it by preference.
  • Identify every licence attached to a response before redistributing anything built from it.

Before you start

  • Comfortable with pandas DataFrames and crosstabs.
  • The first-API-request notebook, or equivalent familiarity with the response envelope.

Python packages

pip install requests pandas

Which data

Five live records chosen to span operators and eras: 25544, 20580, 39084, 43013 and 27607. Claims change as sources are re-ingested, so the disagreement the notebook finds today may be resolved later; the method is what transfers.

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 record plus its claims array, for five sample objects.
  • GET /api/v1/sourcesThe source inventory with licences and last-fetch times.
/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 flatten(claim):
    """Collapse the four typed value slots into one, keeping the provenance."""
    value = next(
        (claim[key] for key in
         ("value_text", "value_numeric", "value_date", "value_bool")
         if claim[key] is not None),
        None,
    )
    source = claim.get("source") or {}
markdown
`source_record` is the identifier *in the upstream catalog*, not here. `S25544` is GCAT's own designation. That is what makes a claim checkable: you can go to GCAT, look up `S25544`, and see whether this row reproduces it faithfully.

What you end up with

  • A flattened claims table with source slug, licence and upstream record id per field.
  • An explicit list of the record fields that carry no per-field claim, grouped by why.
  • A source-by-confidence crosstab read as coverage rather than quality.
  • The contested field/object pairs, with both values side by side.

How to cite

Cite the record, the field, the source slug from the claim, and the access date. Where two sources disagree, cite both: "OrbitalWiki, satellite 25544, launch_mass_kg, GCAT 20281 kg vs Wikidata 419725 kg, retrieved 2026-08-04".

Sources