{"_id":"@kquika-inc/trakt","_rev":"37-1eb909ca6a1aa58087130a95c49a6511","name":"@kquika-inc/trakt","dist-tags":{"latest":"1.2.2"},"versions":{"1.2.0":{"name":"@kquika-inc/trakt","version":"1.2.0","keywords":["trakt-system","predictive-maintenance","aviation","mro","api-client","fleet forecasting","supply chain optimization","scheduled planning","demand forecasting"],"author":{"name":"Kquika, Inc.","email":"support@kquika.com"},"license":"MIT","_id":"@kquika-inc/trakt@1.2.0","maintainers":[{"name":"victororibamise","email":"victor.oribamise@gmail.com"}],"homepage":"https://www.trakt.tech/api-documentation","bugs":{"email":"support@kquika.com"},"dist":{"shasum":"7ade860eb1dbce85fdd6c04fcada48446ea1f36a","tarball":"https://registry.npmjs.org/@kquika-inc/trakt/-/trakt-1.2.0.tgz","fileCount":4,"integrity":"sha512-XfCIGnn6qvXkrl67DIvn0ru69VIN0TTJHVpH3z62c9S2Dpt/zYbFHk4GuP7W1yYzTdaPCVKVwb2mmt1z3bYEyg==","signatures":[{"sig":"MEUCIAG0PjesPIw2LBBQILQEuvEoPot1yAH9LtRxW/TNTwDhAiEAyE1F//wNUvH40Zm9s+OjYEpH/1gKelGnzHBsWFkdEsg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":102158},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"a99835dc7f37c403c112acc2c796280bd4966cf2","scripts":{"build":"tsc","sync:readme":"node scripts/sync-readme.mjs","check:readme":"node scripts/sync-readme.mjs --check","prepublishOnly":"npm run sync:readme && npm run build"},"_npmUser":{"name":"victororibamise","email":"victor.oribamise@gmail.com"},"_npmVersion":"12.0.2","description":"Trakt System Integrations API client: fleet predictions and maintenance forecasts.","directories":{},"_nodeVersion":"24.18.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"5.9","@types/node":"^20.19.43"},"_npmOperationalInternal":{"tmp":"tmp/trakt_1.2.0_1788136301688_0.9129088790962983","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@kquika-inc/trakt","version":"1.2.1","keywords":["trakt-system","predictive-maintenance","aviation","mro","api-client","fleet forecasting","supply chain optimization","scheduled planning","demand forecasting"],"author":{"name":"Kquika, Inc.","email":"support@kquika.com"},"license":"MIT","_id":"@kquika-inc/trakt@1.2.1","maintainers":[{"name":"victororibamise","email":"victor.oribamise@gmail.com"}],"homepage":"https://www.trakt.tech/api-documentation","bugs":{"email":"support@kquika.com"},"dist":{"shasum":"ce08b1cdb3eb5e38303d1b494d24e9e01041fba1","tarball":"https://registry.npmjs.org/@kquika-inc/trakt/-/trakt-1.2.1.tgz","fileCount":4,"integrity":"sha512-OBaN0bmxUTyuq9Z7ndI57V0oJ3vIBPmB/1JRlQsDT59KxBg8kDOAdqi9Q9aQgribAaVhSCboBHco2wKBrsYq1g==","signatures":[{"sig":"MEYCIQCxdbdXJ8L82pACt/N/tHa+jDTrfV27MFJ3EAQ/O+lH+gIhAM+3GRSZxBmU5kX6m66Gj1lcZWhq5lJ7Wr1OnfHwMe4l","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIGZBZc987bStvbWcuRfY4Y+PR4p4b5zRuqv/0B/zPBC4AiEA260JnNlXaQgC+PBNfORf2ya2dQRQDOd0v4UDOsX7DUE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":109304},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"deb1a29fde821d96b8184fa70898e7a9492dcd82","scripts":{"build":"tsc","typecheck":"tsc --noEmit","sync:readme":"node scripts/sync-readme.mjs","check:readme":"node scripts/sync-readme.mjs --check","prepublishOnly":"npm run sync:readme && npm run typecheck && npm run build"},"_npmUser":{"name":"victororibamise","email":"victor.oribamise@gmail.com"},"_npmVersion":"12.0.2","description":"Trakt System Integrations API client: fleet predictions and maintenance forecasts.","directories":{},"sideEffects":false,"_nodeVersion":"24.18.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"5.9","@types/node":"^20.19.43"},"_npmOperationalInternal":{"tmp":"tmp/trakt_1.2.1_1790454534593_0.12203207192669563","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"_id":"@kquika-inc/trakt@1.2.2","bugs":{"email":"support@kquika.com"},"dist":{"shasum":"7c285e20e812caf38dc50be6c4ea292b2910d1b4","tarball":"https://registry.npmjs.org/@kquika-inc/trakt/-/trakt-1.2.2.tgz","fileCount":4,"integrity":"sha512-1bd/kkZMiYQfnwq1oWIzH2ipLg/ypWM9hJm0jZLo7Rp9sU3w5trKEJB6JAVzMYjqvGTMwcB9Qg5l53nG4m1xIg==","signatures":[{"sig":"MEUCIFAZPvQ7bXn7p2LgEZXj6GPj6+ThNcyumdji+NrIlSIqAiEAoZBkxK/oR6DLslnJn9lO+XwiQR6XWPgdx7N6wiAWnuk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCCDV37tN3d8ckUJRRsg1Kb/Mm+poTy7t+7jP9JLbadfQIgRRZ2BW1cuJNqqlaVYP+nFNjSe6kZ3/pKQEvsAMCfhfs="}],"unpackedSize":114842},"main":"./dist/index.js","name":"@kquika-inc/trakt","type":"module","types":"./dist/index.d.ts","author":{"name":"Kquika, Inc.","email":"support@kquika.com"},"engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"2a6f5549c7ec74682108c679ea214207e79c07ec","license":"MIT","scripts":{"build":"tsc","typecheck":"tsc --noEmit","sync:readme":"node scripts/sync-readme.mjs","check:readme":"node scripts/sync-readme.mjs --check","prepublishOnly":"npm run sync:readme && npm run typecheck && npm run build"},"version":"1.2.2","_npmUser":{"name":"victororibamise","email":"victor.oribamise@gmail.com"},"homepage":"https://www.trakt.tech/api-documentation","keywords":["trakt-system","predictive-maintenance","aviation","mro","api-client","fleet forecasting","supply chain optimization","scheduled planning","demand forecasting"],"_npmVersion":"12.0.2","description":"Trakt System Integrations API client: fleet predictions and maintenance forecasts.","directories":{},"maintainers":[{"name":"victororibamise","email":"victor.oribamise@gmail.com"}],"sideEffects":false,"_nodeVersion":"24.18.0","_hasShrinkwrap":false,"devDependencies":{"typescript":"5.9","@types/node":"^20.19.43"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/trakt_1.2.2_1790547654136_0.014724810926343146"}}},"time":{"created":"2026-07-12T19:26:44.698Z","modified":"2026-09-27T22:20:54.405Z","1.0.0":"2026-07-12T19:26:45.081Z","1.0.1":"2026-07-12T19:33:02.541Z","1.0.2":"2026-07-12T19:41:04.122Z","1.0.3":"2026-07-12T19:42:50.050Z","1.0.4":"2026-07-13T19:51:14.438Z","1.0.5":"2026-07-13T19:52:27.191Z","1.0.6":"2026-07-13T19:54:31.864Z","1.0.7":"2026-07-13T19:56:10.530Z","1.0.8":"2026-07-13T19:58:29.751Z","1.0.9":"2026-07-17T08:38:04.439Z","1.1.0":"2026-07-17T19:29:04.393Z","1.1.1":"2026-07-20T11:59:35.440Z","1.1.2":"2026-08-13T09:24:11.498Z","1.1.3":"2026-08-13T09:28:22.363Z","1.1.4":"2026-08-14T09:51:59.184Z","1.1.5":"2026-08-16T14:48:50.459Z","1.1.6":"2026-08-29T22:32:54.640Z","1.2.0":"2026-08-31T00:31:41.897Z","1.2.1":"2026-09-26T20:28:54.667Z","1.2.2":"2026-09-27T22:20:54.217Z"},"bugs":{"email":"support@kquika.com"},"author":{"name":"Kquika, Inc.","email":"support@kquika.com"},"license":"MIT","homepage":"https://www.trakt.tech/api-documentation","keywords":["trakt-system","predictive-maintenance","aviation","mro","api-client","fleet forecasting","supply chain optimization","scheduled planning","demand forecasting"],"description":"Trakt System Integrations API client: fleet predictions and maintenance forecasts.","maintainers":[{"name":"victororibamise","email":"victor.oribamise@gmail.com"}],"readme":"# Trakt System SDK\n\nClient libraries for the Trakt System Integrations API: fleet predictions and\nmaintenance forecasts, in a few lines of code.\n\nTrakt System predicts which components on your fleet need attention, when, and what to\ndo about them. This SDK gives you that data directly, with authentication,\nretries, and rate limits handled for you.\n\nFull API reference, with details on every endpoint:\nhttps://www.trakt.tech/api-documentation\n\n## Install\n\n**Python**\n\n```bash\npip install kquika-trakt              # core\npip install \"kquika-trakt[pandas]\"    # with DataFrame support\n```\n\nYou install `kquika-trakt`, then write `import trakt` in your code.\n\nThe Python package also gives you a `trakt` command to run in your terminal. See\n[Command line](#command-line).\n\n**Node / TypeScript**\n\n```bash\nnpm install @kquika-inc/trakt\n```\n\nRequires Node 18 or newer. TypeScript types are included.\n\n## Quickstart\n\n**Python**\n\n```python\nfrom trakt import Trakt\n\ntrakt = Trakt(token=\"YOUR_API_KEY\")   # or set TRAKT_TOKEN\n\n# What can this token do?\ncfg = trakt.config()\nprint(cfg.access_level, cfg.max_predictions, cfg.can_export)\n\n# Per-component predictions, most urgent first\nfor c in trakt.components():\n    print(c.name, c.aircraft_tail_number, c.health,\n          c.failure_probability, c.recommended_action)\n\n# The next 90 days of maintenance, soonest first\nfor item in trakt.forecast(days=90):\n    if item.is_overdue:\n        print(\"OVERDUE:\", item.tail_number, item.component_name)\n\n# Straight to a DataFrame for planning\ndf = trakt.components_dataframe()\n\n# Fleet-level rollup that matches the dashboards: health, composite average\n# confidence, prediction coverage, and 30-day survival\nsummary = trakt.fleet_summary()\nprint(summary.fleet_health, summary.avg_confidence, summary.survival_30d)\n\n# Everything that changed since you last looked. Not charged against your\n# interactive call allowance, so you can poll it every thirty seconds.\nfor change in trakt.iter_delta(since=\"2026-06-01T00:00:00Z\"):\n    print(change.component_name, change.health_band, change.days_until_due)\nprint(\"resume from\", trakt.last_cursor)\n\n# Why a prediction says what it says\nwhy = trakt.explanation(1421)\nprint(why.risk_level, why.method, why.most_likely_failure_mode)\nfor driver in why.top_contributors[:3]:\n    print(\" \", driver.feature, driver.contribution, driver.direction)\n```\n\n**Node / TypeScript**\n\n```typescript\nimport { Trakt } from \"@kquika-inc/trakt\";\n\nconst trakt = new Trakt({ token: process.env.TRAKT_TOKEN! });\n\nconst cfg = await trakt.config();\nconsole.log(cfg.access_level, cfg.max_predictions);\n\n// Per-component predictions, most urgent first\nconst components = await trakt.components();\nfor (const c of components) {\n  console.log(c.name, c.aircraft_tail_number, c.health, c.recommended_action);\n}\n\n// The next 90 days of maintenance, soonest first\nconst forecast = await trakt.forecast({ days: 90 });\nfor (const item of forecast) {\n  if (item.is_overdue) console.log(\"OVERDUE:\", item.tail_number, item.component_name);\n}\n\n// Fleet-level rollup that matches the dashboards\nconst summary = await trakt.fleetSummary();\nconsole.log(summary.fleet_health, summary.avg_confidence, summary.survival_30d);\n\n// Everything that changed since you last looked. Not charged against your\n// interactive call allowance, so you can poll it every thirty seconds.\nfor await (const change of trakt.iterDelta({ since: \"2026-06-01T00:00:00Z\" })) {\n  console.log(change.component_name, change.health_band, change.days_until_due);\n}\nconsole.log(\"resume from\", trakt.lastCursor);\n\n// Why a prediction says what it says\nconst why = await trakt.explanation(1421);\nconsole.log(why.prediction?.risk_level, why.explanation?.method);\n```\n\n## Command line\n\nThe Python package includes a `trakt` command, so you can check your token or\npull predictions straight from the terminal with no code. It works the same way\nas the Python client, including automatic retries.\n\n```bash\nexport TRAKT_TOKEN=YOUR_API_KEY\n\ntrakt config                         # access level and limits for this token\ntrakt quota                          # remaining allowance on each meter\ntrakt summary                        # fleet health rollup\n\ntrakt components -n 20               # the 20 most urgent components\ntrakt components --aircraft-id 7 --priority high\ntrakt forecast --days 90             # next 90 days, soonest first\ntrakt forecast --days 90 --overdue   # past due items only\ntrakt explain 1421                   # drivers behind one prediction\ntrakt scenarios                      # planning scenarios, or `trakt scenarios 5` for one\n```\n\n`components` and `forecast` print a table. Every other command prints JSON. To\nget JSON from any command, add `--json` right after `trakt`:\n\n```bash\ntrakt --json components --type engine | jq '.[] | select(.health < 40)'\n```\n\nIf your terminal says `trakt: command not found`, use `python -m trakt` in its\nplace. It accepts the same commands.\n\n### Streaming and exports\n\n`delta` prints each component that changed, one per line. It also prints a\ncursor, which is a bookmark for where this run stopped. Save the changes and the\ncursor to separate files, then pass the cursor back next time to pick up where\nyou left off:\n\n```bash\ntrakt delta --since 2026-06-01T00:00:00Z > changes.ndjson 2> cursor.txt\ntrakt delta --cursor \"$(sed 's/^cursor: //' cursor.txt)\" >> changes.ndjson\n```\n\n`export` downloads your whole fleet in one go. It needs a `read_write` or `full`\ntoken.\n\n```bash\ntrakt export --format csv -o fleet.csv\ntrakt export --format ndjson --offset 10000 -o fleet_page2.ndjson\n```\n\nIf your fleet has more rows than one export returns, the command tells you\nwhich `--offset` to use for the next batch.\n\n### Commands\n\n| Command      | Calls                                           |\n| ------------ | ----------------------------------------------- |\n| `config`     | `GET /api/integrations/config`                  |\n| `health`     | `GET /api/health-check`                         |\n| `token`      | `GET /api/token/info`                           |\n| `status`     | `GET /api/integrations/status`                  |\n| `quota`      | `GET /api/integrations/quota`                   |\n| `summary`    | `GET /api/integrations/fleet/summary`           |\n| `aircraft`   | `GET /api/integrations/aircraft/extended`       |\n| `components` | `GET /api/integrations/components/extended`     |\n| `forecast`   | `GET /api/integrations/planner/forecast`        |\n| `explain`    | `GET /api/integrations/predictions/{id}/explanation` |\n| `delta`      | `GET /api/integrations/predictions/delta`       |\n| `export`     | `GET /api/integrations/fleet/bulk-export`       |\n| `scenarios`  | `GET /api/integrations/scenarios[/{scenario_id}]` |\n| `deprecations` | `GET /api/integrations/deprecations`          |\n| `version`    | none, prints the client version                 |\n\nRun `trakt <command> --help` to see the options for any command.\n\n### Options and exit codes\n\n`--token` and `--base-url` take priority over the `TRAKT_TOKEN` and\n`TRAKT_BASE_URL` environment variables. `--timeout` sets how many seconds to\nwait for each response. `-v` shows each request and retry as it happens.\n\nEach command finishes with a number, so a script can tell what happened:\n\n| Code | Meaning                                       |\n| ---- | --------------------------------------------- |\n| 0    | Success                                       |\n| 1    | Something went wrong with the API or your connection |\n| 2    | The command was typed incorrectly             |\n| 3    | Your token was not accepted                   |\n| 4    | Your token's access level does not allow this |\n| 5    | Too many requests, even after automatic retries |\n| 6    | An endpoint shuts down within your `--fail-within` window |\n| 130  | You stopped the command                       |\n\nThe `trakt` command comes with the Python package only. In Node, use the client\nin your code.\n\n## Full endpoint coverage\n\nBoth clients cover every endpoint your token can use. This table shows which\nmethod calls which endpoint.\n\n| Method (Python / Node) | Endpoint |\n| --- | --- |\n| `config` / `config` | `GET /api/integrations/config` |\n| `health_check` / `healthCheck` | `GET /api/health-check` |\n| `token_info` / `tokenInfo` | `GET /api/token/info` |\n| `integration_status` / `integrationStatus` | `GET /api/integrations/status` |\n| `components` / `components` | `GET /api/integrations/components/extended` |\n| `available_predictions` / `availablePredictions` | `GET /api/integrations/predictions/available` |\n| `forecast` / `forecast` | `GET /api/integrations/planner/forecast` |\n| `planner_grid` / `plannerGrid` | `GET /api/integrations/planner/grid` |\n| `failure_windows` / `failureWindows` | `GET /api/integrations/predictions/failure-windows` |\n| `failure_instances` / `failureInstances` | `GET /api/integrations/predictions/failure-instances` |\n| `probability_between` / `probabilityBetween` | `GET /api/integrations/predictions/probability-between` |\n| `select_predictions` / `selectPredictions` | `POST /api/integrations/predictions/select` |\n| `export_predictions` / `exportPredictions` | `POST /api/integrations/predictions/export` |\n| `convert_prediction` / `convertPrediction` | `POST /api/integrations/planner/convert-prediction` |\n| `submit_optimizer_feedback` / `submitOptimizerFeedback` | `POST /api/integrations/optimizer/feedback` |\n| `aircraft` / `aircraft` | `GET /api/integrations/aircraft/extended` |\n| `fleet_export` / `fleetExport` | `GET /api/integrations/fleet/export` |\n| `fleet_summary` / `fleetSummary` | `GET /api/integrations/fleet/summary` |\n| `scenarios`, `create_scenario` / `scenarios`, `createScenario` | `GET`, `POST /api/integrations/scenarios` |\n| `scenario` / `scenario` | `GET /api/integrations/scenarios/{scenario_id}` |\n| `asset_configurations`, `create_asset_configuration` / `assetConfigurations`, `createAssetConfiguration` | `GET`, `POST /api/integrations/asset-configurations` |\n| `maintenance_programs` / `maintenancePrograms` | `GET /api/integrations/maintenance-programs` |\n| `submit_sensor_data` / `submitSensorData` | `POST /api/v1/sensor-data/batch` |\n| `submit_aircraft` / `submitAircraft` | `POST /api/v1/aircraft/batch` |\n| `submit_components` / `submitComponents` | `POST /api/v1/components/batch` |\n| `submit_maintenance` / `submitMaintenance` | `POST /api/v1/maintenance/batch` |\n| `submit_work_orders` / `submitWorkOrders` | `POST /api/v1/work-orders/batch` |\n| `delta`, `iter_delta` / `delta`, `iterDelta` | `GET /api/integrations/predictions/delta` |\n| `bulk_export` / `bulkExport` | `GET /api/integrations/fleet/bulk-export` |\n| `explanation` / `explanation` | `GET /api/integrations/predictions/{id}/explanation` |\n| `explanations` / `explanations` | `POST /api/integrations/predictions/explanations/bulk` |\n| `convert_predictions_bulk` / `convertPredictionsBulk` | `POST /api/integrations/planner/convert-predictions/bulk` |\n| `quota` / `quota` | `GET /api/integrations/quota` |\n| `deprecations` / `deprecations` | `GET /api/integrations/deprecations` |\n\nTwo of these are being retired. `select_predictions` and `export_predictions`\nstop working on **2026-12-31**. Switch to `delta` and `bulk_export` before then.\nBoth clients print a warning the first time you call a retiring endpoint, so you\nsee the deadline in your own logs well ahead of time.\n\n## Staying in sync\n\nThe change feed returns only what changed since you last checked. Checking\noften costs nothing from your regular call allowance.\n\n```python\ncursor = load_cursor()          # whatever you stored last run\n\npage = trakt.delta(cursor=cursor, limit=500)\nfor change in page:\n    upsert(change)\nif page.next_cursor:\n    save_cursor(page.next_cursor)\n```\n\nOr let the client follow the cursor to the end:\n\n```python\nfor change in trakt.iter_delta(cursor=cursor):\n    upsert(change)\nsave_cursor(trakt.last_cursor)\n```\n\nEach row holds the full current state of a component. If a run fails partway,\nstart again from your saved cursor and your copy catches up on its own. You need\nno extra recovery code.\n\nTo get notified automatically, register a webhook URL. Trakt sends a message\nto it when a component's health band changes, when a new critical prediction\nappears, or when an item becomes overdue. Set this up in the app under\nIntegrations, Event Notifications.\n\n## Understanding a prediction\n\nEach prediction comes with an explanation. It shows which sensor readings\npushed the risk up or down, and how likely each type of failure is.\n\n```python\nwhy = trakt.explanation(component_id)\n\nprint(why.explanation_text)\nprint(\"attribution from:\", why.method)\n\nfor driver in why.top_contributors:\n    print(driver.feature, driver.contribution, driver.direction)\n\nprint(\"most likely mode:\", why.most_likely_failure_mode)\nprint(why.failure_mode_probabilities)\n```\n\nA positive `contribution` raises failure risk and a negative one lowers it.\n\nCheck `method` before you quote any of these numbers. It tells you whether the\nexplanation came from a trained model or from a simpler rule of thumb, and a\nreport should say which.\n\nTo explain many components at once, `explanations()` takes up to fifty component\nIDs in one call.\n\n## Working at fleet scale\n\n```python\n# Two hundred conversions in one request, with per-row results\nresult = trakt.convert_predictions_bulk(\n    items=[{\"component_id\": cid} for cid in approved],\n    defaults={\"work_type\": \"inspection\"},\n    dry_run=True,          # validate first, write nothing\n)\n\nprint(result[\"succeeded\"], \"of\", result[\"requested\"])\nfor row in result[\"results\"]:\n    if not row[\"success\"]:\n        print(\"row\", row[\"index\"], \"failed:\", row[\"error\"])\n\n# The whole fleet in one pass, as a file\nexport = trakt.bulk_export(format=\"csv\")\nopen(export[\"filename\"], \"w\").write(export[\"content\"])\n```\n\nEach row is handled on its own, so one bad row leaves the others unaffected.\nCheck `results` to see how each row did, since the call as a whole can succeed\nwhile some rows fail. Running the same call twice creates duplicate work\norders.\n\n## Sending data in\n\nThe five upload methods accept up to 1,000 records per call. When some rows\nfail, the call still completes and reports which ones failed, so always check the\ncounts:\n\n```python\nresult = trakt.submit_sensor_data([\n    {\"component_id\": 1, \"timestamp\": \"2026-02-13T09:00:00Z\",\n     \"temperature\": 85.2, \"external_id\": \"fdr-abc-001\"},\n])\n\nprint(result[\"stored\"], result[\"duplicates\"], result[\"rejected\"])\nfor error in result[\"errors\"]:\n    print(error[\"row\"], error[\"reason\"])\n```\n\nA row is rejected if it has invalid data or points to a component outside your\ncompany. The error tells you the row's position in your list, and the rest of\nthe batch is still saved. Add an `external_id` to each row to make retries safe:\nsending the same ID and timestamp again is counted as a duplicate and stored\nonly once.\n\nFor more than 1,000 records, split them into several calls yourself. That way,\nif something fails, you know exactly which call it was.\n\n## Handling errors\n\nEach kind of failure has its own error type, so you can handle each one\nseparately.\n\n```python\nfrom trakt import (\n    AuthenticationError, PermissionError_, RateLimitError, EndpointRetiredError\n)\n\ntry:\n    components = trakt.components()\nexcept AuthenticationError:\n    print(\"The token was not accepted.\")\nexcept PermissionError_:\n    print(\"This token's access level does not cover that call.\")\nexcept RateLimitError:\n    print(\"An allowance is exhausted. The client already retried with backoff.\")\nexcept EndpointRetiredError as e:\n    print(\"That endpoint is gone. Use\", e.successor)\n```\n\n```typescript\nimport {\n  AuthenticationError, PermissionError, RateLimitError, EndpointRetiredError\n} from \"@kquika-inc/trakt\";\n\ntry {\n  const components = await trakt.components();\n} catch (e) {\n  if (e instanceof AuthenticationError) console.error(\"The token was not accepted.\");\n  else if (e instanceof PermissionError) console.error(\"Access level does not cover that call.\");\n  else if (e instanceof RateLimitError) console.error(\"An allowance is exhausted.\");\n  else if (e instanceof EndpointRetiredError) console.error(\"Gone. Use\", e.successor);\n  else throw e;\n}\n```\n\n`RateLimitError` tells you which allowance ran out. Call `quota()` to see how\nmuch you have left and when it resets.\n\n## Deprecation notices\n\nWhen you call an endpoint that is being retired, the API tells you the shutdown\ndate and which endpoint replaces it. Both clients pass this notice on to you, so\nthe deadline shows up in your logs well before the endpoint stops working.\n\nPython raises a `TraktDeprecationWarning`, once per endpoint per client:\n\n```python\nimport warnings\nfrom trakt import TraktDeprecationWarning\n\nwarnings.simplefilter(\"error\", TraktDeprecationWarning)   # fail your CI on one\nwarnings.simplefilter(\"ignore\", TraktDeprecationWarning)  # or silence it\n```\n\nNode calls `console.warn` by default, and takes a handler:\n\n```typescript\nconst trakt = new Trakt({\n  token: process.env.TRAKT_TOKEN!,\n  onDeprecation: (notice) => {\n    logger.warn({ path: notice.path, sunset: notice.sunset,\n                  successor: notice.successor }, notice.message);\n  },\n});\n```\n\n`GET /api/integrations/deprecations` lists every endpoint scheduled to shut down\nand when. Both clients offer it as `deprecations()`. You can also add the command\nbelow to your build, so the build fails when any shutdown is within the number\nof days you set:\n\n```bash\ntrakt deprecations --fail-within 60\n```\n\n## What the clients do for you\n\n- **Sign in once.** Set your token once and every request uses it.\n- **Automatic retries.** If you hit a rate limit or the server has a brief\n  problem, the client waits and tries again, following the server's guidance on\n  how long to wait. A rejected token or a permission error is not retried, since\n  trying again would give the same result.\n- **Clear errors.** `AuthenticationError`, `PermissionError`, `RateLimitError`,\n  `NotFoundError`, `ServerError`.\n- **Simple objects.** Prediction, survival, and maintenance details sit directly\n  on each component, so `health` and `recommended_action` are easy to reach.\n- **Predictable ordering.** Every list comes back in the same order every time,\n  most urgent first wherever urgency applies. See [Ordering](#ordering) below.\n- **A terminal command.** The Python package includes `trakt` for everyday tasks\n  with no code.\n\n## Ordering\n\n| Method | Order |\n| --- | --- |\n| `components`, `available_predictions` / `availablePredictions`, `select_predictions` / `selectPredictions` | Most urgent first: highest failure probability, then lowest health. |\n| `forecast` | Most urgent first (critical, high, medium, normal), then soonest due within each level. Past due items have a negative `days_until_due`. |\n| `failure_windows` / `failureWindows` | Soonest expected failure first: least remaining life, then lowest health. |\n| `failure_instances` / `failureInstances` | Within each instance, earliest failure day first. |\n| `scenarios`, `integration_status` / `integrationStatus` | Newest first. |\n| `explanations` | The order of the component IDs you passed. |\n| `delta`, `iter_delta` / `iterDelta` | Oldest change first. |\n\nThe change feed is the one list that runs oldest first, on purpose. It records\neach change in the order it happened, so your copy stays correct when you apply\nthem in turn. Applied newest first, an older value would overwrite a newer one,\nand picking up from your saved bookmark would skip changes. For the current\nstate of the fleet, most urgent first, use `components`.\n\nIf your token has a limit on how many components it returns (see\n`max_predictions` in `config()`), `components`, `available_predictions`,\n`failure_windows`, and `forecast` return the most urgent components within that\nlimit, not the first ones created.\n\n## Reading the fields\n\n| Field | Meaning |\n| --- | --- |\n| `health` | 0 to 100, where higher is healthier. |\n| `health_trend` | stable, declining, or critical. |\n| `predicted_rul_hours` / `predicted_rul_days` | Remaining useful life before attention is due. |\n| `failure_probability` | 0 to 1, the modeled chance of failure in the near term. |\n| `recommended_action` | do_nothing, monitor, inspect, repair, or replace. |\n| `priority` | How urgent the item is, for planning. |\n| `task_reference` | The task ID from your own maintenance system, so you can match each row to it. |\n| `days_until_due` | Negative means the item is already past due. |\n\n## Access levels\n\nYour token is issued at one of three levels, which control both the endpoints it\ncan reach and how many records a request returns:\n\n- `read_only`: predictions, forecasts, explanations, and the change feed\n- `read_write`: adds exports, bulk operations, and work order conversion\n- `full`: everything\n\nA call outside your token's level raises a permission error. Call `config()` to\nsee the level and limits for your token.\n\n## Allowances\n\nUsage is tracked in three separate allowances. Keeping your data up to date\nnever eats into the calls your app needs:\n\n| Meter | What it covers | Priced |\n| --- | --- | --- |\n| `interactive` | Everyday requests your app makes | Per call, against your plan's daily and monthly limit |\n| `feed` | Checking the change feed | Enough to check every thirty seconds, on every access level including `read_only` |\n| `bulk` | Whole-fleet exports and batch uploads | Once per operation, whatever the size |\n\nA 50,000 row export costs the same as a 5 row export. Keeping a live copy of\nyour fleet data costs nothing from your app's everyday allowance.\n\n```python\nq = trakt.quota()\nprint(q.interactive.daily_remaining, \"interactive calls left today\")\nprint(q.feed.daily_remaining, \"feed polls left today\")\nprint(q.bulk.monthly_remaining, \"bulk operations left this month\")\n```\n\nEvery response also includes your remaining allowance in the `X-Trakt-Quota-*`\nheaders. When an allowance runs out, the API returns error `429` with the number\nof seconds until it resets. Both clients wait that long and retry for you.\n\n## Need a client in another language?\n\nYou can download a description of the whole API and use a code generator to\nbuild a client in your own language. The file always matches the live API:\n\n```bash\ncurl -LO https://www.trakt.tech/api/openapi.yaml     # YAML format\ncurl -LO https://www.trakt.tech/api/openapi.json     # JSON format\n```\n\nDownloading these files needs no token, since they contain no customer data.\nCalling the API itself still needs your token.\n\nFor example, to generate a Go client:\n\n```bash\nopenapi-generator-cli generate \\\n  -i https://www.trakt.tech/api/openapi.yaml \\\n  -g go -o ./trakt-go\n```\n\n## Citation\n\nIf Trakt informs a paper, technical report, reliability study, or regulatory\nsubmission, cite the release you actually ran.\n\nYou can cite two things. Cite **Trakt System** when your results use its\npredictions, which covers most cases. Cite the **client library** as well when\nyour work is about the client itself, or when a reviewer needs to repeat the\nexact calls you made.\n\n### Citing Trakt System\n\nThe API documentation always shows the up-to-date Trakt System citation in\nBibTeX, APA, IEEE, and CITATION.cff formats:\nhttps://www.trakt.tech/api-documentation#citation\n\nCopy it from that page. This README leaves the platform version out on purpose,\nsince it would go stale with each new release.\n\n### Citing this client\n\n**BibTeX**\n\n```bibtex\n@misc{kquika2026traktpy,\n  title        = {Trakt System Python SDK},\n  author       = {{Kquika, Inc.}},\n  year         = {2026},\n  version      = {1.3.2},\n  publisher    = {{Kquika, Inc.}},\n  howpublished = {\\url{https://pypi.org/project/kquika-trakt/}},\n  url          = {https://pypi.org/project/kquika-trakt/},\n  note         = {Computer software, version 1.3.2}\n}\n\n@misc{kquika2026traktjs,\n  title        = {Trakt System Node SDK},\n  author       = {{Kquika, Inc.}},\n  year         = {2026},\n  version      = {1.2.2},\n  publisher    = {{Kquika, Inc.}},\n  howpublished = {\\url{https://www.npmjs.com/package/@kquika-inc/trakt}},\n  url          = {https://www.npmjs.com/package/@kquika-inc/trakt},\n  note         = {Computer software, version 1.2.2}\n}\n```\n\nThese use `@misc` because every BibTeX style accepts it. If you use biblatex,\nyou can change it to `@software` and delete the `howpublished` line.\n\n**APA 7th**\n\n```\nKquika, Inc. (2026). Trakt System Python SDK (Version 1.3.2) [Computer software]. https://pypi.org/project/kquika-trakt/\n\nKquika, Inc. (2026). Trakt System Node SDK (Version 1.2.2) [Computer software]. https://www.npmjs.com/package/@kquika-inc/trakt\n```\n\nIn text: (Kquika, Inc., 2026).\n\n**IEEE**\n\n```\nKquika, Inc., \"Trakt System Python SDK,\" version 1.3.2, 2026. [Online]. Available: https://pypi.org/project/kquika-trakt/\n\nKquika, Inc., \"Trakt System Node SDK,\" version 1.2.2, 2026. [Online]. Available: https://www.npmjs.com/package/@kquika-inc/trakt\n```\n\n**CITATION.cff**\n\nSave this as `CITATION.cff` in the top folder of your project, and citation\ntools will find it. Keep the entry for the client you use.\n\n```yaml\ncff-version: 1.2.0\nmessage: \"If you use Trakt in your work, please cite it as below.\"\ntitle: \"Trakt System Python SDK\"\ntype: software\nversion: \"1.3.2\"\nlicense: MIT\nurl: \"https://pypi.org/project/kquika-trakt/\"\nrepository-artifact: \"https://pypi.org/project/kquika-trakt/\"\nauthors:\n  - name: \"Kquika, Inc.\"\n```\n\nFor the Node client, change `title` to `Trakt System Node SDK`, `version` to\n`1.2.2`, and both URLs to\n`https://www.npmjs.com/package/@kquika-inc/trakt`.\n\n### Reporting the version\n\nState the client version in your methods section. The client sends its version\nwith every request, so your results can be matched to our server records:\n\n```\ntrakt-python/1.3.2\ntrakt-node/1.2.2\n```\n\nPrint it from your code, so the version you report always matches the one you\nran:\n\n```python\nimport trakt\nprint(trakt.__version__)\n```\n\n```bash\ntrakt --version\n```\n\n```typescript\nimport { VERSION } from \"@kquika-inc/trakt\";\nconsole.log(VERSION);\n```\n\nPredictions also depend on which model produced them, and models are updated on\ntheir own schedule. Every change feed row includes `model_version`, and every\nexplanation includes `model_version` and `active_model`. Record these next to the\nclient and API versions, so readers know exactly which model produced your\nresults:\n\n```python\nversions = {c.model_version for c in trakt.iter_delta(since=study_start)}\nwhy = trakt.explanation(component_id)\nprint(why.model_version, why.active_model)\n```\n\n```typescript\nconst why = await trakt.explanation(componentId);\nconsole.log(why.prediction?.model_version, why.active_model);\n```\n\nIf your results include more than one `model_version`, they came from more than\none model. Report each one, or limit your analysis to a single model.\n\n## Support\n\nAPI reference: https://www.trakt.tech/api-documentation\n\nFor questions, a new token, or a higher limit: support@kquika.com\n\n## License\n\nMIT","readmeFilename":"README.md"}