Skip to Content
ReferenceHTTP APIOverview

HTTP API overview

The Axum service exposes the same engine as the CLI over HTTP. It is what the web UI talks to, and it is the integration point for anything that is not a shell.

orbitforge-api # listens on 127.0.0.1:8080 by default

Read this before your first request

Three behaviors cause more lost time than anything else in this API, and none of them produces an error.

1. Unknown fields are ignored, not rejected. A misspelled or misplaced field is silently dropped and its default is used. The request succeeds and returns a plausible result computed from something other than what you sent.

2. The CLI and the API do not share spelling. The CLI writes --model two-body; the API field is propagation_model and its value is two_body. Hyphens on the command line, underscores over HTTP.

3. Nested config objects are all-or-nothing. Omit rf entirely and you get a complete default. Supply rf with one field and the request fails, because the object has no per-field defaults.

Behavior 1 and behavior 3 interact badly. Putting frequency_ghz at the top level instead of inside rf is ignored, so the request succeeds and quietly uses the default 12 GHz. Putting it inside rf alone fails loudly with rf: missing field tx_power_dbw. The failing case is the safer one.

Conventions

ConventionValue
Base URLhttp://127.0.0.1:8080 by default
Content typeapplication/json on request and response
Field naminglower_snake_case
Enum valueslower_snake_case, for example two_body
TimesRFC 3339 UTC, for example 2026-01-01T00:00:00Z
UnitsNamed in the field, as in duration_hours, altitude_km, frequency_ghz

The service is stateful

This is the most important structural fact about the API. Constellations and scenarios live in the service’s memory and are addressed by identifier.

Analysis endpoints take a constellation_id, not a constellation document. You create the constellation once, then run many analyses against it.

State is in memory. Restarting the service loses every constellation and scenario, and a 404 on an identifier you know you created almost always means the process restarted or you are talking to a different instance.

Endpoint groups

GroupPurpose
/healthLiveness
/constellations/walkerGenerate a Walker constellation
/import/tle, /import/ephemerisImport real objects
/design, /design/templatesRequirements-driven synthesis
/simulatePropagate and register a scenario
/scenarios/{id} and its exportsRetrieve results as CZML, OEM, or CSV
/coverage, /export/coverage/geojsonCoverage statistics and export
/link, /link/chain, /link/interferenceLink budgets
/eclipseUmbra and penumbra intervals
/islInter-satellite link topology
/analysis/doppler, /elements, /footprintPer-satellite analysis
/platform/accessFixed or moving platform access
/maneuver/*, /stationkeep, /transfer/lambertManeuvers and transfers
/od/*Orbit determination
/conjunction/screenClose-approach screening
/resilience/*Reliability and availability
/replan, /fleets/{id}/reconcile, /fleet/snapshotsFleet operations
/trade/sweep, /econ/estimateTrade space and cost
/waveform/*Waveform generation and analysis
/stations, /orbits/special, /ephemeris/solar-systemReference data

Errors

Application errors return a consistent envelope:

{ "error": { "code": "not_found", "message": "constellation `nope` not found; generate it first" } }

Deserialization failures do not. They return 422 with a plain-text body:

Failed to deserialize the JSON body into the target type: missing field `ground_stations` at line 1 column 174

A client that parses every error response as JSON will fail on exactly the errors a new integration hits most often. Branch on the status code, or on the response content type, before parsing.

StatusMeaningBody
200SuccessJSON result
400Well-formed but cannot be honored: unknown enum value, incompatible modelJSON envelope
404Identifier not foundJSON envelope
422Body could not be deserializedPlain text

The plain-text 422 is genuinely useful once you expect it: it names the missing field and its position, which is how the all-or-nothing behavior of nested config objects gets diagnosed.

A minimal session

API=http://127.0.0.1:8080 curl -s $API/health curl -s -X POST $API/constellations/walker \ -H 'content-type: application/json' \ -d '{"name":"demo","planes":6,"sats_per_plane":10, "altitude_km":550.0,"inclination_deg":53.0,"fov_deg":45.0}' curl -s -X POST $API/simulate \ -H 'content-type: application/json' \ -d '{"constellation_id":"demo","duration_hours":6.0, "step_seconds":60.0,"propagation_model":"two_body"}' curl -s $API/scenarios/scenario-demo
{"status":"ok","service":"orbitforge-api","version":"0.1.0"} {"constellation_id":"demo","name":"demo","satellite_count":60} {"scenario_id":"scenario-demo","status":"completed","satellite_count":60,"sample_count":361,"czml_url":"/api/scenarios/scenario-demo/czml"} {"scenario_id":"scenario-demo","name":"demo","start_time":"2026-01-01T00:00:00Z","duration_seconds":21600.0,"step_seconds":60.0,"model":"two_body","satellite_count":60,"sample_count":361}

See also

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