Skip to Content

CSV outputs

What they are

Flat tables for analysis in a spreadsheet, a data frame, or anything else that reads CSV. Two are produced from a scenario: an ephemeris table and a contact table.

They are the most convenient export and the least self-describing, and the second half of that sentence is the important one.

Ephemeris CSV

curl -s http://127.0.0.1:8080/scenarios/scenario-gj/ephemeris.csv
satellite_id,satellite_name,time_s,x_km,y_km,z_km,vx_km_s,vy_km_s,vz_km_s gj-s0-p00-sat00,gj-s0-p00-sat00,0,6928.137,0,0,0,4.564820232396907,6.057721051030392 gj-s0-p00-sat00,gj-s0-p00-sat00,600,5486.340609293676,2546.122041969697,3378.8180710094707,-4.631912845789708,3.614847485712905,4.79706463686287 gj-s0-p00-sat00,gj-s0-p00-sat00,1200,1761.0483556547456,4032.5105450645924,5351.322236957664,-7.335955263172513,1.1603219110883758,1.539799183522527

Real output, elided after three rows.

ParameterTypeUnitDefaultRequiredDescription
satellite_idstringn/a—NoStable identifier. Rows are grouped by satellite, then ordered by time.
satellite_namestringn/a—NoDisplay name. Equal to the identifier for generated constellations.
time_snumbers—NoElapsed seconds from the scenario start. NOT an absolute epoch. See below.
x_km, y_km, z_kmnumberkm—NoPosition in the scenario frame.
vx_km_s, vy_km_s, vz_km_snumberkm/s—NoVelocity.

Kilometers, like everything except CZML, which uses meters.

The file carries no provenance

This CSV has no frame, no time system, and no absolute epoch. time_s is elapsed seconds from a scenario start that lives somewhere else entirely.

A row reading 600, 5486.34, 2546.12, 3378.82 is meaningless on its own. It does not say which frame those axes are, when the scenario began, or which propagation model produced it.

Fetch the scenario metadata alongside any CSV you intend to keep:

curl -s http://127.0.0.1:8080/scenarios/scenario-gj > scenario.json curl -s http://127.0.0.1:8080/scenarios/scenario-gj/ephemeris.csv > ephemeris.csv
{ "scenario_id": "scenario-gj", "start_time": "2026-01-01T00:00:00Z", "duration_seconds": 21600.0, "step_seconds": 60.0, "model": "two_body", "satellite_count": 60, "sample_count": 361 }

start_time is what converts time_s into an absolute epoch, and model is what tells a reviewer how much to trust the numbers. Without both, the CSV is a table that cannot be reproduced or checked, which is precisely what makes a result impossible to audit later.

If you need a self-describing file, use CCSDS OEM instead. It declares its frame, time system, and span in the file.

Contacts CSV

curl -s http://127.0.0.1:8080/scenarios/scenario-demo/contacts.csv

Contact records exist only where a link analysis produced them. Requesting them from a plain propagation returns an explicit error rather than an empty file:

{ "error": { "code": "invalid_request", "message": "scenario `scenario-gj` has no contacts (run a link analysis to produce them)" } }

That error is the right behavior and worth relying on. An empty CSV would be indistinguishable from a constellation that genuinely never made contact, and a scheduling tool consuming it would silently plan nothing.

Run POST /link first; it registers its own scenario, from which contacts can be fetched.

Reading them

Rows are grouped by satellite and ordered by time within each group, so a naive sort by time_s interleaves satellites. Group first.

For a large constellation these files are big: one row per satellite per step, so 60 satellites at 361 steps is 21,660 rows for six hours. Halving the step doubles it.

See also

Question? Give us feedbackDocuments Varaha Constellation Designer main (pre-release)
Last updated on