Can OrbitRoute route to your hardware?
Five public endpoints answer that question without a meeting, an NDA, or our SDK: a vocabulary for describing compute that is not a GPU, a dry-run validator, and a deterministic benchmark graded by the same scorer that grades our own baseline. All five are read-only and stateless — nothing here writes to the fleet or to production routing.
demo, modeled, or federated) is disclosed per option in every decision; no CPU, NPU, FPGA, or QPU hardware receives work on this platform today, and none is under contract. A routing request that says nothing about modalities is a GPU request; one that names non-GPU hardware still gets a GPU decision — and the response now says so explicitly (the modality echo).1. The vocabulary
A resource is described by three enums. A QPU is not modelled as a fast GPU: capacity is described in units native to the modality ({"qubits": 40}, not a synthetic GPU-equivalence).
| Modality (5) | What it is |
|---|---|
| cpu | General-purpose classical compute. |
| gpu | The default. Every node advertised before this contract existed is a GPU node and behaves exactly as it did. |
| npu | Neural accelerators — inference-shaped silicon. |
| fpga | Reconfigurable logic; defaults to requiring classical pre/post processing. |
| qpu | Quantum processors; also defaults to requiring classical pre/post processing. |
| Problem class (7) | Why it exists |
|---|---|
| inference | What a legacy GPU node is taken to run. A request that states no problem class is one of these. |
| training | |
| linear_algebra | Dense/sparse kernels a CPU, GPU, or FPGA might each legitimately claim. |
| signal_processing | FFT/filtering pipelines — classic FPGA/NPU territory. |
| combinatorial_optimization | Scheduling, assignment, routing — the shape of OrbitRoute's own benchmark instance. |
| qubo | Quadratic unconstrained binary optimization — the native encoding of annealers. |
| sampling | Distributions a device produces natively rather than computes. |
| Evidence level (4) | Provenance of the claim | May receive work |
|---|---|---|
| self_reported | Typed into the endpoint. The default for anything an operator sends — the least privileged value, never the most. | no — listed only |
| simulator_measured | Measured on a simulator. Enough to run the benchmark; not enough to take live jobs. | no — listed only |
| hardware_measured | Measured on the physical device. | yes |
| third_party_verified | Measured and attested by someone who is not the operator. | yes |
2. The two rules
acceptable_modalities is GPU-only, and a resource never claims to run everything: it declares the problem classes it can actually run. Both defaults point the same way — newly advertised hardware can never silently capture existing traffic. Backward compatibility here is a safety property, not a courtesy.self_reported or simulator_measured profile is directory-listed but not compute-eligible: it appears in the public directory with its evidence level attached, and it receives no work until the claim is hardware_measured or third_party_verified. Being listed is publicity; being routable is earned.Both rules are enforced in code (eligible_for() and is_routable()) and stated machine-readably by GET /api/v1/compute/contract, so the page you are reading can be checked against the running system.
3. The honest modality echo
POST /api/v1/route accepts problem_class and acceptable_modalities. Because no non-GPU fleet is live, stating them cannot change the decision — so instead of ignoring them silently, the response annotates itself. A GPU-native request (fields unset, or ["gpu"]) gets compute_modality_note: null and exactly the response it always got.
{"model_name": "annealer-probe", "input_size_mb": 8,
"estimated_compute_seconds": 5,
"problem_class": "qubo", "acceptable_modalities": ["qpu"]}
"compute_modality_note": {
"requested_problem_class": "qubo",
"requested_acceptable_modalities": ["qpu"],
"unrecognized_modalities": [],
"unrecognized_problem_class": false,
"non_gpu_fleet_live": false,
"processed_as": "gpu",
"gpu_was_acceptable_to_request": false,
"routing_effect": "none on the fields, everything on the interpretation — no non-GPU fleet is live, so this request was processed as a GPU request even though acceptable_modalities ['qpu'] did not list gpu as acceptable: the decision below is a GPU-fleet answer, not a qpu one (the stated problem_class 'qubo' likewise changed nothing)",
"note": "Heterogeneous compute contract: modalities and problem classes are a published vocabulary and grading harness today, not live non-GPU capacity. See GET /api/v1/compute/contract.",
"contract": "/api/v1/compute/contract"
}
The same sentence is appended to the decision's human-readable reasoning list — the standard every other disclosure on this platform follows (weather source, modeled stations, uncalibrated confidence).
4. The benchmark and the number to beat
The benchmark is a bounded orbital-scheduling instance — 24 jobs, 6 assets, contact windows, power and queue constraints — deterministic in its seed, so two parties can compare results without exchanging data. The baseline is a real earliest-deadline-first planner, not a strawman; beating a bad baseline would prove nothing.
"classical_baseline": {
"solver": "orbitroute-classical-edf-greedy",
"feasible": true,
"scheduled_count": 24, // 24/24 jobs scheduled, zero unscheduled
"unscheduled_count": 0,
"total_cost_usd": 3.6299,
"lateness_penalty": 0.04,
"objective": 3.6699, // the number to beat — lower wins
"wall_clock_ms": 0.255 // a per-run measurement, NOT a constant
}
The objective (cost + lateness penalty) is deterministic for a given seed: 3.6699 on seed 42, feasible at 24/24. wall_clock_ms is whatever that run took on that machine — a per-run measurement; quote your own inclusive of queue and compile time, as the response instructs.
5. The reference result — ties and all
To prove the loop end-to-end with no partner needed, a reference second solver (simulated annealing with a classical warm start) runs against the baseline through the same scorer. Here is its honest record:
Across seeds 0–19, the reference annealer recorded 0 wins and 20 ties against the classical baseline. On seed 42 it also ties: 3.6699 against 3.6699.
A tie is reported as a tie. The warm start means the annealer is never worse than the baseline, and on these instances the earliest-deadline-first schedule is already a strong local optimum the annealer has not escaped within its iteration budget. The point of publishing this is the harness, not a victory: the grading loop is proven end-to-end, the baseline is real, and the number to beat is really the number. If your solver beats 3.6699 on seed 42, that will mean something — winner says whatever the arithmetic says.
6. The five endpoints
The vocabulary and the rules, machine-readable: the enums on this page, the routable evidence levels, the profile fields, and where to advertise.
curl https://www.orbitroute.ai/api/v1/compute/contract
Dry-run a profile against a hypothetical request. Writes nothing — a validate call is not an advertisement.
curl -X POST https://www.orbitroute.ai/api/v1/compute/validate \
-H "Content-Type: application/json" \
-d '{"profile": {"modality": "qpu",
"eligible_problem_classes": ["qubo"],
"evidence_level": "simulator_measured",
"capacity": {"qubits": 40}},
"problem_class": "qubo", "acceptable_modalities": ["qpu"]}'
{
"routable": false,
"routable_reason": "evidence is simulator_measured; directory-listed but not compute-eligible until measured on hardware or verified",
"eligible_for_request": false,
"note": "Dry run. Nothing was advertised, stored, or scheduled."
}
The full instance (assets, contact windows, jobs, constraints, objective definition) plus the classical baseline above. ?seed=, ?jobs=, ?assets= are yours to vary; seed 42 with 24 jobs / 6 assets is the canonical instance.
curl "https://www.orbitroute.ai/api/v1/compute/benchmark?seed=42"
The reference comparison from section 5, freshly computed: both lanes on the same instance, graded by the same scorer, with the annealer's full assignment included so anyone can re-grade it. Deterministic given (seed, budget_ms) on this deployment.
curl "https://www.orbitroute.ai/api/v1/compute/benchmark/reference?seed=42"
Grade your assignment with the same scorer that graded ours — no home-field advantage. An infeasible assignment is named infeasible, not scored; unscheduled jobs are penalised, not ignored. Both behaviours are shown below, on responses captured from real calls to this endpoint.
curl -X POST https://www.orbitroute.ai/api/v1/compute/benchmark/score \
-H "Content-Type: application/json" \
-d '{"seed": 42,
"assignment": [{"job_id": "J000", "asset_id": "A00", "start_s": 98}]}'
{
"seed": 42,
"submitted": {
"feasible": false,
"violations": [
"J000 does not fit a contact window on A00"
],
"scheduled_count": 0,
"unscheduled_count": 24,
"total_cost_usd": 0.0,
"lateness_penalty": 0.0,
"objective": 240.0
},
"classical_baseline_objective": 3.6699,
"objective_delta_vs_baseline": 236.3301,
"beats_classical_baseline": false,
"verdict": "infeasible — not scored against the baseline"
}
The honesty rule in action: a broken submission is not quietly graded as a loss — the verdict names it infeasible, violations says exactly why, and the 23 jobs the submission never mentioned are counted as unscheduled rather than ignored (objective 240.0 = 24 unscheduled × the instance's published 10.0-per-job penalty).
# pull the reference assignment out of /benchmark/reference, submit it back
curl -s "https://www.orbitroute.ai/api/v1/compute/benchmark/reference?seed=42" \
| jq '{seed: 42, assignment: .annealer.assignment}' \
| curl -X POST https://www.orbitroute.ai/api/v1/compute/benchmark/score \
-H "Content-Type: application/json" -d @-
{
"seed": 42,
"submitted": {
"feasible": true,
"violations": [],
"scheduled_count": 24,
"unscheduled_count": 0,
"total_cost_usd": 3.6299,
"lateness_penalty": 0.04,
"objective": 3.6699
},
"classical_baseline_objective": 3.6699,
"objective_delta_vs_baseline": 0.0,
"beats_classical_baseline": false,
"verdict": "does not beat the classical baseline"
}
Feasible at 24/24 and exactly the baseline objective — the tie from section 5, graded through the public scorer. If your solver's objective comes in under 3.6699, beats_classical_baseline flips to true; the verdict is arithmetic, not editorial.
7. From benchmark to directory
When you are ready to be listed, the compute profile rides the existing federation advertisement: add a compute object to POST /api/v1/federation/nodes (walkthrough on /federation). The 201 echoes exactly what your profile changes — today a non-GPU modality keeps a node out of the GPU routing fleet, and since no non-GPU fleet is live, a listed non-GPU node receives no work. That echo, this page, and the modality note all say the same thing on purpose.
Where the routing numbers come from: /methodology. The full customer surface: /api-reference. Whether it is up right now: /status.