RESEARCH DATA & API
Truth Observatory collects public scientific data streams, stores them unchanged with a hash of every record, and serves measured series back out for analysis. This page explains how to get the data, what each field means, what the data cannot tell you, and how to verify and cite it.
1. WHO CAN ACCESS WHAT
The measured series, discrete events, anchor receipts and feed status are free and need no account or key. The raw per-feed archives and the correlation output need a subscription, because they are what pays for collection and storage.
| DATA | ACCESS | ENDPOINT |
|---|---|---|
| Measured time series (Kp, Dst, solar wind, magnetometers, grid demand, …) | FREE | /api/signals/<id> |
| Discrete events (earthquakes, flares, wildfire starts, volcano alerts) | FREE | /api/signals/events/<kind> |
| Feed status and collection health | FREE | /api/feeds |
| Hourly hash anchor receipts | FREE | /api/anchors |
| 5G coverage (carrier-reported, FCC) | FREE | /api/coverage |
| Sealed daily raw archives (every record each collector wrote) | SUBSCRIBER | /api/archive/<feed>/<day> |
| Recent raw records per feed | SUBSCRIBER | /api/feed/<feed> |
| Cross-feed correlations | SUBSCRIBER | /api/correlations |
Working on a funded or academic project that needs bulk raw archives? Email team@dwsc.io with a short description.
2. QUICK START
BROWSER OR SPREADSHEET
Paste a URL with format=csv to download a table. For example, the last 30 days of the planetary Kp index:
https://observatory.tlid.io/api/signals/kp?from=2026-09-21&format=csv
PYTHON (PANDAS)
import pandas as pd
base = "https://observatory.tlid.io/api/signals"
kp = pd.read_csv(f"{base}/kp?from=2025-01-01&to=2025-12-31&format=csv", parse_dates=["key"])
# Events are paged: follow `next` until it is null
import requests
url, quakes = f"{base}/events/quake?from=2025-01-01&minmag=5", []
while url:
page = requests.get(url if url.startswith("http") else "https://observatory.tlid.io" + url).json()
quakes += page["events"]
url = page["next"]
R
kp <- read.csv("https://observatory.tlid.io/api/signals/kp?from=2025-01-01&format=csv")
CURL
curl -s "https://observatory.tlid.io/api/signals" | jq '.series | keys'
3. ENDPOINTS
All times are UTC, ISO 8601. All responses are JSON unless format=csv is given. CORS is open, so the API can be called from notebooks and browser tools.
GET /api/signals
The catalog: every series and event kind with its unit, time resolution, source, start year and the date range actually held (coverage.first / coverage.last). Also lists knownLinks, the pairs of series with an established physical link.
GET /api/signals/<id>
| PARAMETER | DEFAULT | MEANING |
|---|---|---|
from | 7 days before to | Start, ISO date or datetime (inclusive) |
to | now | End, ISO date or datetime (inclusive) |
format | json | csv for a table with header key,mean,min,max,n |
Each row is [key, mean, min, max, n]. key is the start of the time bin (YYYY-MM-DDTHH for hourly and 3-hourly series, YYYY-MM-DD for daily). n is how many source readings fell in that bin. The catalog field stat says which of mean, min or max is the standard summary for that quantity (for example min for Dst, because storms make it more negative).
GET /api/signals/events/<kind>
| PARAMETER | DEFAULT | MEANING |
|---|---|---|
from, to | last 30 days | Time window (max 732 days per request) |
minmag | none | Minimum magnitude, where the event has one |
limit | 20000 | Page size, 1 to 20000 |
offset | 0 | Index of the first event to return |
format | json | csv for a table (one column per field; id and t first) |
GET /api/feeds
Status of every collector. See feed status for what each value means.
GET /api/anchors?limit=48
The most recent hourly hash receipts (up to 500). See verify.
GET /api/coverage?carrier=&tier=&bbox=&zoom=
Carrier-reported 5G coverage as H3 hexagons with the share of each hexagon claimed. carrier is tmobile, att or verizon; tier is 7 (7/1 Mbps) or 35 (35/3 Mbps); bbox is south,west,north,east. Larger views return coarser hexagons; the response says which H3 resolution (res) was used.
4. SERIES CATALOG (LIVE)
Loaded from /api/signals when you open this page. The held column is what the archive contains right now, not just the source's start year.
| ID | QUANTITY | UNIT | RES | HELD | SOURCE |
|---|
| EVENT KIND | NAME | HELD | SOURCE |
|---|
5. LIMITS AND HONESTY FLAGS
No response is ever shortened without telling you.
- Date range caps. One request can cover at most 2 years of hourly data, 6 years of 3-hourly data, 100 years of daily data, or 732 days of events. If your
fromis earlier than that, the start is moved forward and the response has"clamped": truewith the realfrom. Split long ranges into several requests. - Event paging. Event responses include
total,offset,countandtruncated. Whentruncatedis true, fetchnextto get the following page. - CSV metadata. CSV downloads carry the same information in headers:
X-Range-From,X-Range-To,X-Clamped,X-Total,X-Truncated, and aLink: <…>; rel="next"header when there is another page. - Rate limits. Per IP address: 120 requests a minute to
/api/signals/…and/api/coverage, 600 a minute to other API routes. Over the limit you get HTTP429withRetry-After: 60. A full download of every series fits well inside this. - Gaps are gaps. A missing hour means no reading was received. Missing values are never filled, interpolated or carried forward.
6. WHAT FEED STATUS MEANS
| STATUS | MEANING |
|---|---|
live with sources: "ok" | The collector ran on schedule and its recent pulls returned data. |
live with sources: "partial" | The collector is running and some upstream sources answered, but at least one recent pull failed. Data is real but may be incomplete. |
| failing | The collector is running, but every recent pull from the upstream source failed (for example HTTP 403/404, or a facility that has closed). lastGood says when real data last arrived. |
| stale | The collector has written nothing for more than 3 times its normal interval. |
| offline | No records at all. |
Each record a collector writes is either an observation or a DATA-GAP entry with the reason the source failed. Gap entries are kept and hashed like everything else, so the record of outages is as verifiable as the data.
7. METHODS AND LIMITATIONS
COLLECTION
Each stream is fetched from its official public source on a fixed schedule (from 5 minutes to daily, depending on how often the source updates). Responses are recorded as received with a retrieval timestamp. Measured series are extracted into hourly, 3-hourly or daily bins keeping mean, min, max and reading count. History before live collection began comes from the long-term archives named in the catalog (GFZ Potsdam, NASA OMNI, USGS ComCat).
DERIVED NUMBERS — READ BEFORE USING
- AtmosCore is a convenience summary for the cockpit, not a scientific index. It combines the nearest NOAA airport station (within 100 miles), National Weather Service warnings at the point, and the planetary Kp index. Its 42-node design currently has live inputs for about 13 nodes. Do not use it as a dependent variable.
- Correlations are screening results, not findings. Pairs with an established physical cause are labelled known physics (see
knownLinks). Anything else is unexplained only in the sense that the engine has no listed mechanism; it has not been tested for confounders, autocorrelation or multiple comparisons. - 5G coverage is what carriers report to the FCC (Broadband Data Collection), modelled not measured, released twice a year. The share is the fraction of each hexagon's resolution-9 cells the carrier claims.
- Cell sites come from crowd-sourced phone readings (OpenCelliD); positions are estimates.
- Lightning (GOES GLM) covers the Americas and nearby oceans, not the whole planet. Ground-network lightning (Blitzortung) is volunteer-run and uneven in coverage.
- Ionospheric heaters and other facility feeds report what the facility publishes. Some facilities publish little or nothing, or have closed; their feeds will show
partialorfailing.
WHAT IS NOT BUILT
There is no anomaly catalog and no editorial interpretation layer. The Observatory records and serves data; it does not claim causes.
8. VERIFY THE DATA
Every record each collector writes is hashed. Once an hour the new records are folded into a Merkle root, and the top root is written to the TrustLayer chain. Anyone can check that an archive file has not changed since that hour.
- Download a feed's sealed archive for a day:
/api/archive/<feed>/<YYYY-MM-DD>(subscriber). Split it into lines, without the trailing newline. - Get the receipts from
/api/anchors?limit=500. They come in pairs per UTC hour: anANCHORrecord with the roots, and anANCHOR-RESULTrecord with the chaintxHashfor the sameroot. - In the
ANCHORrecord,feeds.<stem>givesday,lineFrom,lineTo(0-based, inclusive) and that feed'sroot. Take those lines, computeleaf = sha256(line)on the exact UTF-8 bytes, and fold pairwise withparent = sha256(leftHex + rightHex), concatenating the lowercase hex strings. An odd node is paired with itself. The result must equal the feed'sroot. - Top root: compute
sha256("<stem>:<feedRoot>")for every feed in the record, sort those hashes, and fold them the same way. The result must equal the record'sroot. - Look up the matching
ANCHOR-RESULT'stxHashathttps://chain.tlid.io/api/hash/<txHash>. ItsdataHashmust equal that root.
# obs-merkle-v1 in Python
import hashlib
h = lambda s: hashlib.sha256(s.encode()).hexdigest()
def root(leaves):
if not leaves: return ""
while len(leaves) > 1:
leaves = [h(leaves[i] + (leaves[i+1] if i+1 < len(leaves) else leaves[i]))
for i in range(0, len(leaves), 2)]
return leaves[0]
feed_root = root([h(line) for line in lines_in_range])
Receipts name feeds by their manifest stem, which can differ from the feed id used in the archive URL (for example the geomag feed is geomagnetic and earthquake is seismic in receipts). Each feed's stem is listed in /api/feeds as stem. The measured series in /api/signals are derived from those records; verifying a series value means checking the archive records it came from.
9. HOW TO CITE
Please cite both the Observatory and the original source of the data you used (listed per series in the catalog). Include the date you downloaded the data, because live series keep growing.
DarkWave Studios LLC (2026). Truth Observatory: archived public geophysical, space-weather and infrastructure data streams [Data set]. https://observatory.tlid.io. Accessed YYYY-MM-DD.
@misc{truth_observatory_2026,
author = {{DarkWave Studios LLC}},
title = {Truth Observatory: archived public geophysical, space-weather and infrastructure data streams},
year = {2026},
howpublished = {\url{https://observatory.tlid.io}},
note = {Data set. Accessed YYYY-MM-DD}
}
Upstream sources ask for these citations:
- Kp, sunspots, F10.7 (GFZ Potsdam): Matzka, J., Stolle, C., Yamazaki, Y., Bronkalla, O. and Morschhauser, A. (2021). The geomagnetic Kp index and derived indices of geomagnetic activity. Space Weather, 19, e2020SW002641. doi:10.1029/2020SW002641
- Sunspot number: SILSO World Data Center, Royal Observatory of Belgium, Brussels.
- OMNI (solar wind, IMF, Dst, AE history): acknowledge NASA/GSFC's Space Physics Data Facility OMNIWeb service.
- Earthquakes: U.S. Geological Survey, Earthquake Hazards Program, ComCat.
10. LICENSE
The Observatory's own compilation (the binned series, catalog, status records and anchor receipts) is released under Creative Commons Attribution 4.0 (CC BY 4.0). You may use, share and adapt it, including commercially, if you credit Truth Observatory as shown above.
The underlying measurements keep their original terms, which take precedence:
| SOURCE | TERMS |
|---|---|
| NOAA, NWS, SWPC, USGS, NASA, NIFC, EIA, FCC | US government works, public domain in the United States |
| GFZ Potsdam (Kp, F10.7) | CC BY 4.0 |
| SILSO sunspot number | CC BY-NC 4.0 (non-commercial) |
| OpenCelliD cell sites | CC BY-SA 4.0 |
| Blitzortung.org lightning | Non-commercial use only; not redistributed through this API |
| OpenSky Network aircraft | Research and non-commercial use; not redistributed through this API |
Data is provided as is, without warranty. It is not a substitute for official warnings. For life-safety decisions use the National Weather Service and local authorities. See also the terms of service.
11. CHANGES AND DATA-QUALITY NOTES
- 2026-10-21 · API v1 documented. Feed status separates
partialandfailingsources from healthy ones and reportslastGood. Signals responses addclamped, event paging (offset,limit,next) and CSV output. Public rate limits introduced. - 2026-10-21 · 5G coverage built from the FCC Broadband Data Collection release dated 2025-12-31.
- 2026-10 · GOES GLM lightning flash rate series begins.
- 2026-09 · Volcano alert series begins.
- 2026-08 · Wildfire and US grid demand series begin.
Found a problem in the data? Email team@dwsc.io with the series, time range and what you expected. Corrections are logged here.