curl "https://api.ornnai.com/api/otpi/hourly"
import requests
rows = requests.get("https://api.ornnai.com/api/otpi/hourly").json()["data"]
for r in rows:
print(r["lab"], r["indexPerMtok"])
const res = await fetch("https://api.ornnai.com/api/otpi/hourly");
const { data } = await res.json();
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ornnai.com/api/otpi/hourly",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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://api.ornnai.com/api/otpi/hourly"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.ornnai.com/api/otpi/hourly")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ornnai.com/api/otpi/hourly")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyGet the hourly token price sample by lab
Hourly sample of the Ornn Token Price Index. Returns the latest capture by default, one UTC date, or a startDate/endDate range. Each row is capturedAt, lab, and indexPerMtok.
The value is the token-weighted blend of that hour’s sample. It is not the settled daily print from GET /api/otpi. Access matches that route: without a key, the free tier covers anthropic, openai, google, and deepseek for the trailing 3 months. A key unlocks all 11 labs and the full history. The response includes access: "public-3mo" | "premium" | "full".
curl "https://api.ornnai.com/api/otpi/hourly"
import requests
rows = requests.get("https://api.ornnai.com/api/otpi/hourly").json()["data"]
for r in rows:
print(r["lab"], r["indexPerMtok"])
const res = await fetch("https://api.ornnai.com/api/otpi/hourly");
const { data } = await res.json();
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ornnai.com/api/otpi/hourly",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$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://api.ornnai.com/api/otpi/hourly"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.ornnai.com/api/otpi/hourly")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ornnai.com/api/otpi/hourly")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyOverview
The hourly sample of the Ornn Token Price Index. Each row is the capture time, the lab, andindexPerMtok.
This is the token-weighted blend of that hour’s sample. The settled daily print remains GET /api/otpi. Access is the same: without a key, anthropic, openai, google, and deepseek for the trailing 3 months. A Premium or Full key unlocks all 11 labs and the full history.Query Parameters
UTC day in YYYY-MM-DD. Returns every sample captured that day. Omit it, and omit the range, for the latest sample.
Inclusive start of a UTC-day window. Use with endDate.
Inclusive end of a UTC-day window. Use with startDate.
Filter to a single lab. Without a key, only anthropic, openai, google, and deepseek are available.
anthropic, openai, google, deepseek, minimax, xiaomi, qwen, moonshotai, z-ai, mistralai, meta-llama Response
Hourly sample rows. The latest capture carries a top-level capturedAt. A date query carries that date. A range carries startDate and endDate.

