Skip to main content

REST API

Base URL examples use $API. All JSON envelopes include disclaimer.

Machine-readable contract: GET $API/openapi.json (OpenAPI 3.1). Agent index: site / repo llms.txt.

Endpoints at a glance​

MethodPathAuthRole
GET/openapi.json—OpenAPI 3.1
GET/healthz—Probe
GET/v1/feeds—Catalog
GET/v1/feeds/:slug—Feed + versions + related
GET/v1/feeds/:slug/track-record—Scored history
GET/v1/quote?slug=—Impersonal quote
GET/v1/leaderboard—Rank by skill
GET/v1/log/head—Commit-log head + integrity
POST/v1/feedssellerRegister feed (visibility: sandbox stays off the public board)
POST/v1/predictionssellerSeal forecast
GET/v1/predictions/:idAPI keyForecast + hash check
GET/v1/predictions/:id/feedbackAPI keyLearning feedback
GET/v1/feeds/:idOrSlug/feedbackAPI keyDrain feedback
POST/v1/feeds/:id/versionssellerVersion bump
GET/v1/admin/*admin JWT / keySite admin

Deprecated alias: GET /v1/signal-feed → prefer /v1/track-record (and per-feed /track-record).


Read and quote​

curl​

curl -sS "$API/v1/feeds"
curl -sS "$API/v1/quote?slug=btc-realized-vol-jev"
curl -sS "$API/v1/feeds/btc-realized-vol-jev/track-record?limit=50"
curl -sS "$API/v1/leaderboard"
curl -sS "$API/v1/log/head"

# After reveal (buyer or seller key):
curl -sS "$API/v1/predictions/<id>" \
-H "authorization: Bearer $NEWSIGNAL_BUYER_KEY"

Python​

import os, json, urllib.request

API = os.environ.get("NEWSIGNAL_API_URL", "http://localhost:8787")
BUYER = os.environ["NEWSIGNAL_BUYER_KEY"]

def get(path: str, auth: str | None = None):
req = urllib.request.Request(f"{API}{path}")
if auth:
req.add_header("authorization", f"Bearer {auth}")
with urllib.request.urlopen(req) as r:
return json.load(r)

catalog = get("/v1/feeds")
quote = get("/v1/quote?slug=btc-realized-vol-jev")
board = get("/v1/leaderboard")
# pred = get(f"/v1/predictions/{prediction_id}", auth=BUYER)
print(len(catalog["feeds"]), quote.get("disclaimer", "")[:40])

TypeScript​

const API = process.env.NEWSIGNAL_API_URL ?? 'http://localhost:8787';
const BUYER = process.env.NEWSIGNAL_BUYER_KEY;

async function get<T>(path: string, auth?: string): Promise<T> {
const res = await fetch(`${API}${path}`, {
headers: auth ? { authorization: `Bearer ${auth}` } : undefined,
});
if (!res.ok) throw new Error(`${res.status} ${path}`);
return res.json() as Promise<T>;
}

const catalog = await get<{ feeds: unknown[]; disclaimer: string }>('/v1/feeds');
const quote = await get(`/v1/quote?slug=btc-realized-vol-jev`);
const board = await get('/v1/leaderboard');
// const pred = await get(`/v1/predictions/${id}`, BUYER);

Publish forecasts​

The seller API role is the data-producer role used for publishing.

curl​

curl -sS -X POST "$API/v1/feeds" \
-H "authorization: Bearer $NEWSIGNAL_SELLER_KEY" \
-H "content-type: application/json" \
-d '{
"slug": "my-btc-vol",
"name": "My BTC realized vol",
"indicator": {
"kind": "realized_vol",
"asset": "BTC",
"horizonHours": 24,
"resolutionSource": "binance.spot.klines",
"baseline": "historical_average",
"enabled": true
},
"notes": "external seller v1"
}'

curl -sS -X POST "$API/v1/predictions" \
-H "authorization: Bearer $NEWSIGNAL_SELLER_KEY" \
-H "content-type: application/json" \
-d '{
"feedId": "<feedId>",
"payload": { "type": "probability", "value": 0.61 }
}'

Python​

import os, json, urllib.request

API = os.environ.get("NEWSIGNAL_API_URL", "http://localhost:8787")
SELLER = os.environ["NEWSIGNAL_SELLER_KEY"]

def post(path: str, body: dict):
data = json.dumps(body).encode()
req = urllib.request.Request(
f"{API}{path}",
data=data,
method="POST",
headers={
"authorization": f"Bearer {SELLER}",
"content-type": "application/json",
},
)
with urllib.request.urlopen(req) as r:
return json.load(r)

feed = post("/v1/feeds", {
"slug": "my-btc-vol",
"name": "My BTC realized vol",
"indicator": {
"kind": "realized_vol",
"asset": "BTC",
"horizonHours": 24,
"resolutionSource": "binance.spot.klines",
"baseline": "historical_average",
"enabled": True,
},
})
pred = post("/v1/predictions", {
"feedId": feed["feedId"],
"payload": {"type": "probability", "value": 0.61},
})
print(pred["predictionId"], pred["payloadHash"], pred["revealAt"])

TypeScript (@newsignal/seller-sdk)​

import { NewsignalSellerClient } from '@newsignal/seller-sdk';

const client = new NewsignalSellerClient({
baseUrl: process.env.NEWSIGNAL_API_URL!,
apiKey: process.env.NEWSIGNAL_SELLER_KEY!,
});

const { feedId } = await client.registerFeed({
slug: 'my-btc-vol',
name: 'My BTC realized vol',
indicator: {
kind: 'realized_vol',
asset: 'BTC',
horizonHours: 24,
resolutionSource: 'binance.spot.klines',
baseline: 'historical_average',
enabled: true,
},
});

await client.publishPrediction({
feedId,
payload: { type: 'probability', value: 0.61 },
});

After settle, drain feedback and bump versions — see Learning loop.