Skip to main content

Charts

The charts endpoint exposes the same aggregated data that powers TrackMyMachines' built-in dashboards. Each chart type wraps an aggregator plus a configured ChartFilter, so passing the same query string you would use in the dashboard URL returns the data behind that chart.

Permissions

EndpointMethodRead-only AccessRead-write AccessDescription
/api/v1/charts/:chart_typeGETRetrieve the data for a chart

GET /api/v1/charts/:chart_type

Required role: read-only or read-write

Path parameters:

  • chart_type: one of the supported chart types (see below). Unknown values return 404 Not Found with { "error": "Chart not found" }.

Supported chart types

chart_typeDescription
machine_utilisationSpindle utilisation — uptime as a share of total available time.
effective_utilisationEffective utilisation — uptime plus productive downtime as a share of available time (excluding discounted downtime).
utilisation_rankingMachine utilisation ranked highest-first — one row per machine (or per cell / site via the grouping).
machine_hoursSpindle uptime in hours — the time machines spent actively cutting.
effective_hoursEffective hours — uptime plus productive downtime — over the selected period.
downtime_hoursDowntime in hours over the selected period.
downtime_analysisBreakdown of how machine time was spent — uptime, productive downtime, unproductive downtime, discounted downtime, and unaccounted downtime.
shift_breakdownUtilisation broken down by shift pattern.
calendarDaily utilisation across the selected period (renders as a calendar heatmap in the dashboard).
downtime_reason_hoursTime spent against each individual downtime reason.
downtime_reason_percentDowntime per reason as a fraction of available time.
downtime_reason_category_hoursTime spent in each downtime reason category.
downtime_reason_category_percentDowntime per reason category as a fraction of available time.
downtime_reason_horizontalDowntime per reason ranked per entity — same rows as downtime_reason_hours, presented as ranked bars in the dashboard.
downtime_reason_category_horizontalDowntime per reason category ranked per entity.
downtime_reason_paretoDowntime reasons ranked by total time, with a cumulative share — the classic 80/20 view.
energyEnergy consumption in kWh over the selected period.
idle_energyEnergy consumed in kWh while machines were idle, with the idle time behind it.
total_partsTotal parts counted across the window — a single whole-window figure.
good_partsGood parts (total minus scrap) across the window — a single whole-window figure.
scrap_rateScrap as a 0–1 share of total parts across the window — a single whole-window figure.
oeeOverall Equipment Effectiveness for the whole window — availability × performance × quality, with each factor's inputs.
oee_availabilityThe availability factor for the whole window, with its inputs.
oee_performanceThe performance factor for the whole window, with its inputs.
oee_qualityThe quality factor for the whole window, with its inputs.

Query parameters

Every parameter is optional — each chart type has sensible defaults (e.g. machine_utilisation defaults to the last 7 days bucketed by day).

  • from, to: ISO8601 start and end of the time range. Must be provided together; an unparseable value returns 422 Unprocessable Entity.
  • bucket: bucket size for time-series charts. One of hour, day, week, month, or max (a single bucket spanning the whole range). Buckets too coarse for the range are coerced to a finer one — check the response envelope for the bucket you actually got.
  • group_by: how to group the data. One of none, machine, factory, area, shift_pattern.
  • shift_type: one of ignore_shift, in_shift, out_of_shift, specific_shift. Defaults to in_shift.
  • machine_foreign_ids[]: array of machine foreign IDs to filter by. A single bare value (machine_foreign_ids=CNC-01) is accepted as a one-element filter.
  • shift_pattern_ids[]: array of shift pattern IDs to filter by.
  • activity_reason_category_ids[]: array of activity reason category IDs to filter by.

Internal database IDs (machine_ids, etc.) are not accepted — only foreign / external identifiers cross the API boundary. Requests that include machine_ids will silently ignore it.

Period-over-period comparison (compare, previous_from, previous_to) is not supported on this endpoint and returns 400 Bad Request. Issue two requests with different windows instead.

Not every parameter is meaningful for every chart type — shift_breakdown always groups by shift_pattern, and the KPI types (the four oee* figures and the three part-count figures) always collapse to a single whole-window row regardless of bucket and group_by.

Example request

curl -X GET "https://your-org.trackmymachines.app/api/v1/charts/machine_utilisation?from=2025-05-20T00:00:00Z&to=2025-05-27T00:00:00Z&bucket=day&group_by=machine" \
-H "Authorization: Bearer YOUR_API_KEY"

Response shape

Every chart type returns the same envelope. group_by, bucket, from and to echo the resolved filter — defaults and coercions included — so you always see the window and grain the data actually covers:

{
"chart_type": "machine_utilisation",
"group_by": "machine",
"bucket": "day",
"from": "2025-05-20T00:00:00+00:00",
"to": "2025-05-27T00:00:00+00:00",
"rows": [
{
"entity_name": "CNC-01",
"from": "2025-05-20T00:00:00+00:00",
"to": "2025-05-21T00:00:00+00:00",
"uptime_seconds": 21600,
"downtime_seconds": 5400,
"offtime_seconds": 1800,
"productive_downtime_seconds": 3600,
"unproductive_downtime_seconds": 1800,
"discounted_downtime_seconds": 0,
"unaccounted_downtime_seconds": 0,
"total_seconds": 28800,
"percentage": 0.875,
"spindle_percentage": 0.75,
"shift_type": "in_shift",
"machine_foreign_id": "CNC-01"
}
]
}

The row fields depend on the chart type:

  • Usage charts (machine_utilisation, effective_utilisation, utilisation_ranking, machine_hours, effective_hours, downtime_hours, downtime_analysis, shift_breakdown, calendar): one row per entity per bucket, as in the example above. All durations are integer seconds; percentage / spindle_percentage are 0–1 fractions.
  • Downtime reason charts (downtime_reason_hours, downtime_reason_percent, the _category_ siblings and the _horizontal variants): entity_name, bucket, duration_seconds, plus activity_reason_name or activity_reason_category_name depending on the grain. The _percent types add percentage (downtime as a 0–1 fraction of available time).
  • downtime_reason_pareto: activity_reason_name, duration_seconds, percent, cumulative_percent (both percents 0–100), ranked by duration.
  • energy: entity_name, bucket, energy_kwh.
  • idle_energy: entity_name, bucket, idle_seconds, idle_energy_kwh.
  • Part-count KPIs (total_parts, good_parts, scrap_rate): exactly one row for the whole window — entity_name, good_parts, total_parts, scrap_parts, scrap_rate (0–1, null when nothing was produced).
  • OEE KPIs (oee, oee_availability, oee_performance, oee_quality): exactly one row for the whole window. factor names the requested figure and value carries it (0–1, null when uncomputable); the row also carries all four factors plus the inputs behind them — operating_seconds, planned_seconds, ideal_run_seconds, actual_run_seconds, good_parts, total_parts, scrap_parts, quantities_confirmed.

When the request is grouped by machine, each row carries machine_foreign_id so results can be joined back to the machine_foreign_ids you filtered by. Rows never contain internal database IDs.

Error responses

  • 400 Bad Request{ "error": "compare is not supported on the charts API" } when compare / previous_from / previous_to is present.
  • 401 Unauthorized — missing, invalid, expired, or wrong-organisation API key.
  • 404 Not Found{ "error": "Chart not found" } when :chart_type is not in the supported list.
  • 422 Unprocessable Entityfrom/to unparseable or provided without the other.