Design
/design/templates/designPurpose
POST /design solves the inverse problem: state what you need and the solver
searches Walker geometries for one that delivers it, returning a recommendation
plus the alternatives and the feasible space it explored.
GET /design/templates returns pre-built requirement documents for common
mission types, which is the fastest way to see a well-formed request.
GET /design/templates
curl -s http://127.0.0.1:8080/design/templatesTwo templates ship:
| Template | Description |
|---|---|
communications | Continuous single-fold coverage, bent-pipe latency budget, LEO Walker Delta |
earth_observation | Revisit-driven imaging access, lower LEO, sun-synchronous-biased search space |
Each carries a complete request object. Fetch one, edit the stations and
constraints, and post it to /design.
The templates are the practical answer to how large the design request schema is.
Rather than assembling link, constraints, and objective blocks from
documentation, start from a template that already has coherent values and change what
you need.
POST /design
Request
| Parameter | Type | Unit | Default | Required | Description |
|---|---|---|---|---|---|
name | string | n/a | — | Yes | Design name, carried into the output. |
start | string | RFC 3339 UTC | 2026-01-01T00:00:00Z | No | Verification window start. |
verification_hours | number | h | — | No | Window over which candidates are checked. |
step_seconds | number | s | — | No | Verification sampling step. |
stations | array | n/a | — | No | Ground stations to serve. Each may carry `min_elevation_deg`, `weight`, and `required`. |
link | object | n/a | — | No | Continuity, fold, revisit, topology, and latency requirement. |
constraints | object | n/a | — | No | Search-space bounds such as altitude and inclination ranges. |
objective | object | n/a | — | No | What to optimize, plus tie-breakers. |
Only name is strictly required. Everything else has a default, which means an
under-constrained request is accepted and answered.
Example
curl -s -X POST http://127.0.0.1:8080/design \
-H 'content-type: application/json' \
-d '{
"name": "europe",
"verification_hours": 6.0,
"step_seconds": 120.0,
"stations": [
{ "id": "madrid", "name": "Madrid",
"latitude_deg": 40.43, "longitude_deg": -3.7, "altitude_km": 0.6 }
]
}'The response has six top-level keys:
| Key | Contents |
|---|---|
request | The request as interpreted, with every default filled in |
status | feasible when at least one candidate met every requirement |
recommended | The winning design, including a ready-to-use constellation document |
alternatives | Other feasible candidates |
feasible_space | The region of the search that satisfied the requirements |
relaxations | Which requirements would have to give if nothing were feasible |
provenance | What was run, and how |
{
"status": "feasible",
"recommended": {
"constellation": {
"schema_version": "orbitforge.constellation.v1",
"name": "europe",
"description": "Walker star 16/4/1 at 1237.5 km, 45 deg inclination",
"shells": [
{
"id": "s0",
"altitude_km": 1237.5,
"inclination_deg": 45.0,
"planes": 4,
"satellites_per_plane": 4
}
]
}
}
}Response elided.
Read request back, not just recommended
The echoed request is the most useful field for a first-time caller. It shows
every default the solver filled in, including the entire link requirement you
did not specify and per-station fields such as min_elevation_deg: 10.0,
weight: 1.0, and required: true.
Given that unknown fields are silently ignored, this echo is the only way to confirm your intent survived. Diff it against what you sent.
The solver answers what you asked, not what you meant
The recommendation above is a Walker Star, 16 satellites in 4 planes of 4, at 1237.5 km and 45 degrees. Nothing in the request named an altitude, an inclination, or a pattern.
Each choice follows from the single station at 40.43 degrees north and from an objective that, by default, rewards fewer satellites. A higher orbit sees more ground per satellite, so the search climbs until something else binds.
1237.5 km is far above the 550 km typical of broadband shells, and it is optimal only for “fewest satellites”. A real system would also care about path loss and latency, and the solver was never told to.
Constrain the search, or accept what it optimizes for. constraints bounds the
altitude range; link states latency and continuity.
Verify the recommendation independently
recommended.constellation is a complete constellation document. Create it and
re-verify at finer resolution than the solver used:
curl -s -X POST http://127.0.0.1:8080/coverage \
-H 'content-type: application/json' \
-d '{"constellation_id":"europe","duration_hours":24.0,
"step_seconds":60.0,"grid_deg":2.0,"min_elevation_deg":25.0}'The solver verified at 120-second steps over 6 hours. A 24-hour run at 60 seconds on a 2-degree grid is a substantially harder test, and it is the one worth quoting.
See also
orbitforge designfor the command-line equivalent./constellations/walkerto specify a geometry directly instead.
main (pre-release)