curl -X POST https://rotastellar-cae.subhadip-mitra.workers.dev/v1/plan \
-H "Content-Type: application/json" \
-H "Origin: https://rotastellar.com" \
-d '{
"satellite_id": "25544",
"preset_id": "onboard-ml-inference"
}'
curl -X POST https://rotastellar-cae.subhadip-mitra.workers.dev/v1/plan \
-H "Content-Type: application/json" \
-H "Origin: https://rotastellar.com" \
-d '{
"satellite_id": "25544",
"custom_job": {
"name": "Capture and Process",
"steps": [
{
"id": "capture",
"name": "Sensor Capture",
"location": "onboard",
"duration_s": 30,
"depends_on": [],
"requires": {"power_w": 40, "compute": 0.3, "thermal_w": 15, "memory_mb": 256, "storage_mb": 1024},
"input_data_mb": 0,
"output_data_mb": 500
},
{
"id": "process",
"name": "Ground Processing",
"location": "ground",
"duration_s": 60,
"depends_on": ["capture"],
"requires": {"power_w": 100, "compute": 1.0, "thermal_w": 50, "memory_mb": 2048, "storage_mb": 2048},
"input_data_mb": 500,
"output_data_mb": 50,
"data_reduction_ratio": 0.1
}
]
}
}'
import requests
response = requests.post(
"https://rotastellar-cae.subhadip-mitra.workers.dev/v1/plan",
headers={
"Content-Type": "application/json",
"Origin": "https://rotastellar.com"
},
json={
"satellite_id": "25544",
"preset_id": "onboard-ml-inference"
}
)
plan = response.json()
print(f"Plan {plan['id']}: {plan['plan']['windows_used']} windows, "
f"confidence {plan['error_budget']['delivery_confidence']}")
{
"id": "a92f33e8-a349-494c-8b4e-f87d859b9ec5",
"created_at": "2026-03-05T06:55:37.811Z",
"version": "1.0.0",
"satellite": {
"id": "25544",
"name": "ISS (ZARYA)",
"norad_id": 25544,
"altitude_km": 417,
"inclination_deg": 51.6,
"period_min": 93,
"tle_epoch": "26063.86671769"
},
"preset": {
"id": "onboard-ml-inference",
"name": "On-Board ML Inference",
"category": "ml-inference",
"steps": 4
},
"orbital_environment": {
"prediction_start": "2026-03-05T06:55:37.811Z",
"prediction_hours": 12,
"eclipse_fraction": 0.348,
"bus": { "..." : "..." },
"windows": [ "..." ],
"ground_passes": [ "..." ],
"summary": {
"total_windows": 14,
"comms_windows": 6,
"sunlit_windows": 9,
"eclipse_windows": 5,
"total_pass_time_s": 2847,
"ground_stations_visible": 8
}
},
"placement_decisions": [
{ "step_id": "capture", "location": "onboard", "reason": "preset_defined" },
{ "step_id": "preprocess", "location": "onboard", "reason": "preset_defined" },
{ "step_id": "inference", "location": "onboard", "reason": "preset_defined" },
{ "step_id": "encrypt_results", "location": "onboard", "reason": "preset_defined" }
],
"transfer_schedule": {
"transfers": [ "..." ],
"total_transfers": 1,
"total_downlink_mb": 11.03,
"total_uplink_mb": 0,
"passes_used": 1,
"total_transfer_time_s": 12
},
"error_budget": {
"worst_case_ber": 0.00001,
"total_fec_overhead_mb": 0.53,
"total_retransmission_reserve_mb": 0.11,
"delivery_confidence": 0.997
},
"security_summary": {
"encryption": "aes256",
"total_encryption_overhead_mb": 0.53,
"total_key_exchanges": 1,
"data_classification": "restricted"
},
"plan": {
"segments": [ "..." ],
"total_duration_s": 1382,
"total_compute_s": 170,
"total_transfer_s": 12,
"total_ground_s": 0,
"windows_used": 2,
"policy": {
"objective": "min_latency",
"deadline_orbits": 3
}
},
"events": [ "..." ]
}
{
"error": {
"code": "validation_error",
"message": "satellite_id is required"
}
}
{
"error": {
"code": "planning_failed",
"message": "No feasible window for step 'inference': thermal constraint exceeded"
}
}
CAE
Create Plan
Create a constraint-aware execution plan for a satellite and workload
POST
/
v1
/
plan
curl -X POST https://rotastellar-cae.subhadip-mitra.workers.dev/v1/plan \
-H "Content-Type: application/json" \
-H "Origin: https://rotastellar.com" \
-d '{
"satellite_id": "25544",
"preset_id": "onboard-ml-inference"
}'
curl -X POST https://rotastellar-cae.subhadip-mitra.workers.dev/v1/plan \
-H "Content-Type: application/json" \
-H "Origin: https://rotastellar.com" \
-d '{
"satellite_id": "25544",
"custom_job": {
"name": "Capture and Process",
"steps": [
{
"id": "capture",
"name": "Sensor Capture",
"location": "onboard",
"duration_s": 30,
"depends_on": [],
"requires": {"power_w": 40, "compute": 0.3, "thermal_w": 15, "memory_mb": 256, "storage_mb": 1024},
"input_data_mb": 0,
"output_data_mb": 500
},
{
"id": "process",
"name": "Ground Processing",
"location": "ground",
"duration_s": 60,
"depends_on": ["capture"],
"requires": {"power_w": 100, "compute": 1.0, "thermal_w": 50, "memory_mb": 2048, "storage_mb": 2048},
"input_data_mb": 500,
"output_data_mb": 50,
"data_reduction_ratio": 0.1
}
]
}
}'
import requests
response = requests.post(
"https://rotastellar-cae.subhadip-mitra.workers.dev/v1/plan",
headers={
"Content-Type": "application/json",
"Origin": "https://rotastellar.com"
},
json={
"satellite_id": "25544",
"preset_id": "onboard-ml-inference"
}
)
plan = response.json()
print(f"Plan {plan['id']}: {plan['plan']['windows_used']} windows, "
f"confidence {plan['error_budget']['delivery_confidence']}")
{
"id": "a92f33e8-a349-494c-8b4e-f87d859b9ec5",
"created_at": "2026-03-05T06:55:37.811Z",
"version": "1.0.0",
"satellite": {
"id": "25544",
"name": "ISS (ZARYA)",
"norad_id": 25544,
"altitude_km": 417,
"inclination_deg": 51.6,
"period_min": 93,
"tle_epoch": "26063.86671769"
},
"preset": {
"id": "onboard-ml-inference",
"name": "On-Board ML Inference",
"category": "ml-inference",
"steps": 4
},
"orbital_environment": {
"prediction_start": "2026-03-05T06:55:37.811Z",
"prediction_hours": 12,
"eclipse_fraction": 0.348,
"bus": { "..." : "..." },
"windows": [ "..." ],
"ground_passes": [ "..." ],
"summary": {
"total_windows": 14,
"comms_windows": 6,
"sunlit_windows": 9,
"eclipse_windows": 5,
"total_pass_time_s": 2847,
"ground_stations_visible": 8
}
},
"placement_decisions": [
{ "step_id": "capture", "location": "onboard", "reason": "preset_defined" },
{ "step_id": "preprocess", "location": "onboard", "reason": "preset_defined" },
{ "step_id": "inference", "location": "onboard", "reason": "preset_defined" },
{ "step_id": "encrypt_results", "location": "onboard", "reason": "preset_defined" }
],
"transfer_schedule": {
"transfers": [ "..." ],
"total_transfers": 1,
"total_downlink_mb": 11.03,
"total_uplink_mb": 0,
"passes_used": 1,
"total_transfer_time_s": 12
},
"error_budget": {
"worst_case_ber": 0.00001,
"total_fec_overhead_mb": 0.53,
"total_retransmission_reserve_mb": 0.11,
"delivery_confidence": 0.997
},
"security_summary": {
"encryption": "aes256",
"total_encryption_overhead_mb": 0.53,
"total_key_exchanges": 1,
"data_classification": "restricted"
},
"plan": {
"segments": [ "..." ],
"total_duration_s": 1382,
"total_compute_s": 170,
"total_transfer_s": 12,
"total_ground_s": 0,
"windows_used": 2,
"policy": {
"objective": "min_latency",
"deadline_orbits": 3
}
},
"events": [ "..." ]
}
{
"error": {
"code": "validation_error",
"message": "satellite_id is required"
}
}
{
"error": {
"code": "planning_failed",
"message": "No feasible window for step 'inference': thermal constraint exceeded"
}
}
Base URL:
https://rotastellar-cae.subhadip-mitra.workers.dev
— No API key required.Request
string
required
NORAD catalog ID (e.g.,
"25544" for ISS).string
Preset workload ID. One of:
onboard-ml-inference, split-learning, earth-observation-qa, federated-learning, resilient-store-forward. Mutually exclusive with custom_job.object
Custom workload definition with arbitrary step DAG. Mutually exclusive with
preset_id. See Custom Workloads for the full schema.name(string) — Workload namesteps(array, required) — Step definitions with dependenciessecurity(object) — Security policy overridespolicy(object) — Execution policy overrides
object
Override security settings from the preset or custom job:
encryption—none,aes128, oraes256data_classification—open,restricted, orconfidentialrequire_authenticated_uplink— booleankey_rotation_orbits— number
object
Planning options:
prediction_hours(number, 1–48, default: 12) — Orbital prediction windowmin_elevation_deg(number, 0–90, default: 5) — Minimum ground station elevation
Either
preset_id or custom_job is required, but not both.curl -X POST https://rotastellar-cae.subhadip-mitra.workers.dev/v1/plan \
-H "Content-Type: application/json" \
-H "Origin: https://rotastellar.com" \
-d '{
"satellite_id": "25544",
"preset_id": "onboard-ml-inference"
}'
curl -X POST https://rotastellar-cae.subhadip-mitra.workers.dev/v1/plan \
-H "Content-Type: application/json" \
-H "Origin: https://rotastellar.com" \
-d '{
"satellite_id": "25544",
"custom_job": {
"name": "Capture and Process",
"steps": [
{
"id": "capture",
"name": "Sensor Capture",
"location": "onboard",
"duration_s": 30,
"depends_on": [],
"requires": {"power_w": 40, "compute": 0.3, "thermal_w": 15, "memory_mb": 256, "storage_mb": 1024},
"input_data_mb": 0,
"output_data_mb": 500
},
{
"id": "process",
"name": "Ground Processing",
"location": "ground",
"duration_s": 60,
"depends_on": ["capture"],
"requires": {"power_w": 100, "compute": 1.0, "thermal_w": 50, "memory_mb": 2048, "storage_mb": 2048},
"input_data_mb": 500,
"output_data_mb": 50,
"data_reduction_ratio": 0.1
}
]
}
}'
import requests
response = requests.post(
"https://rotastellar-cae.subhadip-mitra.workers.dev/v1/plan",
headers={
"Content-Type": "application/json",
"Origin": "https://rotastellar.com"
},
json={
"satellite_id": "25544",
"preset_id": "onboard-ml-inference"
}
)
plan = response.json()
print(f"Plan {plan['id']}: {plan['plan']['windows_used']} windows, "
f"confidence {plan['error_budget']['delivery_confidence']}")
{
"id": "a92f33e8-a349-494c-8b4e-f87d859b9ec5",
"created_at": "2026-03-05T06:55:37.811Z",
"version": "1.0.0",
"satellite": {
"id": "25544",
"name": "ISS (ZARYA)",
"norad_id": 25544,
"altitude_km": 417,
"inclination_deg": 51.6,
"period_min": 93,
"tle_epoch": "26063.86671769"
},
"preset": {
"id": "onboard-ml-inference",
"name": "On-Board ML Inference",
"category": "ml-inference",
"steps": 4
},
"orbital_environment": {
"prediction_start": "2026-03-05T06:55:37.811Z",
"prediction_hours": 12,
"eclipse_fraction": 0.348,
"bus": { "..." : "..." },
"windows": [ "..." ],
"ground_passes": [ "..." ],
"summary": {
"total_windows": 14,
"comms_windows": 6,
"sunlit_windows": 9,
"eclipse_windows": 5,
"total_pass_time_s": 2847,
"ground_stations_visible": 8
}
},
"placement_decisions": [
{ "step_id": "capture", "location": "onboard", "reason": "preset_defined" },
{ "step_id": "preprocess", "location": "onboard", "reason": "preset_defined" },
{ "step_id": "inference", "location": "onboard", "reason": "preset_defined" },
{ "step_id": "encrypt_results", "location": "onboard", "reason": "preset_defined" }
],
"transfer_schedule": {
"transfers": [ "..." ],
"total_transfers": 1,
"total_downlink_mb": 11.03,
"total_uplink_mb": 0,
"passes_used": 1,
"total_transfer_time_s": 12
},
"error_budget": {
"worst_case_ber": 0.00001,
"total_fec_overhead_mb": 0.53,
"total_retransmission_reserve_mb": 0.11,
"delivery_confidence": 0.997
},
"security_summary": {
"encryption": "aes256",
"total_encryption_overhead_mb": 0.53,
"total_key_exchanges": 1,
"data_classification": "restricted"
},
"plan": {
"segments": [ "..." ],
"total_duration_s": 1382,
"total_compute_s": 170,
"total_transfer_s": 12,
"total_ground_s": 0,
"windows_used": 2,
"policy": {
"objective": "min_latency",
"deadline_orbits": 3
}
},
"events": [ "..." ]
}
{
"error": {
"code": "validation_error",
"message": "satellite_id is required"
}
}
{
"error": {
"code": "planning_failed",
"message": "No feasible window for step 'inference': thermal constraint exceeded"
}
}
Errors
| Status | Code | Description |
|---|---|---|
| 400 | validation_error | Invalid request body or parameters |
| 400 | invalid_body | Request body is not valid JSON |
| 403 | origin_not_allowed | Request from disallowed origin |
| 422 | planning_failed | Planner cannot find a feasible schedule |
| 500 | internal_error | Unexpected server error |
⌘I

