Skip to main content

Trakt System SDK

Client libraries for the Trakt System Integrations API: fleet predictions and maintenance forecasts, in a few lines of code.

Trakt System predicts which components on your fleet need attention, when, and what to do about them. This SDK gives you that data directly, with authentication, retries, and rate limits handled for you.

Full API reference, with details on every endpoint: https://www.trakt.tech/api-documentation

Install

Python

pip install kquika-trakt              # core
pip install "kquika-trakt[pandas]"    # with DataFrame support

You install kquika-trakt, then write import trakt in your code.

The Python package also gives you a trakt command to run in your terminal. See Command line.

Node / TypeScript

npm install @kquika-inc/trakt

Requires Node 18 or newer. TypeScript types are included.

Quickstart

Python

from trakt import Trakt

trakt = Trakt(token="YOUR_API_KEY")   # or set TRAKT_TOKEN

# What can this token do?
cfg = trakt.config()
print(cfg.access_level, cfg.max_predictions, cfg.can_export)

# Per-component predictions, most urgent first
for c in trakt.components():
    print(c.name, c.aircraft_tail_number, c.health,
          c.failure_probability, c.recommended_action)

# The next 90 days of maintenance, soonest first
for item in trakt.forecast(days=90):
    if item.is_overdue:
        print("OVERDUE:", item.tail_number, item.component_name)

# Straight to a DataFrame for planning
df = trakt.components_dataframe()

# Fleet-level rollup that matches the dashboards: health, composite average
# confidence, prediction coverage, and 30-day survival
summary = trakt.fleet_summary()
print(summary.fleet_health, summary.avg_confidence, summary.survival_30d)

# Everything that changed since you last looked. Not charged against your
# interactive call allowance, so you can poll it every thirty seconds.
for change in trakt.iter_delta(since="2026-06-01T00:00:00Z"):
    print(change.component_name, change.health_band, change.days_until_due)
print("resume from", trakt.last_cursor)

# Why a prediction says what it says
why = trakt.explanation(1421)
print(why.risk_level, why.method, why.most_likely_failure_mode)
for driver in why.top_contributors[:3]:
    print(" ", driver.feature, driver.contribution, driver.direction)

Node / TypeScript

import { Trakt } from "@kquika-inc/trakt";

const trakt = new Trakt({ token: process.env.TRAKT_TOKEN! });

const cfg = await trakt.config();
console.log(cfg.access_level, cfg.max_predictions);

// Per-component predictions, most urgent first
const components = await trakt.components();
for (const c of components) {
  console.log(c.name, c.aircraft_tail_number, c.health, c.recommended_action);
}

// The next 90 days of maintenance, soonest first
const forecast = await trakt.forecast({ days: 90 });
for (const item of forecast) {
  if (item.is_overdue) console.log("OVERDUE:", item.tail_number, item.component_name);
}

// Fleet-level rollup that matches the dashboards
const summary = await trakt.fleetSummary();
console.log(summary.fleet_health, summary.avg_confidence, summary.survival_30d);

// Everything that changed since you last looked. Not charged against your
// interactive call allowance, so you can poll it every thirty seconds.
for await (const change of trakt.iterDelta({ since: "2026-06-01T00:00:00Z" })) {
  console.log(change.component_name, change.health_band, change.days_until_due);
}
console.log("resume from", trakt.lastCursor);

// Why a prediction says what it says
const why = await trakt.explanation(1421);
console.log(why.prediction?.risk_level, why.explanation?.method);

Command line

The Python package includes a trakt command, so you can check your token or pull predictions straight from the terminal with no code. It works the same way as the Python client, including automatic retries.

export TRAKT_TOKEN=YOUR_API_KEY

trakt config                         # access level and limits for this token
trakt quota                          # remaining allowance on each meter
trakt summary                        # fleet health rollup

trakt components -n 20               # the 20 most urgent components
trakt components --aircraft-id 7 --priority high
trakt forecast --days 90             # next 90 days, soonest first
trakt forecast --days 90 --overdue   # past due items only
trakt explain 1421                   # drivers behind one prediction
trakt scenarios                      # planning scenarios, or `trakt scenarios 5` for one

