Fleet
/fleet/snapshots/fleet/snapshots/{id}/fleets/{constellation_id}/reconcilePurpose
The snapshot endpoints store a fleet state immutably and address it by content, so a configuration can be recorded, compared, and recovered.
The reconcile endpoint compares an as-designed constellation against an as-flown catalog, which is the digital-twin question: is the fleet where the design says it should be.
Note the singular and plural. Snapshots live under /fleet/snapshots; reconciliation
lives under /fleets/{constellation_id}/reconcile. They are different paths, not a
typo.
POST /fleet/snapshots
Request
| Parameter | Type | Unit | Default | Required | Description |
|---|---|---|---|---|---|
state | object | n/a | — | Yes | A FleetState document: a name and a list of slots with their intended elements. |
created | string | RFC 3339 UTC | — | Yes | Creation timestamp. Required here, where the CLI defaults it. |
note | string | n/a | — | No | Free-form note. The only place a reason for the change is recorded. |
parent | string | n/a | — | No | Identifier of the snapshot this supersedes. |
created is required over HTTP, where the CLI supplies a default. Omitting
it fails:
Failed to deserialize the JSON body into the target type: missing field `created`That is arguably the better behavior: a timestamp defaulted by the tool records when the tool ran, not when the configuration was adopted, and only the caller knows the difference.
Example
curl -s -X POST http://127.0.0.1:8080/fleet/snapshots \
-H 'content-type: application/json' \
-d '{
"state": {
"name": "demo-fleet",
"slots": [
{ "id": "demo-s0-p00-sat00",
"elements": { "semi_major_axis_km": 6928.0, "eccentricity": 0.001,
"inclination_deg": 53.0, "raan_deg": 0.0,
"argument_of_perigee_deg": 0.0, "true_anomaly_deg": 0.0 } }
]
},
"created": "2026-01-01T00:00:00Z",
"note": "initial design baseline"
}'{
"id": "8d063f302793722253fcc1a4eeadbf0d5525e6e4ca8b07842073b9746f8bbcb9",
"fleet": "demo-fleet",
"created": "2026-01-01T00:00:00Z",
"note": "initial design baseline"
}The API returns the full digest
The identifier here is the complete 64-character hash. The CLI prints a
12-character prefix of the same value, 8d063f302793, and the prefixes match
because both address the identical content.
Store the full identifier. The CLI accepts an unambiguous prefix for convenience at a terminal, but a prefix that is unique in a small store can collide once the store grows. An API client has no reason to truncate.
Content addressing means identical state produces an identical identifier
regardless of note or created. Saving the same state twice does not create a
second snapshot, and a reverted configuration reproduces the original identifier
exactly.
GET /fleet/snapshots/{id}
Returns the snapshot’s metadata and its full state document.
curl -s http://127.0.0.1:8080/fleet/snapshots/8d063f302793722253fcc1a4eeadbf0d5525e6e4ca8b07842073b9746f8bbcb9{
"meta": {
"id": "8d063f302793722253fcc1a4eeadbf0d5525e6e4ca8b07842073b9746f8bbcb9",
"fleet": "demo-fleet",
"created": "2026-01-01T00:00:00Z",
"note": "initial design baseline"
},
"state": {
"name": "demo-fleet",
"slots": [{ "id": "demo-s0-p00-sat00", "elements": {} }]
}
}Response elided.
The split between meta and state matters: state is the content that was
hashed, meta is what was recorded about the act of saving it. Only state
determines the identifier.
POST /fleets/{constellation_id}/reconcile
Compares a design constellation against an as-flown catalog, matching flown objects to design slots and reporting the discrepancies: slots with no object, objects matching no slot, and objects out of position.
This is the digital-twin operation. A design says where satellites should be; a catalog says where they are; reconciliation is the difference, and it is what turns a design document into an operational picture.
See also
fleet save,fleet list, andfleet showfor the same store from a shell./replanfor what to do about a discrepancy.
main (pre-release)