Developer Guide – DriftMind API

This guide explains how to use the DriftMind API end-to-end with concrete examples in curl, Python, and Java.

Base URL: https://api.thingbook.io/access/api/driftmind/v1 Auth header: Auth: <token> Core flow: Create → Feed → Predict → Delete

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).

For interactive testing of endpoints, use the Swagger UI: Open Swagger UI.
For a gentle introduction to DriftMind, visit: Reflexive Memory Is All You Need.
Looking for a pre-built wrapper? Check out the DriftMind Python Client.
For a deep dive into the architecture and design principles behind DriftMind, DriftMind Whitepaper.

Authentication

All requests require an API token passed via the Auth header:

HTTP Header
Auth: <YOUR_API_TOKEN>

Environment setup

Linux / macOS
export DRIFTMIND_TOKEN="your-token-here"
Windows (PowerShell)
$Env:DRIFTMIND_TOKEN="your-token-here"

Quickstart

The golden path is: Create → Feed → Predict → Delete. The snippet below runs the full cycle end-to-end.

DriftMind may return 422 FORECAST_NOT_READY if insufficient data has been fed. In that case, feed additional observations and retry.
Python — full cycle
import os, requests, time

BASE_URL = "https://api.thingbook.io/access/api/driftmind/v1"
headers  = {"Auth": os.environ["DRIFTMIND_TOKEN"], "Content-Type": "application/json"}

# 1. Create
r = requests.post(f"{BASE_URL}/forecasters", headers=headers, json={
    "forecasterName": "My First Forecaster",
    "features": ["temperature", "humidity"],
    "inputSize": 30,
    "outputSize": 1
})
r.raise_for_status()
fid = r.json()["forecasterId"]
print("Created:", fid)

# 2. Feed — send enough observations to satisfy inputSize
observations = {
    "temperature": [18.0 + i * 0.1 for i in range(35)],
    "humidity":    [0.60 + i * 0.002 for i in range(35)]
}
r = requests.post(f"{BASE_URL}/forecasters/{fid}/observations", headers=headers, json=observations)
r.raise_for_status()
print("Fed observations")

# 3. Predict
r = requests.get(f"{BASE_URL}/forecasters/{fid}/predictions", headers=headers)
r.raise_for_status()
result = r.json()
print(f"Anomaly score: {result['anomalyScore']}")
print(f"Temperature forecast: {result['features']['temperature']['predictions']}")

# 4. Delete
r = requests.delete(f"{BASE_URL}/forecasters/{fid}", headers=headers)
r.raise_for_status()
print("Deleted")
curl — full cycle
# 1. Create — save the returned forecasterId
FID=$(curl -s -X POST https://api.thingbook.io/access/api/driftmind/v1/forecasters \
  -H "Auth: $DRIFTMIND_TOKEN" -H "Content-Type: application/json" \
  -d '{"forecasterName":"My First Forecaster","features":["temperature","humidity"],"inputSize":30,"outputSize":1}' \
  | grep -o '"forecasterId":"[^"]*"' | cut -d'"' -f4)
echo "Created: $FID"

# 2. Feed
curl -s -X POST https://api.thingbook.io/access/api/driftmind/v1/forecasters/$FID/observations \
  -H "Auth: $DRIFTMIND_TOKEN" -H "Content-Type: application/json" \
  -d '{"temperature":[18.0,18.1,18.2,18.3,18.4,18.5,18.6,18.7,18.8,18.9,19.0,19.1,19.2,19.3,19.4,19.5,19.6,19.7,19.8,19.9,20.0,20.1,20.2,20.3,20.4,20.5,20.6,20.7,20.8,20.9,21.0,21.1,21.2,21.3,21.4],"humidity":[0.60,0.60,0.61,0.61,0.62,0.62,0.60,0.59,0.58,0.60,0.61,0.62,0.60,0.59,0.61,0.62,0.63,0.60,0.59,0.58,0.60,0.61,0.62,0.63,0.60,0.61,0.62,0.59,0.58,0.60,0.61,0.62,0.63,0.60,0.59]}'

# 3. Predict
curl -s -X GET https://api.thingbook.io/access/api/driftmind/v1/forecasters/$FID/predictions \
  -H "Auth: $DRIFTMIND_TOKEN"

# 4. Delete
curl -s -X DELETE https://api.thingbook.io/access/api/driftmind/v1/forecasters/$FID \
  -H "Auth: $DRIFTMIND_TOKEN"

Create a Forecaster

Creates a multivariate forecaster and returns a forecasterId.

Endpoint: POST /driftmind/v1/forecasters
FieldDescription
forecasterName Human-readable label for this forecaster.
features Array of feature names. Each name must match the keys you send in observation payloads.
inputSize Sliding window size — the number of past observations the model uses to generate each forecast. Larger values capture longer patterns but require more data before the first prediction is ready.
outputSize Number of future time steps to forecast. Use 1 for single-step prediction or a higher value for a multi-step horizon.

curl

curl
curl -X POST https://api.thingbook.io/access/api/driftmind/v1/forecasters \
  -H "Auth: $DRIFTMIND_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "forecasterName": "Temperature Forecaster",
    "features": ["temperature", "humidity"],
    "inputSize": 30,
    "outputSize": 1
  }'

Python (requests)

Python
import os
import requests

# Note the /v1/ at the end
BASE_URL = "https://api.thingbook.io/access/api/driftmind/v1"
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}/forecasters", json=payload, headers=headers)
r.raise_for_status()
forecaster_id = r.json()["forecasterId"]
print("forecasterId:", forecaster_id)

Java (JAX-RS Client)