components and forecast print a table. Every other command prints JSON. To get JSON from any command, add --json right after trakt:

trakt --json components --type engine | jq '.[] | select(.health < 40)'

If your terminal says trakt: command not found, use python -m trakt in its place. It accepts the same commands.

Streaming and exports

delta prints each component that changed, one per line. It also prints a cursor, which is a bookmark for where this run stopped. Save the changes and the cursor to separate files, then pass the cursor back next time to pick up where you left off:

trakt delta --since 2026-06-01T00:00:00Z > changes.ndjson 2> cursor.txt
trakt delta --cursor "$(sed 's/^cursor: //' cursor.txt)" >> changes.ndjson

export downloads your whole fleet in one go. It needs a read_write or full token.

trakt export --format csv -o fleet.csv
trakt export --format ndjson --offset 10000 -o fleet_page2.ndjson

If your fleet has more rows than one export returns, the command tells you which --offset to use for the next batch.

Commands

Command Calls
config GET /api/integrations/config
health GET /api/health-check
token GET /api/token/info
status GET /api/integrations/status
quota GET /api/integrations/quota
summary GET /api/integrations/fleet/summary
aircraft GET /api/integrations/aircraft/extended
components GET /api/integrations/components/extended
forecast GET /api/integrations/planner/forecast
explain GET /api/integrations/predictions/{id}/explanation
delta GET /api/integrations/predictions/delta
export GET /api/integrations/fleet/bulk-export
scenarios GET /api/integrations/scenarios[/{scenario_id}]
deprecations GET /api/integrations/deprecations
version none, prints the client version

Run trakt <command> --help to see the options for any command.

Options and exit codes

--token and --base-url take priority over the TRAKT_TOKEN and TRAKT_BASE_URL environment variables. --timeout sets how many seconds to wait for each response. -v shows each request and retry as it happens.

Each command finishes with a number, so a script can tell what happened:

Code Meaning
0 Success
1 Something went wrong with the API or your connection
2 The command was typed incorrectly
3 Your token was not accepted
4 Your token's access level does not allow this
5 Too many requests, even after automatic retries
6 An endpoint shuts down within your --fail-within window
130 You stopped the command

The trakt command comes with the Python package only. In Node, use the client in your code.

Full endpoint coverage

Both clients cover every endpoint your token can use. This table shows which method calls which endpoint.

Method (Python / Node) Endpoint
config / config GET /api/integrations/config
health_check / healthCheck GET /api/health-check
token_info / tokenInfo GET /api/token/info
integration_status / integrationStatus GET /api/integrations/status
components / components GET /api/integrations/components/extended
available_predictions / availablePredictions GET /api/integrations/predictions/available
forecast / forecast GET /api/integrations/planner/forecast
planner_grid / plannerGrid GET /api/integrations/planner/grid
failure_windows / failureWindows GET /api/integrations/predictions/failure-windows
failure_instances / failureInstances GET /api/integrations/predictions/failure-instances
probability_between / probabilityBetween GET /api/integrations/predictions/probability-between
select_predictions / selectPredictions POST /api/integrations/predictions/select
export_predictions / exportPredictions POST /api/integrations/predictions/export
convert_prediction / convertPrediction POST /api/integrations/planner/convert-prediction
submit_optimizer_feedback / submitOptimizerFeedback POST /api/integrations/optimizer/feedback
aircraft / aircraft GET /api/integrations/aircraft/extended
fleet_export / fleetExport GET /api/integrations/fleet/export
fleet_summary / fleetSummary GET /api/integrations/fleet/summary
scenarios, create_scenario / scenarios, createScenario GET, POST /api/integrations/scenarios
scenario / scenario GET /api/integrations/scenarios/{scenario_id}
asset_configurations, create_asset_configuration / assetConfigurations, createAssetConfiguration GET, POST /api/integrations/asset-configurations
maintenance_programs / maintenancePrograms GET /api/integrations/maintenance-programs
submit_sensor_data / submitSensorData POST /api/v1/sensor-data/batch
submit_aircraft / submitAircraft POST /api/v1/aircraft/batch
submit_components / submitComponents POST /api/v1/components/batch
submit_maintenance / submitMaintenance POST /api/v1/maintenance/batch
submit_work_orders / submitWorkOrders POST /api/v1/work-orders/batch
delta, iter_delta / delta, iterDelta GET /api/integrations/predictions/delta
bulk_export / bulkExport GET /api/integrations/fleet/bulk-export
explanation / explanation GET /api/integrations/predictions/{id}/explanation
explanations / explanations POST /api/integrations/predictions/explanations/bulk
convert_predictions_bulk / convertPredictionsBulk POST /api/integrations/planner/convert-predictions/bulk
quota / quota GET /api/integrations/quota
deprecations / deprecations GET /api/integrations/deprecations

