Accuracy
How we validate every prediction
Every number on this page is checked against an independent, published reference on every build — not against our own prior output. Here's exactly what that means and where the numbers come from.
1. The SGP4 propagator itself: Vallado's reference vector
SGP4 is the standard model used to propagate a two-line element set (TLE) into a position and velocity. Every conforming SGP4 implementation — ours included — is checked against the same published verification vector from Vallado's canonical SGP4 test suite: satellite 00005, propagated to its own TLE epoch.
TLE epoch position (TEME): r = ( 7022.46529266, -1400.08296755, 0.03995155 ) km TLE epoch velocity (TEME): v = ( 1.89384101, 6.40589376, 4.53480725 ) km/s
Our propagation entry point reproduces this vector to within 10⁻³ km and 10⁻³ km/s — proof we're driving the underlying SGP4 math correctly, not that we've tuned anything to pass a test we wrote ourselves.
2. Orbit geometry: Kepler's third law
A satellite's TLE encodes its mean motion (revolutions per day). Kepler's third law fixes the orbit's size from that number alone — so a real orbit and our propagated one have to agree independently of anything SGP4-specific.
NOAA-20 (NORAD 43013): mean motion 14.19543782 rev/day → semi-major axis ≈ 7204 km (altitude ≈ 825 km) → orbital period ≈ 101 minutes
We check that the propagated geocentric radius and period land inside these physically derived bands, not just that they look plausible.
3. Earth's rotation: GMST against the IAU-1982 reference
Converting a satellite's inertial (TEME) position into a ground-relative one requires knowing exactly how far Earth has rotated — Greenwich Mean Sidereal Time (GMST). We check our GMST implementation against the published IAU-1982 reference value at the J2000.0 epoch, and against Earth's known sidereal rotation rate.
At J2000.0 (2000-01-01 12:00 UTC): GMST = 280.46° (18h 41m 50.5s) Sidereal rate: 15.041°/hour → 90.25° over 6 hours
If this drifts, every AOS/LOS time and every azimuth we report drifts with it — it's the single most consequential number in the whole pipeline, which is why it's checked against a fixed external constant rather than only against internal consistency.
4. Ground-station geometry: WGS84, not a spherical Earth
Azimuth and elevation depend on the observer's real position on an oblate ellipsoid (WGS84), not a sphere — the difference is small but non-zero away from the equator and the poles. We check hand-derived reference geometry: a satellite placed exactly on the observer's local vertical reads elevation 90.00°, one displaced due north reads azimuth ≈ 0°, one displaced due east reads azimuth ≈ 90°, and one on the far side of Earth reads well below the horizon.
What this adds up to, and where the real uncertainty is
Within a 24-hour prediction window, at 10-second propagation steps, timing lands within about ±10 seconds of true AOS/TCA/LOS — tight enough to drive a rotator controller directly. From 24 to 72 hours out, at 30-second steps, timing lands within about ±20 seconds.
Past that, the dominant source of error stops being our math and becomes the age of the element set itself — a TLE from Celestrak degrades as drag and solar activity pull the real orbit away from the model. We don't hide that behind a single polished number: every prediction we return, over the API and in every webhook delivery, carries its source TLE's epoch and a fresh / aging / stale label (under 24h, under 72h, or older) — so you can tell a stale-input problem apart from a bad prediction, which is usually the actual question when a pass looks "off."
That's deliberately a coarse label rather than a fabricated error-in-kilometres figure: real SGP4 error growth depends on the object's drag and current solar activity, not just elapsed time, so a single precise-looking number would claim more certainty than the physics actually supports.
Related
System status — live uptime and webhook delivery reliability. Webhook payload docs — the exact fields, including TLE freshness, sent with every delivery.