Overview
DriftMind is a cold-start, self-adaptive forecasting engine designed for fast data environments. You create a forecaster, feed time-aligned observations, then request forecasts and anomaly scores.
What Swagger is for
Contract reference: endpoints, schemas, status codes, examples.
What this guide is for
Workflow, best practices, and runnable examples (Java + Python + curl).
Authentication
All requests require an API token passed via the Auth header:
Auth: <YOUR_API_TOKEN>
Environment setup
export DRIFTMIND_TOKEN="your-token-here"
$Env:DRIFTMIND_TOKEN="your-token-here"
Quickstart
The golden path is: Create → Feed → Predict → Delete.
FORECAST_NOT_READY if
insufficient data has been fed.
In that case, feed additional observations and retry.
Create a Forecaster
Creates a multivariate forecaster and returns a forecasterId.
POST /driftmind —
See
in Swagger
Parameter Reference
The following parameters define how DriftMind creates and operates a forecaster. Required parameters must be provided; optional parameters have defaults.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
forecasterName |
string | Yes | — | Human-readable name for the forecaster. |
features |
list<string> | Yes | — | List of feature names (columns in your dataset). Must be non-empty and unique. |
inputSize |
int | Yes | — | Number of past points used as input (sliding window size). Minimum: 1. |
outputSize |
int | Yes | — | Number of future points to forecast (horizon). Minimum: 1. Must be ≤
inputSize.
|
maxClustersAllowed |
int | No | 100 | Maximum number of clusters maintained. Impacts memory footprint and model complexity. |
similarityThreshold |
float | No | 0.8 | Similarity threshold (0.6–1.0) used when assigning patterns to clusters. Higher = stricter matching. |
timeStampIntervalInSeconds |
int | No | 60 | Expected interval between points expressed in seconds (used for consistency checks and time alignment). |
fitRate |
int | No | 1 | Frequency of model updates. Lower = faster adaptation. 1 updates on
every ingestion. |
useCustomDateFormat |
bool | No | false | Whether to parse timestamps using a custom format specified by
dateFormat.
|
dateFormat |
string | No | dd-MM-yyyy HH:mm:ss |
Date format used when useCustomDateFormat is true. |
useInitializationDate |
bool | No | false | Whether to align forecaster time relative to a provided
initializationDate (useful when timestamps are absent).
|
initializationDate |
string | No | System time at forecaster creation | Explicit initialization date/time used when useInitializationDate is
true. Must match dateFormat. |
similarityThreshold=0.8, fitRate=1, and
adjust only if you observe over/under-clustering or slow adaptation.
curl
curl -X POST https://api.thingbook.io/access/api/driftmind \
-H "Auth: $DRIFTMIND_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"forecasterName": "Temperature Forecaster",
"features": ["temperature", "humidity"],
"inputSize": 30,
"outputSize": 1
}'
Python
import os
import requests
BASE_URL = "https://api.thingbook.io/access/api"
headers = {"Auth": os.environ["DRIFTMIND_TOKEN"], "Content-Type": "application/json"}
payload = {
"forecasterName": "Temperature Forecaster",
"features": ["temperature", "humidity"],
"inputSize": 30,
"outputSize": 1
}
r = requests.post(f"{BASE_URL}/driftmind", json=payload, headers=headers)
r.raise_for_status()
forecaster_id = r.json()["forecasterId"]
print("forecasterId:", forecaster_id)
Java (JAX-RS Client)
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
public class CreateForecasterExample {
public static void main(String[] args) {
String baseUrl = "https://api.thingbook.io/access/api";
String token = System.getenv("DRIFTMIND_TOKEN");
String payload = """
{
"forecasterName": "Temperature Forecaster",
"features": ["temperature", "humidity"],
"inputSize": 30,
"outputSize": 1
}
""";
Client client = ClientBuilder.newClient();
Response resp = client.target(baseUrl + "/driftmind")
.request(MediaType.APPLICATION_JSON)
.header("Auth", token)
.post(Entity.json(payload));
String body = resp.readEntity(String.class);
System.out.println(resp.getStatus() + " " + body);
}
}
Feed Observations
Feed time-aligned arrays for each feature. All feature arrays must have the same length.
PATCH /driftmind —
See
in Swagger
curl
curl -X PATCH https://api.thingbook.io/access/api/driftmind \
-H "Auth: $DRIFTMIND_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"forecasterId": "abc123-xyz789",
"data": {
"temperature": [18.0, 19.5, 20.1, 20.7],
"humidity": [0.62, 0.60, 0.58, 0.59]
}
}'
Python
import os
import requests
BASE_URL = "https://api.thingbook.io/access/api"
headers = {"Auth": os.environ["DRIFTMIND_TOKEN"], "Content-Type": "application/json"}
payload = {
"forecasterId": "abc123-xyz789",
"data": {
"temperature": [18.0, 19.5, 20.1, 20.7],
"humidity": [0.62, 0.60, 0.58, 0.59]
}
}
r = requests.patch(f"{BASE_URL}/driftmind", json=payload, headers=headers)
r.raise_for_status()
print(r.json())
Request Predictions
Request a forecast for a forecaster. If insufficient data exists, the API returns
422 FORECAST_NOT_READY.
GET /driftmind/forecaster/{forecasterId}/predict —
See
in Swagger
curl -X GET https://api.thingbook.io/access/api/driftmind/forecaster/abc123-xyz789/predict \
-H "Auth: $DRIFTMIND_TOKEN"
Not enough data (422)
{
"error": "FORECAST_NOT_READY"
}
Understand the Response
The prediction response includes an overall anomaly score and a per-feature results map.
{
"anomalyScore": 0.27,
"numberOfClusters": 12,
"features": {
"temperature": {
"timestamps": ["2025-12-31 10:00:00"],
"predictions": [20.7],
"upperConfidence": [21.3],
"lowerConfidence": [20.1],
"anomalyScore": 0.12,
"forecastingMethod": "CLUSTER",
"numberOfClusters": 4
},
"humidity": {
"timestamps": ["2025-12-31 10:00:00"],
"predictions": [0.59],
"upperConfidence": [0.61],
"lowerConfidence": [0.57],
"anomalyScore": 0.42,
"forecastingMethod": "CLUSTER",
"numberOfClusters": 8
}
}
}
| Field | Description |
|---|---|
anomalyScore |
Average anomaly score across all features (rounded to 2 decimals). |
numberOfClusters |
Total clusters across all features (sum of per-feature values). |
features |
Map keyed by feature name containing per-feature forecast outputs and metadata. |
predictions |
Forecasted values for the horizon. |
upperConfidence / lowerConfidence |
Confidence bounds per forecast point. |
forecastingMethod |
Method used (e.g., CLUSTER, FALLBACK). |
Error Handling
All errors are returned as:
{
"error": "ERROR_CODE",
"details": ["optional", "context"]
}
| Status | Code | Meaning | Action |
|---|---|---|---|
| 401 | TOKEN_REJECTED |
Token missing or invalid | Check the Auth header |
| 402 | CREDIT_EXHAUSTED |
Insufficient credit | Top up / change plan / reduce calls |
| 404 | FORECASTER_NOT_FOUND |
Forecaster does not exist | Verify forecasterId |
| 422 | FORECAST_NOT_READY |
Not enough data to forecast | Feed more observations and retry |
| 500 | REDIS_UNAVAILABLE |
Temporary backend issue | Retry with backoff |
Delete a Forecaster
Deletes a forecaster and its associated data. This cannot be undone.
DELETE /driftmind/forecaster/{forecasterId} —
See
in Swagger
curl -X DELETE https://api.thingbook.io/access/api/driftmind/forecaster/abc123-xyz789 \
-H "Auth: $DRIFTMIND_TOKEN"
Success response
{
"message": "FORECASTER_DELETED"
}