Two of these are being retired. select_predictions and export_predictions stop working on 2026-12-31. Switch to delta and bulk_export before then. Both clients print a warning the first time you call a retiring endpoint, so you see the deadline in your own logs well ahead of time.

Staying in sync

The change feed returns only what changed since you last checked. Checking often costs nothing from your regular call allowance.

cursor = load_cursor()          # whatever you stored last run

page = trakt.delta(cursor=cursor, limit=500)
for change in page:
    upsert(change)
if page.next_cursor:
    save_cursor(page.next_cursor)

Or let the client follow the cursor to the end:

for change in trakt.iter_delta(cursor=cursor):
    upsert(change)
save_cursor(trakt.last_cursor)

Each row holds the full current state of a component. If a run fails partway, start again from your saved cursor and your copy catches up on its own. You need no extra recovery code.

To get notified automatically, register a webhook URL. Trakt sends a message to it when a component's health band changes, when a new critical prediction appears, or when an item becomes overdue. Set this up in the app under Integrations, Event Notifications.

Understanding a prediction

Each prediction comes with an explanation. It shows which sensor readings pushed the risk up or down, and how likely each type of failure is.

why = trakt.explanation(component_id)

print(why.explanation_text)
print("attribution from:", why.method)

for driver in why.top_contributors:
    print(driver.feature, driver.contribution, driver.direction)

print("most likely mode:", why.most_likely_failure_mode)
print(why.failure_mode_probabilities)

A positive contribution raises failure risk and a negative one lowers it.

Check method before you quote any of these numbers. It tells you whether the explanation came from a trained model or from a simpler rule of thumb, and a report should say which.

To explain many components at once, explanations() takes up to fifty component IDs in one call.

Working at fleet scale

# Two hundred conversions in one request, with per-row results
result = trakt.convert_predictions_bulk(
    items=[{"component_id": cid} for cid in approved],
    defaults={"work_type": "inspection"},
    dry_run=True,          # validate first, write nothing
)

print(result["succeeded"], "of", result["requested"])
for row in result["results"]:
    if not row["success"]:
        print("row", row["index"], "failed:", row["error"])

# The whole fleet in one pass, as a file
export = trakt.bulk_export(format="csv")
open(export["filename"], "w").write(export["content"])

Each row is handled on its own, so one bad row leaves the others unaffected. Check results to see how each row did, since the call as a whole can succeed while some rows fail. Running the same call twice creates duplicate work orders.

Sending data in

The five upload methods accept up to 1,000 records per call. When some rows fail, the call still completes and reports which ones failed, so always check the counts:

result = trakt.submit_sensor_data([
    {"component_id": 1, "timestamp": "2026-02-13T09:00:00Z",
     "temperature": 85.2, "external_id": "fdr-abc-001"},
])

print(result["stored"], result["duplicates"], result["rejected"])
for error in result["errors"]:
    print(error["row"], error["reason"])

