Skip to main content

Chronicle Quickstart

Chronicle is InertialAI's self-serve finetuning product: upload your real-world data, train from $5, get an automatic before/after eval against the frozen base (with a refund if the finetune doesn't win), and deploy to a private scale-to-zero endpoint.

Install the SDK and grab an API key from your dashboard:

pip install inertialai-api-client

The whole journey

from inertialai_api_client import InertialAI

client = InertialAI(api_key="iai_...")

job = client.fine_tunes.create(
model="chronicle", # or "embed"
training_file="fault_data.jsonl", # local path or file object
task="classification", # optional assertion — see below
)

model = client.deployments.create(
fine_tune_id=job.id,
name="pump-fault-detector", # your model id, unique per account
)

prediction = client.models.predict(
model=model.name,
time_series=[[...]], # your sensor values
text="pump A12, high vibration, bearing replaced last week",
)
print(prediction.output.label)

That's it. fine_tunes.create uploads your file to isolated storage, validates every record, charges the quoted training fee (priced on your data, from $5 — see pricing), trains, and blocks until the before/after eval finishes. Already uploaded the data once? client.fine_tunes.datasets() lists every retained file, and passing its path as training_file_path= (instead of training_file=) trains on it directly — no re-upload. If your tuned model doesn't beat the frozen base on held-out data, the job is flagged and the fee auto-refunds. deployments.create launches a live, scale-to-zero endpoint under your chosen name; models.predict queries it. In our reference run the full journey — upload to first prediction — took 9 seconds.

What task does

The training objective is selected by your record shape (see the training reference); task is an assertion. If you declare task="classification" but your records contain forecasting targets, validation fails loudly with exactly what's mismatched — your model never trains on data you misunderstood. Values: quantile, text, both, classification, regression, contrastive.

Everything else you'll want

# Loss curves + eval as an exportable JSON document
report = client.fine_tunes.eval_report(job.id)

# Custom knobs and your own validation set
job = client.fine_tunes.create(
model="chronicle",
training_file="train.jsonl",
validation_file="val.jsonl", # replaces the random split
hyperparameters={"epochs": 40, "learning_rate": 0.0005, "loss": "huber"},
method="full", # "lora" (default — 75% off) or "full" (listed rate)
)

# Versioning: ship v2, roll back in one call
client.deployments.promote("pump-fault-detector", fine_tune_id=new_job.id)
client.deployments.rollback("pump-fault-detector")

# Usage log: calls, latency, metered cost
usage = client.deployments.usage("pump-fault-detector")

# A key that can ONLY call this model (safe for device fleets)
scoped = client.deployments.create_key("pump-fault-detector")

# Changed your mind? Cancel while queued/training — the fee auto-refunds
client.fine_tunes.cancel(job.id)

# Data retention: purge a job's uploads, weights, and endpoints
client.fine_tunes.delete(job.id)

Embedding models work the same way with client.models.embed(...), which returns a 768-dim vector.

REST, if you prefer

Every SDK call maps 1:1 onto predictable REST resources under /api/v1/finetune/* and /api/v1/endpoints/* — standard verbs, JSON bodies, standard status codes, Authorization: Bearer auth. The full surface is in the interactive API specification at /api/v1/docs on any deployment.