Hello, predictAI
The smallest possible program — push values, read them back, and see your data start to connect.
The shortest path to understanding the platform: create a workspace, push a month of numbers, and look at what the platform already knows about them. No models, no training — just data in, structure out.
You'll need: an API token. Everything else is created below.
1. A client and a workspace
A workspace is the container everything lives in. Create one and scope the client to it:
from predictai import PredictAI
client = PredictAI(token="pa_live_...")
workspace = client.workspaces.post_workspace(json={"name": "Hello predictAI"})
client.workspace_id = workspace["data"]["uid"]
print("workspace:", client.workspace_id)import { PredictAI } from "@predictai/sdk";
const client = new PredictAI({ token: "pa_live_..." });
const workspace = await client.workspaces.postWorkspace({
json: { name: "Hello predictAI" },
});
(client as { workspaceId?: string }).workspaceId = workspace.data.uid;
console.log("workspace:", workspace.data.uid);2. Push data
Signals are named series of values. There's no schema to declare — pushing to a new key creates the signal. Push thirty days of two related metrics:
import math, random
from datetime import date, timedelta
random.seed(7)
start = date.today() - timedelta(days=30)
for i in range(30):
ts = f"{(start + timedelta(days=i)).isoformat()}T00:00:00Z"
visitors = int(900 + 250 * math.sin(i / 4) + random.uniform(-40, 40))
signups = round(visitors * 0.032 + random.uniform(-2, 2), 1)
client.signals.post_signal_push(json={"key": "site_visitors", "value": visitors, "timestamp": ts})
client.signals.post_signal_push(json={"key": "signups", "value": signups, "timestamp": ts})
print("pushed 60 values")const start = Date.now() - 30 * 86_400_000;
for (let i = 0; i < 30; i++) {
const timestamp = new Date(start + i * 86_400_000).toISOString();
const visitors = Math.round(900 + 250 * Math.sin(i / 4) + (Math.random() - 0.5) * 80);
const signups = +(visitors * 0.032 + (Math.random() - 0.5) * 4).toFixed(1);
await client.signals.postSignalPush({ json: { key: "site_visitors", value: visitors, timestamp } });
await client.signals.postSignalPush({ json: { key: "signups", value: signups, timestamp } });
}
console.log("pushed 60 values");Duplicate pushes for the same key and timestamp are safe — the newest value wins — so you can re-run this block freely.
3. Read it back
The signal list returns one annotated row per key, with pre-binned chart data:
signals = client.signals.get_signal(params={"per_page": 10})
for row in signals["data"]["signals"]:
print(f'{row["key"]:15} {row["signal_count"]:4} values '
f'({row["min_timestamp"][:10]} → {row["max_timestamp"][:10]})')const signals = await client.signals.getSignal({ params: { per_page: 10 } });
for (const row of signals.data.signals) {
console.log(
`${row.key}: ${row.signal_count} values ` +
`(${row.min_timestamp.slice(0, 10)} → ${row.max_timestamp.slice(0, 10)})`,
);
}site_visitors 30 values (2026-06-17 → 2026-07-16)
signups 30 values (2026-06-17 → 2026-07-16)4. Ask how they relate
You built signups as a function of visitors — the platform should notice. Correlation is a free, cached read:
analysis = client.signals.get_signal_correlation()
matrix = analysis["data"]["correlations"]["correlation"]
print("visitors ↔ signups:", round(matrix["site_visitors"]["signups"], 2))const analysis = await client.signals.getSignalCorrelation();
const matrix = analysis.data.correlations.correlation;
console.log("visitors ↔ signups:", matrix.site_visitors.signups.toFixed(2));visitors ↔ signups: 0.97That's the whole platform in miniature: values go in as signals, and structure — correlation, relevance, causality, and eventually forecasts — comes out.
Where to go next
- A forecast with zero training — put a pretrained model on this data right now.
- CSV to live forecast — the full production loop, trained on your own history.
- Signals — everything pushing, listing, events, and analysis can do.