A row is rejected if it has invalid data or points to a component outside your company. The error tells you the row's position in your list, and the rest of the batch is still saved. Add an external_id to each row to make retries safe: sending the same ID and timestamp again is counted as a duplicate and stored only once.

For more than 1,000 records, split them into several calls yourself. That way, if something fails, you know exactly which call it was.

Handling errors

Each kind of failure has its own error type, so you can handle each one separately.

from trakt import (
    AuthenticationError, AccessDeniedError, RateLimitError, EndpointRetiredError
)

try:
    components = trakt.components()
except AuthenticationError:
    print("The token was not accepted.")
except AccessDeniedError:
    print("This token's access level does not cover that call.")
except RateLimitError:
    print("An allowance is exhausted. The client already retried with backoff.")
except EndpointRetiredError as e:
    print("That endpoint is gone. Use", e.successor)
import {
  AuthenticationError, AccessDeniedError, RateLimitError, EndpointRetiredError
} from "@kquika-inc/trakt";

try {
  const components = await trakt.components();
} catch (e) {
  if (e instanceof AuthenticationError) console.error("The token was not accepted.");
  else if (e instanceof AccessDeniedError) console.error("Access level does not cover that call.");
  else if (e instanceof RateLimitError) console.error("An allowance is exhausted.");
  else if (e instanceof EndpointRetiredError) console.error("Gone. Use", e.successor);
  else throw e;
}

RateLimitError tells you which allowance ran out. Call quota() to see how much you have left and when it resets.

AccessDeniedError tells you the token was accepted but its access level does not cover that call. Earlier versions called it PermissionError_ in Python and PermissionError in Node. Those names still work and catch the same error, and Python shows a warning when you use the old one. They are removed in 2.0.

Deprecation notices

When you call an endpoint that is being retired, the API tells you the shutdown date and which endpoint replaces it. Both clients pass this notice on to you, so the deadline shows up in your logs well before the endpoint stops working.

Python raises a TraktDeprecationWarning, once per endpoint per client:

import warnings
from trakt import TraktDeprecationWarning

warnings.simplefilter("error", TraktDeprecationWarning)   # fail your CI on one
warnings.simplefilter("ignore", TraktDeprecationWarning)  # or silence it

Node calls console.warn by default, and takes a handler:

const trakt = new Trakt({
  token: process.env.TRAKT_TOKEN!,
  onDeprecation: (notice) => {
    logger.warn({ path: notice.path, sunset: notice.sunset,
                  successor: notice.successor }, notice.message);
  },
});

GET /api/integrations/deprecations lists every endpoint scheduled to shut down and when. Both clients offer it as deprecations(). You can also add the command below to your build, so the build fails when any shutdown is within the number of days you set:

trakt deprecations --fail-within 60

What the clients do for you

  • Sign in once. Set your token once and every request uses it.
  • Automatic retries. If you hit a rate limit or the server has a brief problem, the client waits and tries again, following the server's guidance on how long to wait. A rejected token, or a call your access level does not cover, is not retried, since trying again would give the same result.
  • Clear errors. AuthenticationError, AccessDeniedError, RateLimitError, NotFoundError, ServerError.
  • Simple objects. Prediction, survival, and maintenance details sit directly on each component, so health and recommended_action are easy to reach.
  • Predictable ordering. Every list comes back in the same order every time, most urgent first wherever urgency applies. See Ordering below.
  • A terminal command. The Python package includes trakt for everyday tasks with no code.

Ordering

Method Order
components, available_predictions / availablePredictions, select_predictions / selectPredictions Most urgent first: highest failure probability, then lowest health.
forecast Most urgent first (critical, high, medium, normal), then soonest due within each level. Past due items have a negative days_until_due.
failure_windows / failureWindows Soonest expected failure first: least remaining life, then lowest health.
failure_instances / failureInstances Within each instance, earliest failure day first.
scenarios, integration_status / integrationStatus Newest first.
explanations The order of the component IDs you passed.
delta, iter_delta / iterDelta Oldest change first.

