Docs/API reference/v1
Data API
Source-labeled AI-infrastructure data over REST. v1 covers the GreenCIO Compute Index, capacity intelligence, inference economics, levelized cost of energy, AI-infrastructure review, and a set of reference fixtures that are deliberately withheld from customer traffic. Every response declares how the numbers were produced, so a result can be traced before it is cited.
Request a design-partner key →
https://www.greencio.com/api/v1- JSON over HTTPS. ISO-8601 UTC throughout. Server-to-server only — CORS is not enabled.
- Bearer auth. Cursor pagination.
{ data, meta }envelope,{ error }on failure. - Every success carries
meta.source_mode; reference products add freshness, evidence, and source-rights fields. - Additive changes only inside
/v1. Breaking changes get/v2.
Quickstart#
Three steps once a reviewed key has been issued. Read Product availability before you build against a route — several namespaces exist in the contract but are held back from customer traffic on purpose.
1. Request a design-partner key.
Send a reviewed access request, naming the products you need. Self-service issuance is closed for this launch. Approved test and live keys are delivered through an operator-controlled channel and use the same Bearer path.
2. Set the Authorization header.
bashexport GREENCIO_API_KEY="gc_live_..."3. Make your first request.
curlGET /v1/capacity/intelligencecurl "https://www.greencio.com/api/v1/capacity/intelligence?limit=1" \ -H "Authorization: Bearer $GREENCIO_API_KEY"Field names and metadata below are exact. Values are placeholders — this page does not publish live rows.
json200 OK{ "data": [ { "id": "int_<26-char opaque suffix>", "title": "<publisher headline>", "summary": "<GreenCIO-authored summary, 200 characters maximum>", "source_url": "https://publisher.example/article", "source_name": "<publisher>", "published_at": "<iso-8601 utc>", "discovered_at": "<iso-8601 utc>", "relevance_score": "<0..1>", "impact_level": "high", "sentiment": "neutral", "summary_kind": "derived_summary", "source_rights": { "policy_id": "news_publisher_default", "counsel_status": "approved", "redistribution_status": "derived_only", "publication_scope": "public_summary_only" }, "tags": ["<tag>"], "entities": { "companies": ["<company>"], "locations": ["<location>"], "technologies": ["<technology>"], "financialAmounts": ["<amount>"] } } ], "meta": { "generated_at": "<iso-8601 utc>", "request_id": "req_<26-char opaque suffix>", "next_cursor": "<opaque base64url or null>", "source_mode": "persisted", "feed_last_updated": "<iso-8601 utc>", "status": "live", "freshness": "fresh", "last_success_at": "<iso-8601 utc>", "age_seconds": "<integer>", "max_age_seconds": "<integer>", "source_rights": { "policy_id": "news_publisher_default", "...": "..." } } }
The envelope is identical on every route. Collections carry meta.next_cursor; single resources omit it. Continue with Authentication for key entitlements, or jump to Reference for the endpoint list.
Authentication#
Every request carries an Authorization: Bearer header. The prefix identifies the environment; it does not grant products.
| Prefix | Environment | Billable | Issued by |
|---|---|---|---|
gc_test_ | Test sandbox | No | Reviewed request |
gc_live_ | Live production | Yes | Reviewed request |
curl https://www.greencio.com/api/v1/index/compute \
-H "Authorization: Bearer $GREENCIO_API_KEY"Entitlements are not the prefix#
Product access comes from the customer record attached to the key, not from gc_test_ or gc_live_. Operator-issued sandbox keys are provisioned at Insights entitlement with Pro-level throughput, so a Pro-only route answers 403 unauthorized on a default test key. Name the products you intend to call at review time and they are granted on the key.
A live key additionally enforces the data gates described under Product availability: entitlement alone never causes unqualified data to be served.
Key lifecycle#
- Issued. The secret is shown once. Only a salted scrypt hash and a short non-secret prefix are stored, so a lost key is replaced, never recovered.
- Active. Validated on every request;
last_used_atadvances on each accepted call. - Expiring. Sandbox keys default to a 30-day life (90-day ceiling); live keys default to one year. Both are set per key at issuance.
- Revoked or expired.
401 unauthenticated. Revocation and rotation are operator-driven and take effect on the next request.
Transport and caching#
- CORS is not enabled and will not be. Browser clients must call through your own backend.
- Every response sets
Vary: Authorization. Cacheable routes downgrade toprivate; everything else isno-store. Nothing is shared-cacheable. X-Request-Idis returned on success and failure and matchesmeta.request_id/error.request_id.
Product availability#
A route existing in the contract is not a claim that it will return data. Products are gated independently on persistence, freshness, methodology qualification, and source rights. Where a gate is not met the route answers 503 service_unavailable with a reason — it never substitutes seeded or synthetic rows.
| Route family | Tier | Serves a live key | Condition |
|---|---|---|---|
/v1/index/compute* | Pro | Yes, when qualified | Latest settlement set must be persisted, inside its freshness window, and methodology-qualified. Provisional rows are excluded by default and cannot be requested on a live key. |
/v1/capacity/intelligence* | Insights | Yes, when qualified | Requires the persisted feed, cleared publication rights, and a canonical source URL on every row in the page. |
/v1/inference/token-prices* | Pro | Yes | Returns the current source-linked snapshot. A persisted snapshot outside its freshness window fails closed rather than serving stale prices. |
/v1/lcoe, /v1/inference/unit-economics, /v1/ai-infra/review | Insights / Pro / Pro | Yes | Deterministic functions of the submitted body. No upstream data dependency, so no availability gate. |
/v1/capacity/signals*, /v1/facilities*, /v1/fabs* | Insights / Pro | No — 503 | Quarantined reference fixtures. Available only in an explicit local demo or test runtime, never to a live key and never from customer-serving infrastructure. |
/v1/index/power*, /v1/carbon/*, /v1/webhooks* | — | No — not routed | Reserved namespaces described in the OpenAPI document. No handler exists, so these paths return the site 404 rather than an API error envelope. |
Build retry and alerting around 503 as a first-class state, not an exception. It is how the API says a number did not clear its own evidence bar. Availability is evaluated before query validation, so a gated product answers 503 even when the same request also carries a bad filter — tune filters against a product that is serving.
Conventions#
Every endpoint follows the same conventions. Once you know them you know all of v1.
Response envelope#
Success responses always have data and meta. Error responses always have error and nothing else. Errors never appear inside data, and a partial page is never returned as a success.
{
"data": [ /* items */ ],
"meta": {
"generated_at": "<iso-8601 utc>",
"request_id": "req_<opaque>",
"next_cursor": "<opaque base64url or null>",
"source_mode": "persisted"
}
}{
"error": {
"code": "invalid_filter",
"message": "since must be ISO-8601 UTC",
"field": "since",
"request_id": "req_<opaque>"
}
}error.field is always present and is null when no single field is at fault. Product-specific keys are added to meta, never removed from it, so a consumer that reads only the four common keys stays forward-compatible.
Source mode#
meta.source_mode is the field that decides whether a number may be cited. Read it before the payload.
| Value | Meaning | Live key |
|---|---|---|
persisted | Written by a production pipeline run and read back from storage. | Served |
submitted_model | Deterministic output of a calculator over the assumptions in your request body. No stored data is mixed in. | Served |
static_reference | A versioned reference artifact with an observation date and source metadata rather than a live pipeline. | Served unless the product is separately quarantined |
seed_reference | Preview fixture retained for shape testing. Source-linked rows only, legacy scores labeled unverified. | Refused (503) |
synthetic_demo | Generated demo data for local development. | Refused (503) |
Reference products add freshness, age_seconds, max_age_seconds, evidence_status, and a source_rights object carrying the policy id, counsel status, redistribution status, and publication scope that govern reuse of the rows.
Pagination#
Collections are cursor-paginated. The cursor is an opaque base64url token: round-trip exactly what we sent and do not parse it, because its internal shape is not part of the contract and will change. A cursor addresses a position in the result set as it stood when the page was produced, so for a set that changes between calls, page boundaries can shift. Filter on since and de-duplicate on resource id when you need an exactly-once sweep.
# First page
curl "https://www.greencio.com/api/v1/index/compute/history?limit=100" \
-H "Authorization: Bearer $GREENCIO_API_KEY"
# Next page — pass meta.next_cursor from the previous response
curl "https://www.greencio.com/api/v1/index/compute/history?limit=100&cursor=<meta.next_cursor>" \
-H "Authorization: Bearer $GREENCIO_API_KEY"limitdefaults to 50, maximum 500. A non-integer or out-of-range value is a400 invalid_filter, not a silent clamp.meta.next_cursorisnullwhen the result set is exhausted.- A malformed or unreadable cursor is a
400 invalid_filteron fieldcursor.
Time format#
Every timestamp we return is an ISO-8601 instant in UTC, for example 2026-05-16T00:00:00.000Z. No Unix epoch, no locale variation, no local offsets on the way out.
- Query filters that accept a time require UTC and reject anything else with
400 invalid_filter. - A timestamp inside a request body may carry an explicit offset —
2026-08-01T05:30:00+05:30is accepted. It is converted to UTC before it is hashed, stored, or echoed, so the same instant written either way produces the same result and the same resource id.
Resource IDs#
IDs are opaque, stable across responses, and prefixed by resource type. Resource ids are derived deterministically from the underlying record, so the same row keeps the same id between runs.
| Prefix | Resource |
|---|---|
set_ | Compute Index settlement |
basis_ | Compute Index basis spread |
int_ | Capacity intelligence item |
sig_ | Capacity signal |
fac_ | Data-center facility |
fab_ | Semiconductor fab |
cp_ | Supply-chain chokepoint |
air_ | AI infrastructure review |
req_ | Request identifier (response only) |
Errors#
Every failure uses the same envelope and one of a closed set of codes. Match on code, never on message: messages are tuned for clarity, codes are part of the contract.
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Malformed body, unreadable JSON, missing required header, or a body that exceeds the nesting and node ceilings. |
| 400 | invalid_filter | Query parameter rejected. field names the offender. |
| 401 | unauthenticated | Missing, malformed, unknown, expired, or revoked key. |
| 403 | unauthorized | Key is valid but the customer record does not include this product, or the request asks for data the key may not receive. |
| 404 | not_found | Resource id or index name not recognized within the entitled result set. |
| 408 | request_timeout | Processing exceeded the server-side deadline. Safe to retry; an in-flight idempotent write keeps its lease briefly to prevent a duplicate. |
| 409 | idempotency_conflict | Same Idempotency-Key with a different body, or reused while the first call is still running. |
| 413 | payload_too_large | Request body exceeds the endpoint byte limit. |
| 422 | validation_failed | Body parsed but failed schema validation. Unknown fields are rejected, not ignored. |
| 429 | rate_limited | Burst or monthly quota exceeded. Honor Retry-After. |
| 500 | internal_error | A defect on our side. Report it with the request_id. |
| 503 | service_unavailable | A data, rights, freshness, or capacity gate was not met. The message states which. Retry with backoff. |
Rate-limit headers accompany every response produced after the limit check — successes and failures alike — so a client keeps an accurate budget model without needing a successful call. Authentication and entitlement failures are rejected before the check and carry no rate-limit headers.
Limits#
Rate limits#
Two independent limits apply: a per-second burst and a monthly quota. Both are reported on every response, including successes, so you never have to provoke a 429 to learn what is left.
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 28
X-RateLimit-Reset: 2026-05-16T00:00:01Z
X-RateLimit-Quota-Limit: 50000
X-RateLimit-Quota-Remaining: 47233
X-RateLimit-Quota-Reset: 2026-06-01T00:00:00Z- The burst limit is enforced per key and per endpoint in one-second windows. Parallelising across different routes does not consume one shared bucket.
- The monthly quota is enforced per key and resets at the start of the UTC month.
- A quota unit is reserved once a request clears authentication, entitlement, and the burst gate — before the handler runs. Everything past that point costs one unit, success or failure, so budget for your
4xxand5xxtraffic. - Rejections upstream of that point are free:
401,403, and a429raised by the burst limit consume no quota. Throttling never bills you, so a client backing off correctly is not paying for the backoff. - Breaching either limit returns
429 rate_limitedwithRetry-Afterin seconds.
| Tier | Burst / sec / endpoint | Quota / month |
|---|---|---|
| Insights | 30 | 50,000 |
| Pro | 100 | 250,000 |
| Enterprise | 300 | 1,000,000 |
These are the defaults applied at issuance; both values are set per key and can be raised on a reviewed request. Sandbox keys are provisioned at Pro-level throughput so integration work is not throttled, and their quota counter is separate from any live key on the same account.
Request limits#
Bounds are enforced at the edge of every route so that one malformed or oversized call cannot degrade the endpoint for other traffic.
| Bound | Default | On breach |
|---|---|---|
| Request body | 64 KiB | 413 payload_too_large |
| JSON depth / nodes | 32 levels, 10,000 nodes | 400 invalid_request |
| Server-side deadline | 10 seconds per request | 408 request_timeout |
| Serialized response | 2 MiB | 503 — retry with a smaller limit |
| Concurrent work per endpoint | Bounded per process | 503 — retry with backoff |
A large historical pull should page with limit and cursor rather than requesting one oversized page; the response cap is checked before the body is written.
Idempotency#
An Idempotency-Key header is required on every POST route in v1 — /v1/lcoe, /v1/inference/unit-economics, and /v1/ai-infra/review. Omitting it is a 400 invalid_request naming the header, so a network retry can never silently double-charge a metered call.
curl -X POST https://www.greencio.com/api/v1/lcoe \
-H "Authorization: Bearer $GREENCIO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"capex_usd": 1200000000,
"annual_generation_mwh": 2400000,
"project_lifetime_years": 20,
"discount_rate": 0.08,
"annual_opex_usd": 40000000
}'- Scope is the key plus method, path, and a hash of the exact request body. The same header value on a different route is a different record.
- Same key, same body, within 24 hours → the work runs exactly once. Whichever call reserved the key executes; the rest replay its status and body byte-for-byte, including the original
request_id. Safe to retry and safe to send concurrently, inside that window. - Same key, same body, arriving before the first call has committed →
409 idempotency_conflictwith an in-progress message, rather than a second execution. Treat it as “retry shortly,” not as a failure. - Same key, different body →
409 idempotency_conflict. Choose a new key. - Completed responses stay replayable for 24 hours. A reservation abandoned by a failure is released immediately; one abandoned by a timeout clears after two minutes.
- After 24 hours the key is free again. The expired record is pruned and the same key with the same body reserves afresh, so the call executes and meters a second time. A retry queue that can outlive a day should carry a deadline, not an assumption that the key still protects it.
- Use a UUID, a request hash, or any opaque 8–200 character string. We match it, we do not parse it.
Reference#
The tier column is the entitlement that grants the route. Availability per product is in Product availability; the machine-readable contract is at /openapi.yaml.
GreenCIO Compute Index#
Spot and forward GPU-hour reference settlements across SKU × region × tenor, each with an uncertainty band, a basis relationship to the headline settlement, a methodology version, and a per-settlement audit record. The index is administered independently of any exchange or clearing house, and settlements are informational references rather than executable quotes.
| Method | Path | Description | Tier |
|---|---|---|---|
| GET | /v1/index/computeCurrent settlement set | Current settlement set | Pro |
| GET | /v1/index/compute/{index_name}Single settlement by index name or settlement id | Single settlement by index name or settlement id | Pro |
| GET | /v1/index/compute/historyHistorical settlements, cursor-paginated | Historical settlements, cursor-paginated | Pro |
| GET | /v1/index/compute/basisBasis spreads against the headline settlement | Basis spreads against the headline settlement | Pro |
| GET | /v1/index/compute/methodologyActive methodology version and rulebook hash | Active methodology version and rulebook hash | Pro |
| Parameter | Routes | Notes |
|---|---|---|
sku | Current set | Exact match. |
region | Current set | Exact match. |
tenor | Current set | Exact match. |
index_name | History | Exact match on the composite index name. |
since | History | ISO-8601 UTC. Rejected on /basis against persisted data until historical basis rows are exposed. |
spread_index_name | Basis | Exact match on the base/headline pair name. |
include_provisional | Settlement routes | Boolean. Excluded by default; 403 on a live key. |
Each settlement carries an audit object — the run id, the input ids that were included, the inputs that were rejected, the per-source weight shares, the input hash, and any settlement it supersedes — plus meta.audit_hash and meta.methodology_version. That record is what makes a cited settlement reproducible. Contents are returned to entitled keys and are elided here.
{
"data": [
{
"id": "set_<opaque>",
"index_name": "GCI-<SKU>-<REGION>-<TENOR>",
"sku": "<sku>",
"region": "<region>",
"tenor": "SPOT",
"as_of": "<iso-8601 utc>",
"currency": "USD",
"value": "<usd per gpu-hour>",
"band_low": "<usd per gpu-hour>",
"band_high": "<usd per gpu-hour>",
"band_pct": "<fraction of value>",
"n_inputs": "<integer>",
"n_venues": "<integer>",
"provisional": false,
"methodology_version": "<methodology version>",
"input_hash": "<sha-256 hex>",
"source_mode": "persisted",
"audit": {
"run_id": "<run id>",
"included_input_ids": ["<input id>"],
"rejected_inputs": [],
"source_weight_shares": { "<source>": "<share>" },
"supersedes_settlement_id": null
}
}
],
"meta": {
"generated_at": "<iso-8601 utc>",
"request_id": "req_<opaque>",
"next_cursor": null,
"source_mode": "persisted",
"methodology_version": "<methodology version>",
"audit_hash": "<sha-256 hex>",
"status": "live",
"freshness": "fresh",
"methodology_state": "methodology_met",
"provisional_policy": "excluded_by_default",
"provisional_filtered_count": 0
}
}Methodology governance, the qualification rules, and the change process are published on the Compute Index governance page.
Capacity intelligence#
Classified AI-infrastructure developments — permits, interconnection filings, financings, supply-chain events — as publisher headline plus a GreenCIO-authored summary. Third-party article bodies are never returned. Every row must carry a canonical external HTTPS source URL; a page containing a row that does not fails the whole response with 503 rather than shipping an untraceable item.
| Method | Path | Description | Tier |
|---|---|---|---|
| GET | /v1/capacity/intelligenceSource-linked intelligence items | Source-linked intelligence items | Insights |
| GET | /v1/capacity/intelligence/{id}Single intelligence item | Single intelligence item | Insights |
| Parameter | Notes |
|---|---|
impact | One of high, medium, low. Anything else is 400 invalid_filter. |
tags | Comma-separated. Matches an item carrying any listed tag. |
since | ISO-8601 UTC, filtered on discovered_at. |
limit, cursor | Standard pagination. |
Summaries are capped at 200 characters and labeled summary_kind: derived_summary. The source_rights object on every row and on meta states the redistribution terms that travel with the text, so downstream reuse can be checked programmatically.
Inference economics#
Two deterministic calculators and a source-linked provider token-price snapshot. Both calculators consume only what you submit and return source_mode: submitted_model; unit economics additionally reports provider_price_rows_used: 0. No provider price is silently substituted into your model, and no output is a quote, a tariff, or a financing term.
| Method | Path | Description | Tier |
|---|---|---|---|
| GET | /v1/inference/token-pricesInput/output token prices per provider model, USD per 1M tokens | Input/output token prices per provider model, USD per 1M tokens | Pro |
| GET | /v1/inference/token-prices/historySingle labeled snapshot; history_available is false | Single labeled snapshot; history_available is false | Pro |
| POST | /v1/inference/unit-economicsLevelized inference cost. Idempotency-Key required. | Levelized inference cost. Idempotency-Key required. | Pro |
| POST | /v1/lcoeLevelized cost of energy. Idempotency-Key required. | Levelized cost of energy. Idempotency-Key required. | Insights |
| Parameter | Routes | Notes |
|---|---|---|
provider | Token prices | Exact match, case-insensitive. |
model_class | Token prices | Exact match, case-insensitive. |
since | Token-price history | ISO-8601 UTC, filtered on observed_at. |
/v1/inference/token-prices/history returns the same snapshot the current route returns, labeled series_type: single_snapshot_not_history and history_available: false. Do not build a time series on it until that flag flips.curl -X POST https://www.greencio.com/api/v1/inference/unit-economics \
-H "Authorization: Bearer $GREENCIO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ue-2026-05-16-001" \
-d '{
"facility_capacity_mw": 120,
"gpu_count": 8192,
"gpu_type": "H100",
"capex_usd": 2500000000,
"power_cost_usd_per_mwh": 68,
"utilization_rate": 0.72
}'Omitted optional assumptions take a fixed default rather than being inferred from anything else. Several of them move the headline number, so set them deliberately.
| Field | Route | Default when omitted |
|---|---|---|
tokens_per_second_per_gpu | Unit economics | 120 — drives the token-capacity denominator |
pue | Unit economics | 1.2 |
project_lifetime_years | Unit economics | 5 (required on LCOE) |
discount_rate | Unit economics | 0.12 (required on LCOE) |
annual_opex_usd | Both | 0 |
annual_fuel_cost_usd, opex_escalation_rate, fuel_escalation_rate, degradation_rate | LCOE | 0 |
Each response repeats the methodology version it was computed under and carries an explicit disclaimer field. Out-of-range inputs are rejected with 422 validation_failed naming the field rather than being clamped.
AI infrastructure review#
The shared contract behind the GreenCIO CLI and the MCP coding profile. It accepts a normalized description of an infrastructure repository — relative paths plus a fixed allowlist of detected facts — and returns the assembled fact set, the evidence still missing, and any submitted-assumption economics or power screen you asked for.
| Method | Path | Description | Tier |
|---|---|---|---|
| POST | /v1/ai-infra/reviewReview normalized infrastructure facts. Idempotency-Key required. | Review normalized infrastructure facts. Idempotency-Key required. | Pro |
The request schema is strict: unknown fields are rejected with 422 validation_failed. The route accepts no repository source text, no code snippets, no environment values, and no credentials, and every response asserts that boundary back in provenance.repository_content_received: false and provenance.network_data_fetched_by_review: false.
| Body field | Required | Contents |
|---|---|---|
scan | Yes | File count, optional repository name and revision, a truncation flag, and the findings list. Each finding is a relative path, an optional line number, a source kind, and at least one of provider, region, gpu_type, gpu_count, replicas, utilization_rate, model. |
economics | No | Unit-economics assumptions, evaluated by the same calculator as the dedicated route. |
power | No | Site facts for the heuristic time-to-power screen. Not an interconnection study. |
compute_price_basis | No | A settlement you are pricing against, carried through with its observation time, methodology version, and source mode. |
413 payload_too_large. Split a large repository across requests, each with its own Idempotency-Key, and set scan.truncated when your scanner stopped early so the response can say the picture is incomplete.Findings are treated as pattern matches, not proof of deployed infrastructure, and the response says so in warnings. A review with no economics and no power screen returns status facts_only together with the missing_evidence list needed to reach actionable.
Quarantined fixtures#
Three route families are implemented and covered by tests but deliberately withheld from customer traffic. They answer 503 for any live key and from any customer-serving runtime, and are reachable only in an explicit local demo or test profile. They are documented so a contract diff does not read as an undisclosed surface — not because they are usable evidence.
| Method | Path | Description | Tier |
|---|---|---|---|
| GET | /v1/capacity/signalsSource-linked seed signals, legacy scores unverified | Source-linked seed signals, legacy scores unverified | Insights |
| GET | /v1/capacity/signals/{id}Single seed signal | Single seed signal | Insights |
| GET | /v1/facilitiesFacility CSV fixture | Facility CSV fixture | Insights |
| GET | /v1/facilities/{id}Single facility fixture row | Single facility fixture row | Insights |
| GET | /v1/fabsSemiconductor fab fixture | Semiconductor fab fixture | Pro |
| GET | /v1/fabs/{id}Single fab fixture row | Single fab fixture row | Pro |
| GET | /v1/fabs/chokepointsSupply-chain chokepoint fixture | Supply-chain chokepoint fixture | Pro |
| Fixture | Why it is withheld |
|---|---|
/v1/capacity/signals | Rows without a canonical external source URL are dropped, but the surviving corpus still carries no approved publication-rights record and its legacy confidence scores have no verified methodology. Linked-market probabilities are never synthesized, so the array is always empty. |
/v1/facilities | The CSV carries prose source notes but no canonical per-row URLs, no approved rights record, and no source observation date. File modification time is not freshness evidence, so the snapshot date is reported as null alongside the artifact hash and row count. |
/v1/fabs | No row-level citations and no approved redistribution policy. Rows are labeled unverified and stale. Do not treat them as node-capacity evidence. |
Deferred namespaces#
Three namespaces appear in the OpenAPI document as a declared target contract and have no handler. Requests to them return the site 404, not an API error envelope, so client code can distinguish “not built” from “built but gated”.
| Namespace | Target | Blocking work |
|---|---|---|
/v1/index/power* | v1.1 | Power Forecast needs prediction-market integration before it can return probability bands. An empty namespace is preferable to an uncalibrated one. |
/v1/carbon/* | v1.2 | Carbon Trail targets corporate sustainability filings and needs an assurance-grade audit chain before it ships. |
/v1/webhooks* | v1.1 | Push delivery is an operational commitment — retry policy, signed payloads, dead-letter handling, replay. Pull-mode polling is the contract until then. |
Design-partner access is the way to influence which of these lands first.
Versioning & status#
- URL version. The path prefix
/v1is the compatibility promise: additive changes only, and a breaking change becomes/v2. - Document version.
/openapi.yamlcarries its owninfo.version, which tracks revisions of the product contract — including the deferred namespaces — and moves independently of the URL prefix. Pin against the path prefix, not the document version. - Non-contract routes. Only paths under
/api/v1are covered. Other/api/*routes are internal application surfaces and may change without notice. - Reporting. Include the failing call's
request_id; it is the join key to the server-side record of that exact request.
Changelog
- v1 contract — implemented route families: Compute Index, capacity intelligence, inference economics and LCOE, AI-infrastructure review, and the quarantined capacity-signal, facility, and fab fixtures. Power Forecast, Carbon Trail, and webhooks are reserved for later versions.
Next steps
Keep building from here
Keys stay operator-issued. Pair the REST contract with MCP for agents, or open the Index product area your desk already reviews.