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 →

Base URL
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. 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. 2. Set the Authorization header.

    bash
    export GREENCIO_API_KEY="gc_live_..."
  3. 3. Make your first request.

    curlGET /v1/capacity/intelligence
    curl "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.

PrefixEnvironmentBillableIssued by
gc_test_Test sandboxNoReviewed request
gc_live_Live productionYesReviewed request
bash
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_at advances 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 to private; everything else is no-store. Nothing is shared-cacheable.
  • X-Request-Id is returned on success and failure and matches meta.request_id / error.request_id.
Never use a live key from browser code. Keys belong in environment variables or a secret manager, not in client bundles or public repositories. A compromised key is revoked through a reviewed request and a replacement is issued; the old secret cannot be re-enabled.

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 familyTierServes a live keyCondition
/v1/index/compute*ProYes, when qualifiedLatest 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*InsightsYes, when qualifiedRequires the persisted feed, cleared publication rights, and a canonical source URL on every row in the page.
/v1/inference/token-prices*ProYesReturns 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/reviewInsights / Pro / ProYesDeterministic functions of the submitted body. No upstream data dependency, so no availability gate.
/v1/capacity/signals*, /v1/facilities*, /v1/fabs*Insights / ProNo — 503Quarantined 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 routedReserved 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.

jsonSuccess — collection
{
  "data": [ /* items */ ],
  "meta": {
    "generated_at": "<iso-8601 utc>",
    "request_id": "req_<opaque>",
    "next_cursor": "<opaque base64url or null>",
    "source_mode": "persisted"
  }
}
jsonError — any status ≥ 400
{
  "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.

ValueMeaningLive key
persistedWritten by a production pipeline run and read back from storage.Served
submitted_modelDeterministic output of a calculator over the assumptions in your request body. No stored data is mixed in.Served
static_referenceA versioned reference artifact with an observation date and source metadata rather than a live pipeline.Served unless the product is separately quarantined
seed_referencePreview fixture retained for shape testing. Source-linked rows only, legacy scores labeled unverified.Refused (503)
synthetic_demoGenerated 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.

curl
# 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"
  • limit defaults to 50, maximum 500. A non-integer or out-of-range value is a 400 invalid_filter, not a silent clamp.
  • meta.next_cursor is null when the result set is exhausted.
  • A malformed or unreadable cursor is a 400 invalid_filter on field cursor.

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:30 is 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.

PrefixResource
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.

HTTPCodeMeaning
400invalid_requestMalformed body, unreadable JSON, missing required header, or a body that exceeds the nesting and node ceilings.
400invalid_filterQuery parameter rejected. field names the offender.
401unauthenticatedMissing, malformed, unknown, expired, or revoked key.
403unauthorizedKey is valid but the customer record does not include this product, or the request asks for data the key may not receive.
404not_foundResource id or index name not recognized within the entitled result set.
408request_timeoutProcessing exceeded the server-side deadline. Safe to retry; an in-flight idempotent write keeps its lease briefly to prevent a duplicate.
409idempotency_conflictSame Idempotency-Key with a different body, or reused while the first call is still running.
413payload_too_largeRequest body exceeds the endpoint byte limit.
422validation_failedBody parsed but failed schema validation. Unknown fields are rejected, not ignored.
429rate_limitedBurst or monthly quota exceeded. Honor Retry-After.
500internal_errorA defect on our side. Report it with the request_id.
503service_unavailableA 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.

httpResponse headers (every request)
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 4xx and 5xx traffic.
  • Rejections upstream of that point are free: 401, 403, and a 429 raised 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_limited with Retry-After in seconds.
TierBurst / sec / endpointQuota / month
Insights3050,000
Pro100250,000
Enterprise3001,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.

BoundDefaultOn breach
Request body64 KiB413 payload_too_large
JSON depth / nodes32 levels, 10,000 nodes400 invalid_request
Server-side deadline10 seconds per request408 request_timeout
Serialized response2 MiB503 — retry with a smaller limit
Concurrent work per endpointBounded per process503 — 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
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 committed409 idempotency_conflict with an in-progress message, rather than a second execution. Treat it as “retry shortly,” not as a failure.
  • Same key, different body409 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.

MethodPathTier
GET/v1/index/compute

Current settlement set

Pro
GET/v1/index/compute/{index_name}

Single settlement by index name or settlement id

Pro
GET/v1/index/compute/history

Historical settlements, cursor-paginated

Pro
GET/v1/index/compute/basis

Basis spreads against the headline settlement

Pro
GET/v1/index/compute/methodology

Active methodology version and rulebook hash

Pro
ParameterRoutesNotes
skuCurrent setExact match.
regionCurrent setExact match.
tenorCurrent setExact match.
index_nameHistoryExact match on the composite index name.
sinceHistoryISO-8601 UTC. Rejected on /basis against persisted data until historical basis rows are exposed.
spread_index_nameBasisExact match on the base/headline pair name.
include_provisionalSettlement routesBoolean. 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.

json200 OK · shape only — values and audit contents elided
{
  "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.

MethodPathTier
GET/v1/capacity/intelligence

Source-linked intelligence items

Insights
GET/v1/capacity/intelligence/{id}

Single intelligence item

Insights
ParameterNotes
impactOne of high, medium, low. Anything else is 400 invalid_filter.
tagsComma-separated. Matches an item carrying any listed tag.
sinceISO-8601 UTC, filtered on discovered_at.
limit, cursorStandard 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.

MethodPathTier
GET/v1/inference/token-prices

Input/output token prices per provider model, USD per 1M tokens

Pro
GET/v1/inference/token-prices/history

Single labeled snapshot; history_available is false

Pro
POST/v1/inference/unit-economics

Levelized inference cost. Idempotency-Key required.

Pro
POST/v1/lcoe

Levelized cost of energy. Idempotency-Key required.

Insights
ParameterRoutesNotes
providerToken pricesExact match, case-insensitive.
model_classToken pricesExact match, case-insensitive.
sinceToken-price historyISO-8601 UTC, filtered on observed_at.
History is not yet a series. /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.
curlPOST /v1/inference/unit-economics
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.

FieldRouteDefault when omitted
tokens_per_second_per_gpuUnit economics120 — drives the token-capacity denominator
pueUnit economics1.2
project_lifetime_yearsUnit economics5 (required on LCOE)
discount_rateUnit economics0.12 (required on LCOE)
annual_opex_usdBoth0
annual_fuel_cost_usd, opex_escalation_rate, fuel_escalation_rate, degradation_rateLCOE0

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.

MethodPathTier
POST/v1/ai-infra/review

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 fieldRequiredContents
scanYesFile 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.
economicsNoUnit-economics assumptions, evaluated by the same calculator as the dedicated route.
powerNoSite facts for the heuristic time-to-power screen. Not an interconnection study.
compute_price_basisNoA settlement you are pricing against, carried through with its observation time, methodology version, and source mode.
Chunk large scans. The schema caps a scan at 2,000 findings, but the 64 KiB request body bound is reached first — a realistic finding serializes to roughly 70–110 bytes, so a single request carries on the order of 600 to 900 of them before returning 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.

MethodPathTier
GET/v1/capacity/signals

Source-linked seed signals, legacy scores unverified

Insights
GET/v1/capacity/signals/{id}

Single seed signal

Insights
GET/v1/facilities

Facility CSV fixture

Insights
GET/v1/facilities/{id}

Single facility fixture row

Insights
GET/v1/fabs

Semiconductor fab fixture

Pro
GET/v1/fabs/{id}

Single fab fixture row

Pro
GET/v1/fabs/chokepoints

Supply-chain chokepoint fixture

Pro
FixtureWhy it is withheld
/v1/capacity/signalsRows 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/facilitiesThe 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/fabsNo 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”.

NamespaceTargetBlocking work
/v1/index/power*v1.1Power Forecast needs prediction-market integration before it can return probability bands. An empty namespace is preferable to an uncalibrated one.
/v1/carbon/*v1.2Carbon Trail targets corporate sustainability filings and needs an assurance-grade audit chain before it ships.
/v1/webhooks*v1.1Push 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 /v1 is the compatibility promise: additive changes only, and a breaking change becomes /v2.
  • Document version. /openapi.yaml carries its own info.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/v1 are 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.