Java
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/driftmind/v1";
    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 + "/forecasters")
        .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.

Endpoint: POST /driftmind/v1/forecasters/{id}/observations

curl

curl
curl -X POST https://api.thingbook.io/access/api/driftmind/v1/forecasters/abc123-xyz789/observations \
  -H "Auth: $DRIFTMIND_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "temperature": [18.0, 19.5, 20.1, 20.7],
    "humidity":    [0.62, 0.60, 0.58, 0.59]
  }'

Python

Python
import os
import requests

BASE_URL = "https://api.thingbook.io/access/api/driftmind/v1"
headers = {"Auth": os.environ["DRIFTMIND_TOKEN"], "Content-Type": "application/json"}

forecaster_id = "abc123-xyz789"
payload = {
  "temperature": [18.0, 19.5, 20.1, 20.7],
  "humidity":    [0.62, 0.60, 0.58, 0.59]
}

# Note: POST to .../forecasters/{id}/observations
url = f"{BASE_URL}/forecasters/{forecaster_id}/observations"
r = requests.post(url, json=payload, headers=headers)
r.raise_for_status()
print(r.json())

Java (JAX-RS Client)

Java
String forecasterId = "abc123-xyz789";
String payload = """
{
  "temperature": [18.0, 19.5, 20.1, 20.7],
  "humidity":    [0.62, 0.60, 0.58, 0.59]
}
""";

Response resp = client.target(baseUrl + "/forecasters/" + forecasterId + "/observations")
    .request(MediaType.APPLICATION_JSON)
    .header("Auth", token)
    .post(Entity.json(payload));

System.out.println(resp.getStatus() + " " + resp.readEntity(String.class));

Request Predictions

Request a forecast for a forecaster. If insufficient data exists, the API returns 422 FORECAST_NOT_READY.

Endpoint: GET /driftmind/v1/forecasters/{id}/predictions
curl
curl -X GET https://api.thingbook.io/access/api/driftmind/v1/forecasters/abc123-xyz789/predictions \
  -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.

Example response
{
  "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 CLUSTER — normal operation; the model has formed stable clusters and is generating confident forecasts. FALLBACK — the model is still warming up or encountered an unstable state; predictions are based on simpler heuristics and anomaly scores are less reliable. Feed more observations and the method will transition to CLUSTER automatically.

List all Forecasters

Retrieve a list of all forecasters belonging to your API token, including metadata like creation time and usage statistics.

Endpoint: GET /driftmind/v1/forecasters

curl

curl
curl -X GET https://api.thingbook.io/access/api/driftmind/v1/forecasters \
  -H "Auth: $DRIFTMIND_TOKEN"

Python (requests)

Python
# Assumes BASE_URL and headers are defined
r = requests.get(f"{BASE_URL}/forecasters", headers=headers)
r.raise_for_status()
print(r.json())

Java (JAX-RS Client)

Java
Client client = ClientBuilder.newClient();
Response resp = client.target(baseUrl + "/forecasters")
    .request(MediaType.APPLICATION_JSON)
    .header("Auth", token)
    .get();

System.out.println(resp.readEntity(String.class));

Get Forecaster Data

Retrieve the most recent observations currently held in the forecaster's memory buffer. This is useful for validation and debugging to ensure data is being fed correctly.

Endpoint: GET /driftmind/v1/forecasters/{id}/observations

curl

curl
curl -X GET https://api.thingbook.io/access/api/driftmind/v1/forecasters/abc123-xyz789/observations \
  -H "Auth: $DRIFTMIND_TOKEN"

Python (requests)

Python
forecaster_id = "abc123-xyz789"
url = f"{BASE_URL}/forecasters/{forecaster_id}/observations"

r = requests.get(url, headers=headers)
r.raise_for_status()
print(r.json())

Java (JAX-RS Client)

Java
String forecasterId = "abc123-xyz789";
Response resp = client.target(baseUrl + "/forecasters/" + forecasterId + "/observations")
    .request(MediaType.APPLICATION_JSON)
    .header("Auth", token)
    .get();

System.out.println(resp.readEntity(String.class));

Get Forecaster Details

Retrieve the specific configuration of a forecaster, including its input/output sizes, feature names, and internal parameters.

Endpoint: GET /driftmind/v1/forecasters/{id}

curl

curl
curl -X GET https://api.thingbook.io/access/api/driftmind/v1/forecasters/abc123-xyz789 \
  -H "Auth: $DRIFTMIND_TOKEN"

Python (requests)

Python
forecaster_id = "abc123-xyz789"
url = f"{BASE_URL}/forecasters/{forecaster_id}"

r = requests.get(url, headers=headers)
r.raise_for_status()
details = r.json()
print(f"Name: {details['forecasterName']}")
print(f"Config: {details['configuration']}")

Java (JAX-RS Client)

Java
String forecasterId = "abc123-xyz789";
Response resp = client.target(baseUrl + "/forecasters/" + forecasterId)
    .request(MediaType.APPLICATION_JSON)
    .header("Auth", token)
    .get();

System.out.println(resp.readEntity(String.class));

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.

Endpoint: DELETE /driftmind/v1/forecasters/{id}
curl
curl -X DELETE https://api.thingbook.io/access/api/driftmind/v1/forecasters/abc123-xyz789 \
  -H "Auth: $DRIFTMIND_TOKEN"

Success response

{
  "message": "FORECASTER_DELETED"
}

Ready to Integrate?

The live API is documented in Swagger — explore endpoints, test payloads, and start sending data in minutes. No lengthy onboarding, no gatekeeping.

Create a free account and your first API key is ready immediately. The DriftMind overview explains what you can build on top.