The change feed is the one list that runs oldest first, on purpose. It records each change in the order it happened, so your copy stays correct when you apply them in turn. Applied newest first, an older value would overwrite a newer one, and picking up from your saved bookmark would skip changes. For the current state of the fleet, most urgent first, use components.

If your token has a limit on how many components it returns (see max_predictions in config()), components, available_predictions, failure_windows, and forecast return the most urgent components within that limit, not the first ones created.

Reading the fields

Field Meaning
health 0 to 100, where higher is healthier.
health_trend stable, declining, or critical.
predicted_rul_hours / predicted_rul_days Remaining useful life before attention is due.
failure_probability 0 to 1, the modeled chance of failure in the near term.
recommended_action do_nothing, monitor, inspect, repair, or replace.
priority How urgent the item is, for planning.
task_reference The task ID from your own maintenance system, so you can match each row to it.
days_until_due Negative means the item is already past due.

Access levels

Your token is issued at one of three levels, which control both the endpoints it can reach and how many records a request returns:

  • read_only: predictions, forecasts, explanations, and the change feed
  • read_write: adds exports, bulk operations, and work order conversion
  • full: everything

A call outside your token's level raises AccessDeniedError. Call config() to see the level and limits for your token.

Allowances

Usage is tracked in three separate allowances. Keeping your data up to date never eats into the calls your app needs:

Meter What it covers Priced
interactive Everyday requests your app makes Per call, against your plan's daily and monthly limit
feed Checking the change feed Enough to check every thirty seconds, on every access level including read_only
bulk Whole-fleet exports and batch uploads Once per operation, whatever the size

A 50,000 row export costs the same as a 5 row export. Keeping a live copy of your fleet data costs nothing from your app's everyday allowance.

q = trakt.quota()
print(q.interactive.daily_remaining, "interactive calls left today")
print(q.feed.daily_remaining, "feed polls left today")
print(q.bulk.monthly_remaining, "bulk operations left this month")

Every response also includes your remaining allowance in the X-Trakt-Quota-* headers. When an allowance runs out, the API returns error 429 with the number of seconds until it resets. Both clients wait that long and retry for you.

Need a client in another language?

You can download a description of the whole API and use a code generator to build a client in your own language. The file always matches the live API:

curl -LO https://www.trakt.tech/api/openapi.yaml     # YAML format
curl -LO https://www.trakt.tech/api/openapi.json     # JSON format

Downloading these files needs no token, since they contain no customer data. Calling the API itself still needs your token.

For example, to generate a Go client:

openapi-generator-cli generate \
  -i https://www.trakt.tech/api/openapi.yaml \
  -g go -o ./trakt-go

Citation

If Trakt informs a paper, technical report, reliability study, or regulatory submission, cite the release you actually ran.

You can cite two things. Cite Trakt System when your results use its predictions, which covers most cases. Cite the client library as well when your work is about the client itself, or when a reviewer needs to repeat the exact calls you made.

Citing Trakt System

The API documentation always shows the up-to-date Trakt System citation in BibTeX, APA, IEEE, and CITATION.cff formats: https://www.trakt.tech/api-documentation#citation

Copy it from that page. This README leaves the platform version out on purpose, since it would go stale with each new release.

Citing this client

BibTeX

