{"openapi":"3.0.3","info":{"title":"CPS - Cheapest-Power Scheduler","version":"mvp-2","description":"Advisory scheduler intelligence for AI training and batch workloads. CPS watches real day-ahead power prices across customer sites and regions, then recommends where and when each flexible job should run to minimize power cost. Advisory only: CPS recommends, a human approves, and the customer's own scheduler dispatches. Every decision is sealed as a tamper-evident, hash-chained receipt.","contact":{"name":"CPS Support","email":"support@syensystems.com"}},"servers":[{"url":"https://cps.sedra-0b3.workers.dev"}],"security":[{"bearerAuth":[]}],"paths":{"/health":{"get":{"summary":"Service health, live price feeds, and pricing. No key required.","security":[],"responses":{"200":{"description":"Service status, live feeds, last price poll, active site count, decisions today, and pricing."}}}},"/api/signup":{"post":{"summary":"Self-serve account creation. Returns an API key, shown once. No key required.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["work_email","company"],"properties":{"name":{"type":"string"},"work_email":{"type":"string","format":"email"},"company":{"type":"string"}}}}}},"responses":{"201":{"description":"Account created. Response includes api_key (shown once) and principal id."},"400":{"description":"Missing or invalid work_email / company."},"429":{"description":"Too many signup attempts from this address."}}}},"/sites":{"post":{"summary":"Register a datacenter or region as a site. Prices are hydrated immediately at registration.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","region","node"],"properties":{"name":{"type":"string"},"region":{"type":"string"},"price_source":{"type":"string","default":"caiso_oasis_dam","example":"caiso_oasis_dam or nyiso_dam"},"node":{"type":"string","description":"Price node for the source, e.g. TH_NP15_GEN-APND (CAISO NP15) or N.Y.C. (NYISO)."},"kw_per_gpu":{"type":"number","default":0.7},"pue":{"type":"number","default":1.3},"gpu_capacity":{"type":"integer","default":0},"hypothetical":{"type":"boolean","default":false}}}}}},"responses":{"201":{"description":"Site created; includes id and price_backfill status."},"400":{"description":"name, region, node required."}}},"get":{"summary":"List your sites.","responses":{"200":{"description":"Array of site objects scoped to the calling principal."}}}},"/prices/ingest":{"post":{"summary":"Push observed price rows for one of your sites (the daily poller also refreshes prices automatically).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["site_id","prices"],"properties":{"site_id":{"type":"string"},"prices":{"type":"array","items":{"type":"object","properties":{"ts":{"type":"string","format":"date-time"},"price_per_kwh":{"type":"number"}}}},"source":{"type":"string","default":"caiso_oasis_dam"}}}}}},"responses":{"200":{"description":"Number of rows ingested."},"400":{"description":"site_id and prices[] required."},"404":{"description":"Site not found."}}}},"/jobs":{"post":{"summary":"Submit a flexible GPU job for scheduling advice.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["gpu_count","est_hours"],"properties":{"name":{"type":"string"},"gpu_count":{"type":"integer"},"est_hours":{"type":"number"},"flex_start":{"type":"string","format":"date-time","description":"Defaults to now."},"flex_end":{"type":"string","format":"date-time","description":"Defaults to now + 48h."}}}}}},"responses":{"201":{"description":"Job created; includes id and principal."},"400":{"description":"gpu_count, est_hours required."},"402":{"description":"Payment required."}}}},"/jobs/{id}":{"get":{"summary":"Fetch a job and its latest decision.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Job plus latest decision summary."},"404":{"description":"Job not found."}}}},"/jobs/{id}/recommendation":{"get":{"summary":"Get the cheapest site and start window for a job. Seals a tamper-evident decision receipt.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Recommendation with every option priced in dollars, plus decision_id and receipt_hash. Advisory only: approve the decision to accept it."},"404":{"description":"Job not found."},"422":{"description":"No feasible site with price data in the window."}}}},"/decisions/{id}/approve":{"post":{"summary":"Approve a proposed decision (human-in-the-loop accept).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Decision approved; job marked scheduled."},"404":{"description":"Decision not found."},"409":{"description":"Decision already decided."}}}},"/decisions/{id}/reject":{"post":{"summary":"Reject a proposed decision.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Decision rejected."},"404":{"description":"Decision not found."},"409":{"description":"Decision already decided."}}}},"/decisions/{id}/dispatch":{"post":{"summary":"Record that an approved decision was handed to your scheduler (Slurm/Kubernetes plugin).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"cluster_job_id":{"type":"string"}}}}}},"responses":{"200":{"description":"Dispatch recorded with timestamp."},"404":{"description":"Decision not found."},"409":{"description":"Not approved or already dispatched."}}}},"/decisions/{id}/close":{"post":{"summary":"Close a dispatched decision with the real run window. CPS computes actual power cost from its price history and records it next to the projection.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["actual_start","actual_end"],"properties":{"actual_start":{"type":"string","format":"date-time"},"actual_end":{"type":"string","format":"date-time"}}}}}},"responses":{"200":{"description":"Actual cost and variance vs projection."},"400":{"description":"Invalid or missing window."},"404":{"description":"Decision not found."},"409":{"description":"Never dispatched or already closed."}}}},"/decisions/{id}/receipt":{"get":{"summary":"Fetch the sealed decision receipt. Recompute sha256 over the canonical decision fields to verify receipt_hash; follow prev_hash to walk the chain.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Full receipt: job, recommended site, options, hashes, timestamps, and actuals when closed."},"404":{"description":"Decision not found."}}}},"/metering":{"get":{"summary":"Metering records (GPUs managed, decisions issued, GPU-hours) and current pricing.","parameters":[{"name":"principal","in":"query","schema":{"type":"string"}},{"name":"month","in":"query","schema":{"type":"string","example":"2026-10"}}],"responses":{"200":{"description":"Metering rows plus pricing: $10 per GPU managed per month; pilot $5,000 flat for 30 days on one cluster."}}}},"/api/overview":{"get":{"summary":"Aggregate stats for your account (dashboard data).","responses":{"200":{"description":"Job count, decisions by status, projected totals, GPUs managed."}}}},"/api/decisions":{"get":{"summary":"Your 100 most recent decisions with job and site names.","responses":{"200":{"description":"Decision list scoped to the calling principal."}}}},"/api/sites-prices":{"get":{"summary":"Your sites with their latest observed power price.","responses":{"200":{"description":"Sites each with latest_price {price_per_kwh, observed_at, source}."}}}},"/api/account":{"delete":{"summary":"Delete your account and all your data (sites, jobs, decisions, metering) in one call.","responses":{"200":{"description":"Account data wiped."}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"CPS API key issued by POST /api/signup. Send as Authorization: Bearer <key>."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"type":"boolean","example":false},"error":{"type":"string"}}}}}}