GPU Rental Indexes: History
Published GPU price indices, daily and intraday, one index per request.
Returns the records that changed inside the range, so asking for yesterday gives you yesterday’s changes rather than everything still in force.
start is included and end is not, so consecutive ranges join up without returning anything twice. A plain date for end means the end of that day, so start=2026-06-01&end=2026-06-01 is that whole day.
Omitting start gives you the most recent 30 days.
curl --request GET \
--url https://data-api.compute-index.com/v2/gpu/rental/indexes/history \
--header 'Authorization: Bearer <token>'import requests
url = "https://data-api.compute-index.com/v2/gpu/rental/indexes/history"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://data-api.compute-index.com/v2/gpu/rental/indexes/history', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://data-api.compute-index.com/v2/gpu/rental/indexes/history",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://data-api.compute-index.com/v2/gpu/rental/indexes/history"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://data-api.compute-index.com/v2/gpu/rental/indexes/history")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://data-api.compute-index.com/v2/gpu/rental/indexes/history")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "example-index",
"type": "daily",
"timestamp": "2026-09-02",
"value": 2.18,
"p5": 1.9,
"p95": 2.55
}
],
"meta": {
"page_size": 100,
"returned": 100,
"has_more": true,
"next": {
"path": "/v2/gpu/rental/prices/history",
"query_params": {
"page_size": "100",
"page_token": "eyJkIjoicHJpY2VzIiwiZSI6Imhpc3RvcnkiLC4uLg.qgLm5w"
},
"url": "https://data-api.compute-index.com/v2/gpu/rental/prices/history?page_token=eyJkIjoicHJpY2VzIiwiZSI6Imhpc3RvcnksLi4u.qgLm5w&page_size=100"
},
"sort": {
"by": "valid_from",
"order": "desc"
},
"window": {
"start": "2026-06-01T00:00:00+00:00",
"end": "2026-07-01T00:00:00+00:00",
"clamped": true,
"history_starts_at": "<string>"
},
"source": "compute-index"
}
}{
"status": 401,
"title": "Unauthorized",
"detail": "Missing or invalid bearer token.",
"code": "unauthenticated",
"request_id": "01JQ2X8N4T6V9WZ0ABCD"
}{
"status": 403,
"title": "Forbidden",
"detail": "The token does not carry the scopes this endpoint requires.",
"code": "insufficient_entitlement",
"request_id": "01JQ2X8N4T6V9WZ0ABCD"
}{
"status": 404,
"title": "Not Found",
"detail": "No such resource, or none you are entitled to see.",
"code": "not_found",
"request_id": "01JQ2X8N4T6V9WZ0ABCD"
}{
"status": 422,
"title": "Unprocessable Content",
"detail": "A parameter failed validation.",
"code": "validation_failed",
"request_id": "01JQ2X8N4T6V9WZ0ABCD"
}{
"status": 429,
"title": "Too Many Requests",
"detail": "Rate limit exceeded; see the X-RateLimit-* headers.",
"code": "rate_limited",
"request_id": "01JQ2X8N4T6V9WZ0ABCD"
}id is required; /metadata
lists the ids your token holds, and an id you do not hold returns 404./metadata as
history_starts_at.meta.next until it is null, and send nothing alongside it — the
link already carries your filters, dates and ordering. See
Paging.timestamp or value with sort_by, and reverse with
sort_order=desc. Because a request names one index, every row in a response has the same shape:
all daily, or all intraday.
Example
# A daily index: one row per published day, `timestamp` is a date
curl -H "Authorization: Bearer $TOKEN" \
"https://data-api.compute-index.com/v2/gpu/rental/indexes/history?id=rental-h100-1y-us-daily&start=2026-06-01&end=2026-07-01"
# An intraday index: one row per 30-minute interval, `timestamp` is a UTC instant
curl -H "Authorization: Bearer $TOKEN" \
"https://data-api.compute-index.com/v2/gpu/rental/indexes/history?id=rental-h100-1y-us-intraday&start=2026-06-30T00:00:00Z&end=2026-07-01T00:00:00Z"
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Query Parameters
Window start, inclusive (ISO 8601 datetime, or a bare date = start of that day UTC). Default: end minus 30 days.
Window end, exclusive (ISO 8601 datetime, or a bare date = that whole day, i.e. the bound becomes the following midnight UTC). Default: now. Consecutive windows tile with no overlap: start=2026-06-01&end=2026-06-07 then start=2026-06-08&end=2026-06-14.
The index to read. The ids available to you are listed by /metadata; an id you do not hold is a 404, identical to one that does not exist.
"example-index"
Who computes the series you read: gx or compute-index. Omit it for the index's default. /metadata lists the values each index accepts; any other is a 400. A GX-administered index's history may begin later than ours, so an early window can be empty from gx and not from compute-index.
"compute-index"
Extra fields to include on each row, comma-separated. /metadata lists the ones each index offers you; any other is a 400. Each is added to the row as a field of its own, null on points from gx.
"unsmoothed_value"
Sort field. One of: timestamp, value. Default: timestamp.
Sort direction: asc or desc. Default: asc.
Rows per page (max 1000).
1 <= x <= 1000Opaque token token from a previous response's meta.next. It carries the whole request — filters, ordering, window and position — so supply it alone; the only parameter that may accompany it is page_size. Do not construct or parse these; the format is not part of the contract.
Response
Successful Response
The rows in this page, ordered as meta.sort reports.
One published day of a daily index.
Any extra fields you request with extra_fields are further top-level fields of the row, named as
/metadata lists them, and present only when requested. Each is a number, or null on a point from gx.
- DailyIndexRow
- IntradayIndexRow
Show child attributes
Show child attributes
/history, which additionally reports the window it queried.
source names who computed the rows in this page.
Show child attributes
Show child attributes
curl --request GET \
--url https://data-api.compute-index.com/v2/gpu/rental/indexes/history \
--header 'Authorization: Bearer <token>'import requests
url = "https://data-api.compute-index.com/v2/gpu/rental/indexes/history"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://data-api.compute-index.com/v2/gpu/rental/indexes/history', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://data-api.compute-index.com/v2/gpu/rental/indexes/history",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://data-api.compute-index.com/v2/gpu/rental/indexes/history"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://data-api.compute-index.com/v2/gpu/rental/indexes/history")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://data-api.compute-index.com/v2/gpu/rental/indexes/history")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "example-index",
"type": "daily",
"timestamp": "2026-09-02",
"value": 2.18,
"p5": 1.9,
"p95": 2.55
}
],
"meta": {
"page_size": 100,
"returned": 100,
"has_more": true,
"next": {
"path": "/v2/gpu/rental/prices/history",
"query_params": {
"page_size": "100",
"page_token": "eyJkIjoicHJpY2VzIiwiZSI6Imhpc3RvcnkiLC4uLg.qgLm5w"
},
"url": "https://data-api.compute-index.com/v2/gpu/rental/prices/history?page_token=eyJkIjoicHJpY2VzIiwiZSI6Imhpc3RvcnksLi4u.qgLm5w&page_size=100"
},
"sort": {
"by": "valid_from",
"order": "desc"
},
"window": {
"start": "2026-06-01T00:00:00+00:00",
"end": "2026-07-01T00:00:00+00:00",
"clamped": true,
"history_starts_at": "<string>"
},
"source": "compute-index"
}
}{
"status": 401,
"title": "Unauthorized",
"detail": "Missing or invalid bearer token.",
"code": "unauthenticated",
"request_id": "01JQ2X8N4T6V9WZ0ABCD"
}{
"status": 403,
"title": "Forbidden",
"detail": "The token does not carry the scopes this endpoint requires.",
"code": "insufficient_entitlement",
"request_id": "01JQ2X8N4T6V9WZ0ABCD"
}{
"status": 404,
"title": "Not Found",
"detail": "No such resource, or none you are entitled to see.",
"code": "not_found",
"request_id": "01JQ2X8N4T6V9WZ0ABCD"
}{
"status": 422,
"title": "Unprocessable Content",
"detail": "A parameter failed validation.",
"code": "validation_failed",
"request_id": "01JQ2X8N4T6V9WZ0ABCD"
}{
"status": 429,
"title": "Too Many Requests",
"detail": "Rate limit exceeded; see the X-RateLimit-* headers.",
"code": "rate_limited",
"request_id": "01JQ2X8N4T6V9WZ0ABCD"
}