@misc{kquika2026traktpy,
  title        = {Trakt System Python SDK},
  author       = {{Kquika, Inc.}},
  year         = {2026},
  version      = {1.3.3},
  publisher    = {{Kquika, Inc.}},
  howpublished = {\url{https://pypi.org/project/kquika-trakt/}},
  url          = {https://pypi.org/project/kquika-trakt/},
  note         = {Computer software, version 1.3.3}
}

@misc{kquika2026traktjs,
  title        = {Trakt System Node SDK},
  author       = {{Kquika, Inc.}},
  year         = {2026},
  version      = {1.2.3},
  publisher    = {{Kquika, Inc.}},
  howpublished = {\url{https://www.npmjs.com/package/@kquika-inc/trakt}},
  url          = {https://www.npmjs.com/package/@kquika-inc/trakt},
  note         = {Computer software, version 1.2.3}
}

These use @misc because every BibTeX style accepts it. If you use biblatex, you can change it to @software and delete the howpublished line.

APA 7th

Kquika, Inc. (2026). Trakt System Python SDK (Version 1.3.3) [Computer software]. https://pypi.org/project/kquika-trakt/

Kquika, Inc. (2026). Trakt System Node SDK (Version 1.2.3) [Computer software]. https://www.npmjs.com/package/@kquika-inc/trakt

In text: (Kquika, Inc., 2026).

IEEE

Kquika, Inc., "Trakt System Python SDK," version 1.3.3, 2026. [Online]. Available: https://pypi.org/project/kquika-trakt/

Kquika, Inc., "Trakt System Node SDK," version 1.2.3, 2026. [Online]. Available: https://www.npmjs.com/package/@kquika-inc/trakt

CITATION.cff

Save this as CITATION.cff in the top folder of your project, and citation tools will find it. Keep the entry for the client you use.

cff-version: 1.2.0
message: "If you use Trakt in your work, please cite it as below."
title: "Trakt System Python SDK"
type: software
version: "1.3.3"
license: MIT
url: "https://pypi.org/project/kquika-trakt/"
repository-artifact: "https://pypi.org/project/kquika-trakt/"
authors:
  - name: "Kquika, Inc."

For the Node client, change title to Trakt System Node SDK, version to 1.2.3, and both URLs to https://www.npmjs.com/package/@kquika-inc/trakt.

Reporting the version

State the client version in your methods section. The client sends its version with every request, in the User-Agent and X-Trakt-Client headers, so your results can be matched to our server records:

trakt-python/1.3.3
trakt-node/1.2.3

Print it from your code, so the version you report always matches the one you ran:

import trakt
print(trakt.__version__)
trakt --version
import { VERSION } from "@kquika-inc/trakt";
console.log(VERSION);

Predictions also depend on which model produced them, and models are updated on their own schedule. Every change feed row includes model_version, and every explanation includes model_version and active_model. Record these next to the client and API versions, so readers know exactly which model produced your results:

versions = {c.model_version for c in trakt.iter_delta(since=study_start)}
why = trakt.explanation(component_id)
print(why.model_version, why.active_model)
const why = await trakt.explanation(componentId);
console.log(why.prediction?.model_version, why.active_model);

If your results include more than one model_version, they came from more than one model. Report each one, or limit your analysis to a single model.

Support

API reference: https://www.trakt.tech/api-documentation

For questions, a new token, or a higher limit: support@kquika.com

License

MIT

Metadata

Release files for kquika-trakt 1.3.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for kquika-trakt 1.3.3
File Size Uploaded Provenance Actions
kquika_trakt-1.3.3.tar.gz 34.9 kB Without provenance Details for kquika_trakt-1.3.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for kquika-trakt 1.3.3
File Interpreter ABI Platform Actions
kquika_trakt-1.3.3-py3-none-any.whl Python 3 none any Details for kquika_trakt-1.3.3-py3-none-any.whl

Total release size: 69.5 kB

Release files / kquika_trakt-1.3.3.tar.gz

Download URL kquika_trakt-1.3.3.tar.gz
Size 34.9 kB
Tags Source
SHA-256 checksum
How to use checksums
dfa25c235b50041ee4e899e7266b4bde81ab002fc38ea8526c1fa63259badb20
BLAKE2b-256 checksum
How to use checksums
30adfd14e512d0715f308cf1000c317200bff842c4b60d75be9d394c53d0e377
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.9

Release files / kquika_trakt-1.3.3-py3-none-any.whl

Download URL kquika_trakt-1.3.3-py3-none-any.whl
Size 34.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fd869cb86742043d81f02b04fcc324370e5a5ffb224f5391a3072bf3fac31e85
BLAKE2b-256 checksum
How to use checksums
cf0db101a71d117eeb91a258987752f39769c3571406edf058b5da9017402614
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.9

Security for kquika-trakt 1.3.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page