How the numbers are produced
This page is the derivation behind every figure OrbitRoute publishes: what is measured from real data, what is a model with stated assumptions, and what is simulated. It is written for the engineer who has to decide whether the routing output means anything.
One rule governs the page: every claim below names the public endpoint that returns it, so you can reproduce the number instead of taking it. Where a figure moves (satellite counts, graded-job counts, duty cycles), the endpoint is authoritative and the number quoted here is a dated reading.
1. Basis vocabulary
Four words carry the whole disclosure. They mean exactly this, everywhere — in API payloads, on this page, and in an audit deliverable.
| Term | Definition | Example |
|---|---|---|
| measured | Derived from data observed by the platform or fetched from a third party at request time. Reproducible from a public endpoint. | Satellite position from published orbital elements; deadline hit rate from graded jobs. |
| modeled | Computed from a stated physical or economic model with parameters that are assumptions, not observations. Directionally useful, wrong in the details. | Ground-station bandwidth; the orbital price multiplier; link rate derates. |
| simulated | Produced by a stand-in for hardware that does not exist yet. Not a measurement of anything. | Job execution on an orbital node; weather when no live weather source is configured. |
| unmeasured | The platform has no observation for this and refuses to substitute one. Fields report null plus a status string rather than a plausible number. |
reliability_status: "unmeasured"; confidence: null with confidence_status: "uncalibrated". |
The fourth row is the load-bearing one. A platform that never says "unmeasured" is a platform that fabricates.
2. Orbital propagation
Positions come from SGP4 propagation of two-line element sets published by CelesTrak. There is no proprietary ephemeris and no orbit determination of our own: the elements are third-party inputs, and the propagator is the standard NORAD model (the sgp4 library, TEME output).
- Element source. CelesTrak GP and supplemental feeds (stations, starlink, oneweb, active, iridium-NEXT, planet, spire, GNSS and GEO groups).
- Relay, not direct fetch. The production host's egress address is dropped by CelesTrak, so feeds are pushed in by a trusted machine that can reach it, through an owner-authenticated relay endpoint. Bodies are re-validated as TLE groups before ingestion and a mostly-garbage body is rejected even if a few element sets in it parse. A relayed feed replaces the held copy only when it parses; otherwise the previous elements stay in service and the failure is counted.
- Refresh cadence. Elements are refreshed on a 30-minute floor (CelesTrak itself republishes roughly four times a day), and the last successful refresh timestamp is public.
- Element age is published, not hidden. Every asset in
/api/v1/satellites/positionscarrieselement_age_days— days since the element set's epoch. SGP4 position error grows on the order of 1–3 km per day after epoch for LEO, so age is the single most useful number for judging how much to trust a predicted pass time. - Stale operator elements are refused. An operator-supplied element set more than 14.0 days past epoch is rejected rather than propagated, and a hot-swap of an operator's elements invalidates the cached positions and pass predictions derived from the old ones.
/api/v1/satellites/positions — per-asset lat, lon, altitude_km, velocity_km_s, element_age_days, norad_id. Pull the same NORAD id's elements from CelesTrak, run SGP4 yourself at the returned timestamp, and compare. Reading 2026-07-30: 11,690 satellites tracked, per /api/v1/viz/snapshot → sats.3. Pass prediction and geometry
A contact opportunity is a window in which a satellite is above a station's elevation mask. Three details matter to anyone checking the arithmetic:
- Per-station elevation mask. Each site declares its own mask — 5° for high-latitude polar sites, 10° typical, 15° for the optical sites. The engine uses the station's own value, not one global constant. The masks are in the table in §9.
- WGS84 station geometry. Station elevation angles are computed against the WGS84 ellipsoid rather than a sphere, so a high-latitude site's horizon is not off by the flattening term.
- Sub-second refinement. Rise and set times are found by coarse stepping and then refined, so a reported pass start is not quantised to the step size. Pass duration is what the refined boundaries give, not a nominal figure.
- Search window. The engine searches one orbital period, clamped to 2–6 hours (Keplerian period for a circular orbit at the asset's altitude). If no contact exists in that window, the reported latency is the searched horizon — an explicit bound — and never a placeholder that looks like a prediction.
- Slant range, not altitude. Line-of-sight distance from station to satellite at elevation el and altitude h, with Re = 6371.0 km:
rho = sqrt((Re + h)^2 - (Re * cos(el))^2) - Re * sin(el) link_rtt_ms = 2 * rho / 299.792458 # c in km/ms
Spherical Earth for the range term; the flattening error is under 0.3%, which is negligible next to what this replaced — a fixed 25 ms link latency applied to ranges spanning 400 km to 110,000 km.
/api/v1/satellites/{asset_id}/passes — per pass: pass_start, pass_end, duration_s, max_elevation_deg, station_id, station_name, minutes_until, plus in_progress, truncated_at_window and start_clipped so a partial window is never presented as a whole one. GET /api/v1/ground-stations for each site's elevation_mask_deg.4. The latency budget
estimated_latency_ms for an orbital candidate is time-to-first-result, not link round-trip time. It is the only quantity comparable with the terrestrial path, which has always included its own payload term, and it is disclosed term by term in the decision's reasoning.
latency_ms = time_to_contact_min * 60000 # wait for the next usable pass
+ link_rtt_ms # 2 * slant_range / c
+ 15.0 # modeled on-node processing (ms)
+ transfer_ms # uplink + downlink over the pass
+ queue_wait_ms # live queue depth on that node
transfer_s(payload_mb, bw_gbps, derate) = (payload_mb * 8 / 1000) / (bw_gbps * derate)
Terrestrial, for comparison: 5 ms base + 0.5 ms per MB of input, plus 40 ms for a non-US region.
The hard veto
If the uplink cannot fit inside the contact window — payload transfer seconds greater than the pass duration, or a station with no usable rate at pass time — the candidate is removed, not penalised. A 100 GB job cannot route to a node whose best pass is 400 seconds long, at any score, and the veto reason is returned in the reasoning naming the payload, the required contact seconds, the available seconds, and the station. Without this term a large job flipped to orbital on a low apparent latency, which was the defect this replaced.
/api/v1/route and read the reasoning array. On an orbital recommendation it contains a line of the form "Latency budget N ms = X min wait for contact + Y ms light time over Z km slant range + 15 ms modeled handling + T ms to move U MB up / D MB down at B Gbps + Q ms queue (searched H h of pass geometry)". Every term is named with its value and they sum to estimated_latency_ms. Raise input_size_mb until the transfer term dominates, then past the point where the payload no longer fits the pass, and the candidate disappears with a stated veto reason instead of getting cheaper.5. Link availability and rate
Optical downlinks do not work through cloud. The engine gates the link choice on weather at the specific station at pass time, and derates the achieved rate for both link type and pass geometry. Both derate tables are modeled — no measured link budget exists for these sites.
| Condition | Chosen link | Rate derate |
|---|---|---|
| cloud cover < 30% | optical | 1.0 |
| 30% – 60% cloud | optical, degraded | 0.5 |
| > 60% cloud, site has RF | RF fallback | 0.4 (dual-capable site loses its optical headroom) |
| RF-only site, any weather | RF | 1.0 (the advertised rate already is the RF rate) |
| > 60% cloud, optical-only site | no usable link — the station is dropped from the candidate set, not switched to RF it does not have | 0.0 |
Pass-geometry derate, applied on top: 0.5 + 0.5 × sin(el) — 1.0 at zenith, about 0.59 at a 10° pass. A low pass runs through more atmosphere at longer range for less link margin. Modeled.
Weather is fetched live per station when a weather source is configured; otherwise it is simulated, and each weather record carries its own source_kind (live or simulated) so a consumer never has to guess which one gated the decision. That flag also feeds the confidence degradation in §8.
/api/v1/ground-stations — each station carries a nested weather object with cloud_cover_pct, recommended_link, optical_viable, optical_degraded, rf_available, and the source / source_kind pair that says whether the reading was live or simulated. GET /api/v1/weather/{station_id} for one site.6. Power and eclipse
A node in Earth's shadow runs on battery, so its available power — and therefore its routing score on the power dimension — is not a constant. Illumination is computed from physics, not assumed:
- Solar position from a low-precision analytic ephemeris (Vallado Algorithm 29), accurate to about 0.01°.
- Cylindrical Earth-shadow test against the satellite's propagated position: eclipsed when the satellite is on the anti-sun side and inside a shadow cylinder of radius 6371 km about the Earth–Sun axis. Cylindrical rather than conical umbra differs by under 90 s per LEO orbit.
- In eclipse, available power is 0.6 of the sunlit budget — a modeled depth-of-discharge-limited LEO bus assumption, not a measurement of any specific spacecraft. Federated operators will advertise their own figure.
- SGP4 emits TEME and the solar ephemeris is MOD; the arcminute-level frame disagreement is smaller than the penumbra, so it does not affect a shadow test.
/api/v1/route: when the recommended node is in shadow the reasoning array carries "Node in eclipse — battery-limited to N W", and when illumination cannot be determined from the elements it says so and scores battery-limited rather than assuming full sun. /api/v1/viz/snapshot returns the sun subsolar point and the lit/eclipsed split of the satellite particles, which is the same shadow test — the terminator and eclipse shading on /viz are drawn from it.7. The scoring vector
Each candidate — every orbital asset and every terrestrial provider — is scored 0–100 on five dimensions, then combined as a weighted sum. These are the engineered baseline weights; they sum to 1.0.
| Dimension | Weight | What the 0–100 sub-score is |
|---|---|---|
| latency | 0.25 | Log-scaled from 5 ms (100) to the 6 h search ceiling (0), identical curve for both paths — they were previously on different axes, which made the comparison meaningless. |
| cost | 0.30 | Modeled job cost against the rate card in §11; terrestrial sits at a fixed 50 baseline. |
| availability | 0.20 | Usable-contact quality: contact seconds against a 480 s reference, decayed by time-to-contact (45 min constant). Not a binary "has a pass". |
| queue_depth | 0.15 | Live queue occupancy on the node, from the real job queue. |
| power | 0.10 | Effective available watts under the eclipse model in §6. |
Weights are adjusted by the learning loop from graded-job outcomes and clamped to [0.05, 0.50] per dimension, so no single dimension can be driven to dominate or to zero. Among orbital candidates within 3.0 points of the top orbital score, capacity class breaks the tie (committed > federated > demo > modeled), so capacity the platform can describe honestly is preferred over a marginally higher-scoring simulation of someone else's satellite. This can select a candidate up to 3.0 points below the top score and never more; when it fires, the reasoning array names both candidates and both scores (§12).
8. Preference score vs. confidence
This distinction used to be wrong, and the fix is worth stating plainly because it changes the API.
confidence was total_score / 100 — the weighted preference sum from §7 divided by 100 and given a probability's name. It moved with the cost multiplier and the solar wattage and with nothing that had anything to do with the recommendation being right: not element age, not whether weather was live or simulated, not pass resolution, not whether the target had any measured reliability at all. A response could report confidence: 0.802 one field away from an honest reliability_status: "unmeasured".The response now separates ranking from certainty:
| Field | Meaning |
|---|---|
preference_score | 0–100. The weighted ranking from §7 under its correct name. This is the number that used to be confidence × 100. It is not a probability. |
confidence | A calibrated probability that the decision meets its predicted deadline — or null. Never a rescaled score. |
confidence_status | "uncalibrated" (confidence is null) or "calibrated". |
confidence_basis | The audit trail: measured base rate, sample size, method, and every modeled degradation factor with the reason it applied. Divide any factor back out and reproduce the number. |
How a calibrated confidence is built
confidence = base_rate * product(degradation_factors)
base_rate = one-sided 95% Wilson lower bound on the deadline hit rate
over REAL graded jobs (internal synthetic load excluded),
published only at n >= 50
The base rate is measured; every factor below is modeled. The lower bound rather than the raw hit rate means a small-but-sufficient sample cannot overclaim: at n=50 with a perfect record the bound is 0.9487, not 1.0; a 90% observed rate over 60 jobs gives 0.8181.
| Degradation factor | Value | When it applies |
|---|---|---|
| element_age | 1.0 → 0.80 | 1.0 inside 2 days past epoch, decaying linearly to 0.80 at the 14-day refusal boundary. 0.90 if the pass predictor did not report an age at all — unverifiable freshness cannot score as fresh. |
| weather_source | 0.85 | The optical/RF gate ran on simulated weather rather than live. |
| pass_geometry | 0.70 | No usable contact in the searched window, so the reported latency is a horizon bound rather than a pass-derived budget. |
| target_reliability | 0.90 | No graded jobs for this specific target yet (reliability_status: "unmeasured"). |
On a terrestrial recommendation the three orbital-only factors are reported as 1.0 with "not applicable to this target", so the factor set has the same shape on every response.
Why the gate is 50 and not 10
As of 2026-07-30 the platform has 9 real graded jobs (88.9% deadline hit rate, 115.24% mean latency error), plus over 19,600 graded internal synthetic jobs that are excluded from calibration because they measure the scheduler, not customer workloads. (That synthetic count rises with every scheduler tick, so the live reading below is authoritative for it.) The learning loop starts nudging weights at 10 graded jobs; that is a reasonable floor for adjusting an internal weight and an unreasonable one for printing a probability at a customer. A single-digit hit rate carries a sampling interval tens of points wide, so publishing its point estimate would be the same defect with better arithmetic. 50 is the boundary /sla already publishes as its calibration phase, and using the same number in both places means the API and the scoreboard cannot tell different stories.
So today confidence is null on every response, with confidence_status: "uncalibrated" and a confidence_basis stating the sample size and the threshold. It will stay null until the graded-job count reaches 50.
/api/v1/jobs-stats/sla…What changed for SDK users
- The
confidencekey is still present on every response, so key access and.get("confidence")keep working — but the value isnulltoday. Arithmetic on it now raises instead of silently propagating a preference index dressed as a probability. - If you were ranking or thresholding on
confidence, readpreference_scoreand divide by 100 for the identical previous behaviour. - If you want a probability, branch on
confidence_statusand handle "uncalibrated" — which is the honest state of this platform right now.
/api/v1/jobs-stats/sla — jobs_measured, deadline_hit_rate_pct, avg_latency_error_pct, synthetic_jobs_graded. No API key required. POST /api/v1/route and read preference_score, confidence, confidence_status, confidence_basis. Multiply confidence_basis.measured_base_rate by confidence_basis.degradation_product — or by the individual factors — and you get confidence back, to the 3 decimals it is published at.9. The ground segment (37 sites)
source: "modeled" for this reason. These are geometry figures, not a service-level commitment.Aggregate modeled bandwidth is 148.5 Gbps across the network; the sites span all five latitude bands (arctic, north, tropical, south, antarctic), which is a statement about geographic spread and not an availability figure — for availability, see the duty cycle in §10.
| Site | Network | Lat | Lon | Link | Mask° | Gbps | Basis |
|---|---|---|---|---|---|---|---|
| Accra, Ghana | ATLAS | 5.6037 | -0.187 | rf | 10.0 | 2.0 | modeled |
| Guam | ATLAS | 13.48 | 144.8 | rf | 10.0 | 2.0 | modeled |
| Papeete, Tahiti | ATLAS | -17.5325 | -149.5677 | rf | 10.0 | 2.0 | modeled |
| Hermiston, Oregon | AWS Ground Station | 45.84 | -119.289 | both | 10.0 | 6.0 | modeled |
| Manama, Bahrain | AWS Ground Station | 26.0667 | 50.5577 | rf | 10.0 | 3.0 | modeled |
| Sydney, Australia | AWS Ground Station | -33.8688 | 151.2093 | both | 10.0 | 4.0 | modeled |
| Darmstadt, Germany (ESOC) | ESA | 49.8728 | 8.6251 | rf | 10.0 | 1.5 | modeled |
| Santa Maria, Azores | ESA | 36.997 | -25.136 | rf | 10.0 | 2.0 | modeled |
| Ascension Island | ESA/USSF | -7.9467 | -14.4022 | rf | 10.0 | 2.5 | modeled |
| Awarua, New Zealand | KSAT | -46.5289 | 168.381 | rf | 10.0 | 3.0 | modeled |
| Inuvik, Canada | KSAT | 68.3607 | -133.723 | both | 5.0 | 4.0 | modeled |
| Puertollano, Spain | KSAT | 38.687 | -4.107 | both | 10.0 | 4.0 | modeled |
| Punta Arenas, Chile | KSAT | -53.1638 | -70.9171 | both | 10.0 | 3.0 | modeled |
| Svalbard (SvalSat) | KSAT | 78.2307 | 15.3896 | both | 5.0 | 4.0 | modeled |
| Troll, Antarctica | KSAT | -72.0117 | 2.535 | rf | 5.0 | 2.0 | modeled |
| Tromsø, Norway | KSAT | 69.6492 | 18.9553 | both | 5.0 | 5.0 | modeled |
| McMurdo, Antarctica | NASA NSN | -77.8463 | 166.6683 | rf | 5.0 | 2.0 | modeled |
| Fairbanks, Alaska | NASA NSN/ASF | 64.8581 | -147.8542 | rf | 10.0 | 2.0 | modeled |
| Hartebeesthoek, South Africa | SANSA/KSAT | -25.887 | 27.712 | rf | 10.0 | 2.5 | modeled |
| Clewiston, Florida | SSC | 26.753 | -80.944 | rf | 10.0 | 2.5 | modeled |
| Dongara, Western Australia | SSC | -29.046 | 115.348 | rf | 10.0 | 3.0 | modeled |
| Esrange (Kiruna), Sweden | SSC | 67.8836 | 21.0684 | both | 5.0 | 5.0 | modeled |
| Mauritius | SSC | -20.2833 | 57.5167 | rf | 10.0 | 3.0 | modeled |
| Santiago, Chile | SSC | -33.4489 | -70.6693 | optical | 10.0 | 6.0 | modeled |
| Maui, Hawaii | USSF AMOS | 20.7984 | -156.3319 | optical | 10.0 | 10.0 | modeled |
| Bogotá, Colombia | independent | 4.711 | -74.0721 | rf | 10.0 | 2.0 | modeled |
| Cape Town, South Africa | independent | -33.9249 | 18.4241 | rf | 10.0 | 2.5 | modeled |
| Dubai, UAE | independent | 25.2048 | 55.2708 | optical | 15.0 | 8.0 | modeled |
| Manaus, Brazil | independent | -3.119 | -60.0217 | rf | 10.0 | 2.0 | modeled |
| Mumbai, India | independent | 19.076 | 72.8777 | both | 10.0 | 5.0 | modeled |
| Nairobi, Kenya | independent | -1.2921 | 36.8219 | both | 10.0 | 3.0 | modeled |
| Perth, Australia | independent | -31.9505 | 115.8605 | optical | 15.0 | 10.0 | modeled |
| Reykjavik, Iceland | independent | 64.1466 | -21.9426 | both | 5.0 | 4.0 | modeled |
| Seoul, South Korea | independent | 37.5665 | 126.978 | both | 10.0 | 8.0 | modeled |
| Singapore | independent | 1.3521 | 103.8198 | both | 10.0 | 6.0 | modeled |
| Tokyo, Japan | independent | 35.6762 | 139.6503 | optical | 15.0 | 10.0 | modeled |
| Wake Island | independent | 19.2823 | 166.647 | rf | 10.0 | 2.0 | modeled |
Network names identify the real operator at each geographic site and describe the location only. They are not a claim of any relationship with those operators.
/api/v1/ground-stations or /api/v1/viz/snapshot → stations. Every field in the table above is in that payload, including source. Count the rows.10. Contact duty cycle
The honest answer to "how often can you talk to my satellite" is a duty cycle, not a coverage percentage. contact_duty_cycle is the fraction of a 24 h window in which a reference orbit is in line of sight of at least one station above that station's own elevation mask, computed by stepping the orbit at 30 s over circular two-body reference orbits with an Earth-fixed ground track (J2 nodal regression is not modeled).
This replaced a 5-latitude-bucket "geographic coverage" figure that reported values near 100% — which measured where stations exist, not when a satellite can be reached.
| Reference orbit | Alt (km) | Incl (°) | Duty cycle | Worst gap | Contacts / 24 h |
|---|---|---|---|---|---|
| Starlink-like | 550.0 | 53.0 | 44.7% | 40.5 min | 79 |
| Sun-synchronous | 550.0 | 97.6 | 58.2% | 30.5 min | 77 |
| ISS-like | 420.0 | 51.6 | 32.7% | 47.0 min | 72 |
| OneWeb-like | 1200.0 | 87.9 | 89.7% | 21.5 min | 32 |
| Mid-inclination | 1015.0 | 29.7 | 82.3% | 17.0 min | 50 |
Computed against the 37-station network in §9 on 2026-07-30. Every figure moves when a station is added or a mask changes, so the endpoint is authoritative — the table above is pinned to the computation by a CI test rather than maintained by hand.
The number worth internalising: a 550 km / 53° shell is reachable 44.7% of the day with a worst blackout of 40.5 minutes. Any latency figure for a job routed to such a shell is dominated by wait-for-contact, which is exactly why the latency budget in §4 leads with time_to_contact_min.
/api/v1/ground-stations/coverage — contact_duty_cycle per reference orbit with duty_cycle_pct, worst_gap_min, contact_intervals, plus method and coverage_note. No API key required.11. The pricing model
Terrestrial rates are a modeled public on-demand rate card, approximately March 2026. They are not quotes and they do not reflect committed-use or negotiated discounts.
| GPU | GCP $/GPU-hr | AWS $/GPU-hr | Azure $/GPU-hr |
|---|---|---|---|
| H100 | 3.98 | 4.15 | 4.30 |
| A100 | 2.10 | 2.21 | 2.35 |
| L40S | 1.15 | 1.22 | 1.30 |
The crossover for a specific workload is computed on /calculator using this same table and multiple.
/api/v1/cost-compare returns the per-provider rates and job costs the engine actually scored against, with the orbital figure labeled modeled.12. Capacity classes
Every orbital asset row in the public asset and routing payloads carries a capacity_class — /api/v1/satellites/positions stamps it per asset alongside a capacity_class_labels dictionary, and a routing decision's orbital_option.capacity_class reports it for the option it scored. It is a claim about how real the capacity is, ranked best to worst for routing preference:
| Class | Means | Count it yourself |
|---|---|---|
| committed | Real capacity under a signed contract. | Zero. No asset carries this class. |
| federated | Real operator nodes self-advertised through the federation API, routable only after owner attestation of the operator. | /api/v1/federation/nodes |
| demo | OrbitRoute's own validation fleet: real GPU specs propagated on real orbits from real element sets, used to exercise the engine against true orbital physics. Not contracted third-party hardware. | /api/v1/satellites/positions, rows with source: "core" |
| modeled | Catalog satellites with category-estimated specs — a network-scale simulation of third-party assets. | /api/v1/satellites/positions, the remainder |
Nothing is committed. When a contract closes, that asset's id is added to a configuration list and it flips class without a logic change — which is also why the class is a payload field rather than page copy.
13. Limits
The parts a buyer should weigh against everything above.
- Job execution on orbital nodes is simulated. There is no GPU in orbit running your workload. The routing decision, the physics behind it, and the grading of its prediction are real computations; the execution is a stand-in.
- 9 real graded jobs. Predicted-vs-actual grading is live and published, but the sample is single-digit and the mean latency error is over 100%, which at this n measures sample size rather than steady-state accuracy. This is why
confidenceis null (§8). Over 19,600 internal synthetic jobs are graded and excluded from every published customer figure. - No ground-segment contracts. All 37 stations are modeled locations with modeled bandwidth (§9).
- Orbital pricing is a 3.0× modeled multiplier, not a measurement (§11), ahead of any commercial orbital capacity existing.
- Weather may be simulated. When no live weather source is configured the optical/RF gate runs on simulated conditions; the flag is on every weather record and degrades confidence when it is set.
- Element age bounds pass-time accuracy. SGP4 on elements days past epoch predicts pass times to minutes, not seconds; the age is published per asset so you can bound it yourself.
- Modeled link budgets. The derate tables in §5 are engineering assumptions. No link budget has been measured at any of these sites.
- Reference-orbit duty cycles are two-body. Circular orbits with an Earth-fixed ground track; J2 nodal regression is not modeled, so real revisit patterns will drift from the table in §10.
- No service-level commitment is offered anywhere on this platform, and no uptime figure is contractual. The scoreboard at /sla is a calibration record of a predictor, not a promise.
14. Reproduce it yourself
Every endpoint below is public and needs no API key except /api/v1/route and /api/v1/cost-compare, which take a free key from /signup.
| Endpoint | Verifies |
|---|---|
/api/v1/satellites/positions | §2 propagation, element age, capacity class per asset. |
/api/v1/satellites/{asset_id}/passes | §3 pass geometry, elevation, duration. |
/api/v1/ground-stations | §9 the station table, masks, modeled basis — and §5 link gating per site, including whether the weather behind it was live or simulated. |
/api/v1/weather/{station_id} | §5 one site's conditions and recommended link. |
/api/v1/ground-stations/coverage | §10 contact_duty_cycle, worst gaps, method. |
/api/v1/jobs-stats/sla | §8 the graded-job record the confidence gate reads. |
/api/v1/route | §4 the latency budget term by term, §7 the scores, §8 preference_score / confidence_status / confidence_basis. |
/api/v1/cost-compare | §11 the rate card and the modeled orbital figure. |
/api/v1/viz/snapshot | Satellite count, station list, modeled line-of-sight geometry. |
curl https://www.orbitroute.ai/api/v1/ground-stations/coverage curl https://www.orbitroute.ai/api/v1/jobs-stats/sla
If a number on this page disagrees with the endpoint next to it, the endpoint is right and the page is stale — send it to the contact route on /about and it gets corrected.