MiroxMirox
  • Platform

    • Philosophy
    • Platform Overview
    • Platform Resources
    • Availability and Maintenance Windows
    • Releases and Versions
  • Mirox-Cloud

    • Cloud Overview
    • Connected Microservices
  • Mirox-Agent

    • Agent Overview
    • Deployment Options
    • Data Scraper
    • Digital Twin
  • Technical Details

    • Metric Collection
  • Information

    • Supported Plants
  • Plant Types

    • Solar Plants
    • Solar Trackers and Park Controllers
    • Wind Plants
    • Battery Storage
    • Alarm System
  • Monitoring & Visualization

    • Real-time Monitoring
    • Digital Twin
    • Component States
    • Inverter Status Codes
    • Inverter Events
    • Loss Detection
    • Power Limits & Curtailment
    • Efficiency Detection
    • KPI Dashboard
  • Data Management

    • Events
    • Alarm Levels
    • Tickets
    • Forecasts
    • Reports
    • Metrics
  • Alert Manager

    • Overview
    • Alert Rules
    • Alerts & Notifications
    • Examples
  • Integration & Sharing

    • Cooperations
    • API Tokens
    • VPN
    • VPN Address Conflicts
    • Proxy
  • AI

    • AI Assistant & Wizards
    • Agentic Access (MCP)
  • Billing

    • Market & Tariffs
    • How Revenue Is Calculated
    • Accounting & Billing
    • Contracts
  • Collaboration

    • Invitations
  • Security

    • Authentication
    • Account Lockout
    • Organization Security Policy
    • Permission System
    • Network Segmentation
    • Cooperation Restrictions
    • Access Audit Logging
    • Activity & Audit Trail
    • Data Isolation
  • Getting Started

    • Onboarding
    • Setup
  • Personal

    • Using the VPN
    • Using the Proxy
    • Two-Factor Authentication
    • Sessions
    • API Tokens
    • Notifications
    • Connect Microsoft Teams
  • Per Park

    • Contacts
    • Network Devices
    • Data Loggers
    • Generic Modbus Reader
    • Components
    • Direct VPN (per Agent)
    • Data Volume
    • History Import
  • Organization

    • Member Permissions
    • Security Policy
    • Cooperations
    • File Storage
    • VPN Services
    • Working with Reports
  • Data Export

    • Metric Export
    • Metric Export API
    • Migrating to the Metric Export
    • Legacy Export API
    • External Report Generation
    • Grafana
    • Grafana Dashboards
    • API Overview
    • MiroxQL Formulas (API)
  • Support

    • Request an Integration
  • Reporting

    • External Report Generator
    • Metric Export for Excel
  • Remote Access
  • Account Security
  • AI in Mirox
  • History Import
  • Reports
  • Data Export
  • English
  • Deutsch
  • Español
  • Français
  • Português
  • Italiano
  • English
  • Platform

    • Philosophy
    • Platform Overview
    • Platform Resources
    • Availability and Maintenance Windows
    • Releases and Versions
  • Mirox-Cloud

    • Cloud Overview
    • Connected Microservices
  • Mirox-Agent

    • Agent Overview
    • Deployment Options
    • Data Scraper
    • Digital Twin
  • Technical Details

    • Metric Collection
  • Information

    • Supported Plants
  • Plant Types

    • Solar Plants
    • Solar Trackers and Park Controllers
    • Wind Plants
    • Battery Storage
    • Alarm System
  • Monitoring & Visualization

    • Real-time Monitoring
    • Digital Twin
    • Component States
    • Inverter Status Codes
    • Inverter Events
    • Loss Detection
    • Power Limits & Curtailment
    • Efficiency Detection
    • KPI Dashboard
  • Data Management

    • Events
    • Alarm Levels
    • Tickets
    • Forecasts
    • Reports
    • Metrics
  • Alert Manager

    • Overview
    • Alert Rules
    • Alerts & Notifications
    • Examples
  • Integration & Sharing

    • Cooperations
    • API Tokens
    • VPN
    • VPN Address Conflicts
    • Proxy
  • AI

    • AI Assistant & Wizards
    • Agentic Access (MCP)
  • Billing

    • Market & Tariffs
    • How Revenue Is Calculated
    • Accounting & Billing
    • Contracts
  • Collaboration

    • Invitations
  • Security

    • Authentication
    • Account Lockout
    • Organization Security Policy
    • Permission System
    • Network Segmentation
    • Cooperation Restrictions
    • Access Audit Logging
    • Activity & Audit Trail
    • Data Isolation
  • Getting Started

    • Onboarding
    • Setup
  • Personal

    • Using the VPN
    • Using the Proxy
    • Two-Factor Authentication
    • Sessions
    • API Tokens
    • Notifications
    • Connect Microsoft Teams
  • Per Park

    • Contacts
    • Network Devices
    • Data Loggers
    • Generic Modbus Reader
    • Components
    • Direct VPN (per Agent)
    • Data Volume
    • History Import
  • Organization

    • Member Permissions
    • Security Policy
    • Cooperations
    • File Storage
    • VPN Services
    • Working with Reports
  • Data Export

    • Metric Export
    • Metric Export API
    • Migrating to the Metric Export
    • Legacy Export API
    • External Report Generation
    • Grafana
    • Grafana Dashboards
    • API Overview
    • MiroxQL Formulas (API)
  • Support

    • Request an Integration
  • Reporting

    • External Report Generator
    • Metric Export for Excel
  • Remote Access
  • Account Security
  • AI in Mirox
  • History Import
  • Reports
  • Data Export
  • English
  • Deutsch
  • Español
  • Français
  • Português
  • Italiano
  • English
  • Getting Started

    • Onboarding
    • Setup
  • Personal

    • Using the VPN
    • Using the Proxy
    • Setting Up Two-Factor Authentication
    • Managing Your Sessions
    • API Tokens
    • Notifications
    • Connect Microsoft Teams
  • Per Park

    • Managing Plant Contacts
    • Managing Network Devices
    • Configuring Data Loggers
    • Generic Modbus Reader
    • Configuring Components
    • Configuring VPN Servers per Agent (Direct VPN)
    • Data Volume per Plant
    • Importing a Plant's History
  • Organization

    • Managing Member Permissions
    • Setting Your Organization's Security Policy
    • Creating Cooperations
    • Using File Storage
    • Organization VPN Services
    • Working with Reports
  • Data Export

    • Metric Export
    • Metric Export API
    • Migrating to the Metric Export
    • Legacy Export API
    • External Report Generation
    • Using Grafana as an External Read Platform
    • Building Your Own Grafana Dashboards
    • API Overview
    • MiroxQL Formulas (API Reference)
  • Support

    • Request an Integration

Metric Export API

The Metric Export API delivers any metric of your plants as a time series, as CSV or JSON, with one GET request. It reads the same metric collection as the reports, including the metrics your organization defined itself.

Every link the Data Export page shows is a call of this API, so the easiest way to a working request is to build it there and copy it.

Open in Mirox

Data Export ▸ Metrics for a free selection, Data Export ▸ API builder for a template. Both show the link of what you selected.

The export links of the previous export keep working unchanged. They are described in the Legacy Export API; how to move from one to the other is in the migration guide.

Routes

All paths follow https://service.mirox.io/api.

RouteAnswerPurpose
GET /v1/export/seriesCSV, or JSON with format=jsonExport metrics as a time series
GET /v1/export/series/estimateJSONSize and duration of an export, without reading data
GET /v1/export/series/catalogJSON, or a CSV glossary with format=csvThe metrics you can export
GET /v1/export/series/lanesJSONThe components of one plant
GET /v1/export/series/template/{template_uid}CSV, or JSON with format=jsonExport a template
POST /v1/export/template/{template_uid}/convertJSONConvert a legacy template

Authentication

Send an API token of the group Metric Export in the Authorization header:

Authorization: Bearer YOUR_API_TOKEN

The token reads every export route on this page and the legacy routes. It cannot create, change or delete anything. In a browser where you are logged in to Mirox, the links work without a token.

You only receive data of the plants whose measurements you may read. The metrics of your organization are exported by every organization role except External. See Who can export what.

Metrics Are Selected by Id; a Query Is Scoped to the Plant

An export names metrics by their id. Mirox resolves each id to its own query, scoped to the plant. The metrics of your organization are validated entries of the collection that are scoped to the plant in the same way. The only query text a caller can send is a MetricsQL expression in expr: it is run on the plants of the request only, with the plant added to every selector, and it is refused when it names a plant, a park or an organization itself.

Exporting a Time Series

GET /v1/export/series

Grid feed-in of one plant over the previous month, per day:

curl --compressed "https://service.mirox.io/api/v1/export/series?park=ABC123DEF456&metrics=plant.grid_feedin&window=previous_month&step=day" \
  -H "Authorization: Bearer YOUR_API_TOKEN" -o feedin.csv
Date;Grid feed-in (kWh)
2026-08-01;5321,4
2026-08-02;4980,2
...

Parameters

ParameterValuesDefaultMeaning
metrics1 to 20 metric ids, comma-separatedrequired unless expr is givenThe columns, in this order. See Metrics and values.
expra MetricsQL expression, repeatable up to 5 times—Raw queries of the time-series store, one set of columns each, after the metrics. See Raw MetricsQL queries.
parkplant UIDs, comma-separated—The plants. park or portfolio is required.
portfolioportfolio UIDs, comma-separated—All plants of these portfolios, in addition to park. At most 50 plants in total.
start, enddate or date with time—A free time range. See Time range.
year, quarter, month, week, daynumbers—A calendar range.
windowpresetprevious_monthA named range.
stepauto, 1min, 5min, 15min, 1h, day, week, month, quarter, yearautoThe length of one row. See Steps.
mismatchrefuse, sparserefuseWhat happens to a metric that does not serve the step: refuse the request, or export it at its own step. See Metrics with different steps.
valuesauto, delta, cumulative, nativeautoThe value mode of all metrics.
tzlocal, utclocalThe calendar of the rows. See Time grid.
multi_park_aggmerge, splitmergeSeveral plants combined, or one column per plant. See Several plants.
componentsup to 100 component references, comma-separatedallRestricts component metrics to these components. See Components.
lane_limit1 to 10050Components per metric and page.
lane_page1 and up1The page of components.
formatcsv, jsoncsvThe format of the answer.
languageen, de, es, fr, it, ptenThe language of the column names.
separator_csv, ; tab |;The column separator.
separator_decimal. ,,The decimal separator. It must differ from separator_csv.
datetime_formatstrftime pattern, up to 64 charactersper stepThe format of the time column.
headername, idnameColumn headers as names or as ids. See CSV answer.
emptyblank, zeroblankA missing value as an empty cell or as 0.
offset_columntrue, falsetrueThe column UTC offset. It appears only at steps shorter than a day in plant local time.
precisiondisplay, fulldisplayValues rounded to the digits of the metric, or unrounded.

lane_limit and lane_page outside their bounds are set to the nearest bound. A parameter the route does not know is ignored.

Metrics and Values

A metric id has the form <prefix>.<name>, for example plant.grid_feedin, inverter.ac_power or sensor.irradiance. A metric of your organization is organization.<id of the metric>. The catalog lists all of them.

Each metric has a quantity, which decides the value modes it offers:

valuesA row showsApplies to
deltathe amount within the intervalenergy only
cumulativethe running total since the start of the rangeenergy and other counted quantities
nativethe value as the metric delivers itevery metric
autodelta for energy, native for everything else

A suffix sets the mode of one metric and wins over values:

metrics=plant.grid_feedin:cumulative,plant.grid_power

A mode that does not apply to a metric is never an error. The metric is exported as native, and the note value_mode_ignored says so. delta is never applied to a power.

The same metric in two modes gives two columns. The same metric in the same mode twice gives one.

Energy Per Interval Below 15 Minutes

A meter counts energy in whole steps. At 1min or 5min, an energy in mode delta therefore jumps between zero and one step. The export delivers it and adds the note energy_delta_fine_step, which names the matching power metric where the collection has one. For a curve use the power metric; for energy use 15min or longer.

Time Range

Give the range in one of three ways. Two ways in one request answer 400 window_conflict.

WayParametersExample
Free rangestart, endstart=2026-07-01&end=2026-07-31
Calendaryear with quarter, month, week or dayyear=2026&quarter=2
Presetwindowwindow=previous_week

Free range. start and end are a date (2026-07-01) or a date with time (2026-07-01T06:00, 2026-07-01T06:00:00Z, 2026-07-01T06:00:00+02:00). A value without a time zone is read in the time zone of the rows. An end that is a date includes that day; an end with a time is the moment the range ends. Without end, the range ends now. end alone, without start, is refused.

Calendar. year from 2020 to 2100, quarter 1 to 4, month 1 to 12, week 1 to 53 (ISO week), day 1 to 31. day needs month. Without year, the current year is meant. day wins over week, week over month, month over quarter.

Presets. today, yesterday, last_7_days, last_30_days, this_week, previous_week, this_month, previous_month, this_quarter, previous_quarter, this_year, previous_year. The this_ presets run up to now; last_7_days and last_30_days roll up to now at steps below a day (the same clock time 7 or 30 days back); at day and coarser they are the last 7 or 30 local days including today. At day and coarser every window is widened to whole days (weeks, months …) in the plant's time zone, and the response echoes the effective window.

A range starts in 2020 at the earliest and spans at most 1827 days (five years). A range that reaches into the future ends now, with the note end_clamped.

Steps

step=auto chooses a step that every requested metric serves and that fits the limits: 15min for up to two days, 1h for up to 62 days, day for up to three years, month beyond. If that step does not fit, the next coarser one is tried, then the finer ones. The note step_auto and the header X-Mirox-Step name the step that was chosen.

Each metric offers its own steps. The catalog lists them as export_steps:

Kind of metricSteps
Energy from a meter that counts every minute1min to year
Energy counted less often — wind turbines, settled curtailment15min to year
Power (W, var, VA, W/m²), voltage, current, frequency1min, 5min, 15min
Temperature, state of charge and other measured levelsfrom the measuring interval to year
Operating states and status codes15min
Performance ratioday, week, month, quarter, year
Availability15min, 1h, day, week, month, quarter, year
Metrics of your organizationfrom their finest resolution to year, never finer than 15min

Power is offered at 15 minutes or finer only. A daily or monthly power is an average that hides what happened; the energy metric gives the figure that is meant.

A step is never changed silently. With mismatch=refuse, the default, a step that one of the metrics does not serve answers 400 step_not_served with the steps of every metric, and with step=auto, metrics that share no step answer 400 no_common_step. With mismatch=sparse, such a request is delivered instead — see Metrics with different steps.

Steps of a day or longer cover whole intervals. A range that starts or ends inside one is widened outward, with the note window_aligned. Weeks start on Monday.

Metrics With Different Steps

mismatch=sparse delivers a request whose metrics do not all serve the step, as long as each of them serves some step. The grid of the file is the requested step; with step=auto it is the step that most metrics serve as is, chosen by the range and the limits as usual. Column positions and the shape of the CSV and JSON answer do not change.

The metric servesWhat the export doesNote
only finer stepsReads it at the coarsest of them and folds it up to the grid by the rule of its quantity: an energy is added, a reading averaged, a ratio recomputed from its halves, a state keeps its latest code.step_folded with the read step
only coarser stepsReads it at the finest of them and writes each value on the row its own interval starts on — a day's figure on the row of its local midnight, a month's on the row of its first day. The rows between stay empty.step_sparse with that step
a coarser step, but none of its intervals starts on a rowThe column is empty, for example a daily figure on a file that starts at 06:00.metric_unavailable with reason off_grid

Two cases are refused in both modes, with 400 step_not_served: a figure per month, quarter or year on a week file, because its first day is hardly ever a Monday; and a monthly figure such as the Marktwert on a quarter or year file, because a sum or a mean of months is not that figure. On a month file it is read as is, on a finer file it is sparse.

The estimate lists the same notes, counts the reads at each metric's own step, and marks a step in per_step as within budget even when not every metric serves it. The Data Export page always asks with mismatch=sparse; a template carries its own mismatch in its spec.

Time Grid

With tz=local, rows follow the local time of the plant, including daylight saving time: a day is a local day of 23, 24 or 25 hours, a month is a local month. With tz=utc, rows follow the UTC calendar.

  • At steps shorter than a day in local time, the column UTC offset follows the time column (+02:00). On the day the clocks go back, one hour appears twice; the offset tells the two apart. offset_column=false leaves the column out.
  • Plants in different time zones share one time column. Such a request is answered on the UTC calendar, with the note merged_on_utc, whether the plants are combined or split.
  • With tz=utc and a step of a day or longer, a metric that exists per local day only has no UTC value. Its column stays empty, with the note utc_calendar_unsupported.

The header X-Mirox-Grid names the calendar that was used: local:Europe/Berlin or utc.

Several Plants

With multi_park_agg=merge, every metric is one column for all plants, combined by the rule of the metric. The catalog lists the rule as merge:

mergeCombined valueMetrics
sumadded over the plantsenergy, counted quantities, power
meanaveraged over the plantsirradiance, temperature, state of charge and other levels
pair_ratiorecomputed from the plants' totalsperformance ratio, availability and other ratios
firstthe shared valueprices, when all plants lie in one market zone
split_onlycannot be combinedstates and status codes

A metric that cannot be combined is exported per plant, with the note merge_not_meaningful. This also holds for a ratio at a step at which its two halves are not available, and for prices of plants in different market zones.

With multi_park_agg=split, every metric is one column per plant. With a single plant, both give the same file.

Component metrics are always per plant (note components_split_by_park).

Components

A metric of a component level gives one column per component. The levels are inverter, gak (combiner box), string, turbine, sensor, meter, battery_box (container), battery_storage (rack), battery_module, battery_cell and battery_pcs (power converter).

Without components, the export carries all visible components of the plants, lane_limit per metric and page. If there are more, the note lanes_truncated names the total; request the next page with lane_page.

components restricts the export to the components you name. A reference has the form <level>:<id>, for example inverter:1043. A sensor or meter that Mirox measures but that has no entry in the plant's components has a reference of the form sensor:h3f9c2a71b04e6d5. The components route lists the references of a plant. A reference that belongs to none of the selected plants answers 400 unknown_lane.

metrics=inverter.ac_power&components=inverter:1043,inverter:1044

Raw MetricsQL Queries

expr adds a raw query in MetricsQL, the query language of the platform's time-series store, to an export — for a series the collection has no metric for. The parameter can be repeated up to five times; each expression may have up to 4 000 characters. A request may carry expr alone, or metrics and expr together; the metric columns come first.

expr=sum by (inverter_id) (powerplant_inverter_power_ac)&park=ABC123DEF456&window=yesterday&step=15min

An expression is evaluated per plant, as a dashboard evaluates it: on the plant's own data, at the requested step, as raw samples — every step is allowed, values and the folding rules of the metrics do not apply. Mirox adds the plant to every selector of the expression; an expression that names a park, organization or plant label itself is refused with 400 expr_forbidden_label.

Caseheader=nameheader=id
One series per plantMetricsQL sum by (inverter_id) (powerplant_inverter_power_ac)expr1
Several series on any plantthe heading followed by each series' own name{labels}expr1{inverter_id="INV1"}
Several plantsthe plant name in front, as for any columnABC123DEF456/expr1

When an expression answers several series on any of its plants, every plant's columns of that expression carry the series labels, so a file has one naming per expression. A heading longer than 1 000 characters is cut with … inside the expression, never in the series text. In the JSON answer, columns[].key is the header=id text and columns[].metric is the expression's id, expr.e1, expr.e2, …, which the notes and refusals use. A plant on which the expression answers nothing keeps one empty column, with the note expr_no_series; with several plants, every plant gets its own columns, with the note expr_split_by_park.

An expression may answer at most 500 series on one plant (400 expr_too_many_series); aggregate it, with sum by (…) for example. The series count against the same 400 columns and 1 800 000 values as every export: the first read of each expression on each plant is a short probe, the widths are summed over the whole request, and a request that outgrows the limits is refused with 400 over_budget and params.series before any full read of any expression. An expression that does not parse, is empty, is too long, or that the store refuses answers 400 expr_invalid with the reason.

The estimate counts an expression as one column per plant, because its series are only known once it is read. Expressions are not stored in templates.

CSV Answer

The answer is UTF-8, with the file name series_export_<first day>_<last day>_<step>.csv. An answer larger than about 1 MB is compressed when the request carries Accept-Encoding: gzip (curl: --compressed).

The columns are, in this order: the time, the UTC offset where it applies, then the metrics in the order of metrics.

Caseheader=nameheader=id
TimeDatetimestamp
UTC offsetUTC offsetutc_offset
One plant, or plants combinedGrid feed-in (kWh)plant.grid_feedin
Plants splitSunnyside - Grid feed-in (kWh)ABC123DEF456/plant.grid_feedin
ComponentWR 01.01 - AC power per inverter (W)ABC123DEF456/inverter:1043/inverter.ac_power
Component, several plantsSunnyside - WR 01.01 - AC power per inverter (W)ABC123DEF456/inverter:1043/inverter.ac_power
Metric with variants, such as three phasesthe name followed by the variantthe id followed by #<variant>
One metric in two value modesthe same name twiceplant.grid_feedin:delta, plant.grid_feedin:cumulative
Raw MetricsQL queryMetricsQL <expression>, followed by the series labels where there are severalexpr1, expr1{inverter_id="INV1"} — see Raw MetricsQL queries

Use header=id in Scripts and Workbooks

Names are made for people: they follow language and change when a metric is renamed. Ids are stable. A script or a workbook that finds its columns by header should request header=id. In a template you can also give each column a header text of your own.

The time column is formatted per step unless datetime_format is given:

StepFormatExample
1min, 5min, 15min, 1h%Y-%m-%d %H:%M2026-08-01 06:15
day, week%Y-%m-%d2026-08-01
month, quarter, year%Y-%m2026-08

Every row is stamped with the start of its interval. A missing value is an empty cell, so "no data" and "zero" can be told apart; empty=zero writes 0 instead.

Four headers of the answer repeat what was resolved:

HeaderContentExample
X-Mirox-Stepthe stepday
X-Mirox-Gridthe calendarlocal:Europe/Berlin
X-Mirox-Windowstart and end of the exported range2026-08-01T00:00:00+02:00/2026-09-01T00:00:00+02:00
X-Mirox-Notesthe notes, separated by ;step_auto:step=day

JSON Answer

format=json answers the same table as structured data:

FieldContent
windowstart, end, grid, tz_name, step, and aligned when the range was widened
parksthe exported plants with uid, name and timezone
bucketsthe rows: start as a time with offset, ts as Unix seconds
columnsone entry per column: key (the header=id text), metric, name, unit, digits, quantity, values_mode, merge, park_uid, lane (ref, level, title), variant, and values in the order of buckets; a missing value is null
notesthe notes with code, metric and params
lanes_totalcomponents per component metric, before paging
lane_page, lane_limitthe page that was delivered
totalsvalues, queries and duration_ms of the export

Notes

A note tells you what Mirox did on its own. It never fails an export. Notes are part of the JSON answer and of the header X-Mirox-Notes. The header holds up to 1 KB of notes, written as code:key=value,key=value and separated by ;. If not all of them fit, the header ends with notes_omitted:count=<n>; the JSON answer holds all of them.

NoteMeaning
parks_droppedPlants you named but cannot read were left out. uids names them.
grant_requiredA money metric stays empty for a plant on which you lack the accounting permission.
value_mode_ignoredThe requested value mode does not apply to the metric; it was exported as native.
energy_delta_fine_stepAn energy per interval at a step below 15 minutes shows meter steps. twin names the matching power metric.
legacy_id_mappedAn id of the previous export was translated. from, to and exactness say how.
merge_not_meaningfulThe metric cannot be combined over plants and is shown per plant.
components_split_by_parkComponent metrics are shown per plant.
merged_on_utcThe plants lie in different time zones; the rows are in UTC.
utc_calendar_unsupportedThe metric has no value on the UTC calendar; its column is empty.
window_alignedThe range was widened to whole intervals. start and end give the result.
end_clampedThe range reached into the future and ends now.
step_autoThe step that auto chose.
step_foldedWith mismatch=sparse: the metric was read at a finer step and folded up to the grid.
step_sparseWith mismatch=sparse: the metric has one value per step, on the first row of each of its intervals.
lanes_truncatedThe metric has more components than the page holds. total, page and limit say where you are.
lanes_unpagedMeasured series without an entry in the plant's components were exported as measured.
metric_unavailableThe metric has no values for a plant; the column is empty. reason is planned, not_applicable, no_data_source, draft, deleted, unknown_lane, off_grid or, in a template, not_permitted.
expr_no_seriesA raw query answered no series on a plant; its column is empty.
expr_split_by_parkRaw queries are read per plant and get one set of columns per plant.
provider_noteA remark of the metric itself, for example which source answered.

An empty column is always kept. A metric that does not apply to one of the plants, or a money metric without the accounting permission, leaves its column in place, so the positions of the other columns never move.

Estimating Before Exporting

GET /v1/export/series/estimate

The route takes the parameters of the export, without the file format, and answers what the export would be — without reading data and without counting against the hourly allowance.

FieldContent
step, grid, windowwhat the request resolves to
parks, columns, rows, values, queriesthe size
bytes_csv, seconds_estimateapproximate file size and duration
within_budgetwhether the export would be delivered
preview_okwhether it is small enough for the preview in the app (200 000 values)
limitsthe limits in force
per_stepfor every step: served_by_all, values, within_budget, and the reason if not
refusalsevery error the export would answer, with code, params and hint
notesthe notes the export would carry

A refusal never fails the estimate: it answers 200 and lists the refusal. The estimate counts, it renders nothing: the row labels and headings are the export's. A raw query counts as one column per plant, and with mismatch=sparse the notes name the folded and sparse columns.

The Metric Catalog

GET /v1/export/series/catalog
ParameterValuesDefaultMeaning
park, portfolioUIDs—The plants the metrics are judged against. Without plants, the whole collection is listed.
languageen, de, es, fr, it, ptenThe language of names and descriptions.
levela levelallOne level only.
quantityenergy, amount, rate, level, ratio, state, priceallOne quantity only.
searchtext, up to 100 characters—Searches name, description, unit, id and the ids of the previous export.
include_unavailabletrue, falsetrueAlso lists metrics that cannot be exported for the selected plants.
page, limitnumbers, limit up to 1001, 100Paging.
sortorder, name, id, level, with - in front for descendingorderThe order of the list.
formatjson, csvjsoncsv answers the glossary.

Each metric carries, next to its id, name, description, unit and level:

FieldContent
quantitywhat the number is: energy, amount (another counted quantity), rate (power), level, ratio, state or price
value_modes, default_value_modethe value modes it offers, and the one auto chooses
export_stepsthe steps it offers
native_step_secondshow often it is measured
mergehow several plants are combined
twin_item_idfor an energy metric, its power metric
lane_levelfor a component metric, the level of its components
legacy_idsthe ids of the previous export it answers for
applies_parkson how many of the selected plants it applies
exportable, export_reasonwhether it can be exported, and if not why: draft, planned, grant_required, not_applicable or no_source

For up to 10 plants, each plant is checked for the equipment a metric needs. Above that, plants are judged by their type only; what a single plant lacks shows at export time as a note metric_unavailable.

Glossary. format=csv answers the whole filtered list as a file, metric_catalog_<language>.csv, with the columns id, level, name, unit, description, quantity, value modes, steps, measuring interval, combination over plants, note and previous ids. page and limit do not apply.

curl "https://service.mirox.io/api/v1/export/series/catalog?format=csv&language=en" \
  -H "Authorization: Bearer YOUR_API_TOKEN" -o metric_catalog_en.csv

Available Metrics

The collection is ordered by level. The prefix of an id tells where a metric belongs.

LevellevelId prefixWhat it holds
Plant · measuredplantplant.What the plant itself measures: the grid meter, the inverter sums, the site sensors, the power limits it was told to hold.
Plant · referenceplant_referenceplant.What the plant should have done: irradiation in the plane of the modules, expected production, performance ratio, specific yield, losses.
Plant · compensationplant_compensationplant.Curtailment and shutdown losses as energy and power, per recipient and method.
Metricsmetricsavailability., organization.Availability figures, sun hours, and the metrics of your organization.
Inverterinverterinverter.One column per inverter.
Combiner boxgakgak.One column per combiner box.
Stringstringstring.One column per string.
Batterybatterybattery.The storage as a whole: energy, power, state of charge, setpoints.
Battery containerbattery_boxbattery_box.One column per container.
Battery rackbattery_storagebattery_storage.One column per rack.
Battery modulebattery_modulebattery_module.One column per module.
Battery cellbattery_cellbattery_cell.One column per cell or measuring point.
Battery converter (PCS)battery_pcsbattery_pcs.One column per power converter.
Wind turbineturbineturbine.One column per turbine.
Sensorsensorsensor.One column per sensor: irradiance, irradiation, temperature, humidity, wind.
Metermetermeter.One column per energy meter.
Infrastructureinfrastructureinfrastructure.The data path and the site: completeness, logger health, network, alarms, control connections.
Weatherweatherweather.Weather at the site, including wind and temperature at 80, 120 and 180 m.
Marketmarketmarket.Prices and market values.
Plant financialfinancialfinancial.Money values of the plant. They need the accounting permission.

The complete list with names, units and descriptions in your language is the catalog, the glossary file, or Explanations on the Metrics tab. The weather forecast values of the previous export are not part of the collection; see the migration guide.

Components of a Plant

GET /v1/export/series/lanes
ParameterValuesDefaultMeaning
parkone plant UIDrequiredThe plant.
levela component levelrequiredSee Components.
metrica metric id—For sensors and meters: lists the ones that delivered this metric in the last 30 days.
searchtext—Searches the names.
include_hiddentrue, falsefalseAlso lists hidden components.
page, limitnumbers, limit up to 1001, 50Paging.
sortorder, name, with - in front for descendingorderorder is the order of the columns in the export.

Each entry has the reference ref for the parameter components, the name, the level, the parent (parent_ref, parent_name — the inverter of a string, for example), attributes (role of a meter, position of an irradiance sensor, vendor), hidden, and source: db for an entry of the plant's components, store for a series that is measured but has no such entry.

A plant that does not exist and a plant you cannot read both answer 404 park_not_found.

Template System

A template is a saved list of metrics with defaults for step, time range, values, time zone, combination of plants, component page size and column headers. What templates are for, and how to manage them in the app, is in the Metric Export guide.

Exporting a Template

GET /v1/export/series/template/{template_uid}

The route takes the parameters of the export except metrics, components and values, which the template fixes. Every parameter you leave out takes the template's default; every parameter you give wins over it.

curl --compressed "https://service.mirox.io/api/v1/export/series/template/CAFE1000CAFE?park=ABC123DEF456&window=previous_month&header=id" \
  -H "Authorization: Bearer YOUR_API_TOKEN" -o standard.csv
  • A template of another organization answers 404 template_not_found.
  • A legacy template answers 400 template_is_legacy; params.legacy_url is the link that exports it.
  • A column whose metric is no longer available is exported empty under its header, with the note metric_unavailable. The same holds for a metric of your organization when you export as External (reason not_permitted).

System Templates

TemplateUIDStepTime range
Standard ExportCAFE1000CAFEdayprevious_month
Extended ExportCAFE1001CAFEdayprevious_month
Extended Export (inverter availability)CAFE1002CAFEdayprevious_month
Energy Availability ExportCAFE1003CAFEdayprevious_month
Report TechnicalABCD12340002dayprevious_month
Wind TurbinesCAFE1010CAFEdayprevious_month
Battery StorageCAFE1020CAFEdayprevious_month
Irradiance SensorsCAFE1030CAFE15minyesterday

The first five succeed CAFE0000CAFE, CAFE0001CAFE, CAFE0002CAFE, CAFE0003CAFE and ABCD12340001, which keep working on the legacy route. Their columns are listed in the migration guide. They offer the steps day, week, month, quarter and year; the first four also offer 15min and 1h.

Managing Templates

Templates are listed, read, created, changed and deleted under /v1/export/template. Reading works with a Metric Export token. Writing needs the organization role Admin, Moderator, Asset Manager (Technical) or Asset Manager (Commercial) and a login or a Full Access token.

RequestPurpose
GET /v1/export/templateList templates. view=current lists the system templates of this page and your organization's templates; view=legacy, the default, lists the stored templates as before; view=all lists both. kind=series or kind=legacy filters.
GET /v1/export/template/{template_uid}Read one template.
POST /v1/export/templateCreate a template with kind=series and the content in spec. Without kind, the request creates a legacy template from metric_ids, as before.
PUT /v1/export/template/{template_uid}Change name, description or spec. The kind cannot change.
DELETE /v1/export/template/{template_uid}Delete a template. System templates cannot be changed or deleted.

The spec of a template:

FieldValuesDefault
items1 to 40 entries, each with metric, optionally values and labelrequired
stepa stepauto
valuesa value modeauto
tzlocal, utclocal
windowa presetprevious_month
multi_park_aggmerge, splitmerge
lane_limit1 to 10050
headername, idname
mismatchrefuse, sparserefuse

label is the header text of the column with header=name. A metric may appear once, and a template holds no raw queries. When a template is saved, every metric must be exportable, and the metrics must share a step — under mismatch=sparse, each must serve some step; otherwise the answer is 422 spec_invalid and params.problems names the metric and the reason. A template runs with its own mismatch (the app shows it as Metrics of another step: Strict or Lenient); the parameter on the export link wins over it.

Converting a Legacy Template

POST /v1/export/template/{template_uid}/convert
FieldValuesMeaning
nameup to 100 charactersThe name of the new template. Default: the name of the legacy template followed by "(new)".
dry_runtrue, falsetrue answers the mapping without creating anything.

The answer lists mapped (legacy_id, metric, values, exactness: exact or approximate) and unmapped (legacy_id, reason: formula, no_equivalent, report_value or instant, and up to three suggestions), and, unless it was a dry run, the new template. A dry run answers 200, a conversion 201.

The new template exports days over the previous month. The legacy template is never changed. Two legacy columns that read the same meter become one column. 422 nothing_to_convert means that no column has a counterpart, or that the template is not a legacy template.

Limits

An export is answered within one request, so its size is bounded. Every limit is checked before data is read; a request that is too large is refused at once and tells you what would fit.

LimitValue
Metrics per request20; in a template 40
Raw MetricsQL queries per request5, of 4 000 characters each, with at most 500 series per plant
Plants per request50
Components per metric and page50 by default, at most 100
Columns400
Values per column180 000 — 125 days at 1min, 625 days at 5min, five years at 15min
Values in total1 800 000 (rows × columns)
Time range1827 days
Reads of the measurement store per request1 500
Duration50 seconds
Exports per user and hour240
Exports running at the same time3 per organization

Splitting a Large Export

400 over_budget names in params what was needed and what is allowed, and in hint the way out: step, the next coarser step that fits, and max_days, the longest range that fits at the requested step. Ask the estimate first if you build requests in a script; its per_step lists the size for every step.

If neither a coarser step nor a shorter range is what you want, split the export:

Split byHow
TimeOne request per month or quarter. Use the calendar parameters (year=2026&month=7) and join the files.
PlantOne request per plant or portfolio.
MetricComponent metrics in requests of their own. One component metric on a plant with 200 inverters is 200 columns.
Pagelane_page=1, 2, … for the components of one metric.

Some metrics are worked out from several sources for every day, above all plant.production_reported (Production, resolved). They need many more reads of the measurement store than a meter reading, at every step. A request or a template that carries such a metric reaches about nine plant-months at present: one plant over nine months, or nine plants over one month. A step of a week or longer widens the range to whole intervals, and the widened range counts. Split such exports by time or by plant, or export the metric in a request of its own.

429 busy and 429 rate_limited carry the header Retry-After with the seconds to wait.

Errors

An error of the routes on this page has this form:

{
  "detail": {
    "code": "step_not_served",
    "message": "The step is not served by every requested metric.",
    "params": {"step": "1h", "metrics": {"plant.grid_power": ["1min", "5min", "15min"]}},
    "hint": {"offered_common": ["1min", "5min", "15min"]}
  }
}

code is stable and meant for programs. message is an English text for people. params says what was wrong, hint what would work.

StatuscodeMeaningparams and hint
400scope_requiredNeither park nor portfolio was given.hint.example
400unknown_metricA metric id does not exist.params.ids; hint.suggestions with similar ids
400legacy_metric_idAn id of the previous export has no counterpart in the collection.params.id, params.legacy_url; hint.reason, hint.closest, hint.pending, hint.legacy_url
400metric_not_exportableThe metric exists but is not a time series you can export.params.id, params.reason: draft, planned, no_source, events or master
400window_conflictThe range was given in more than one way.params.families
400window_invalidThe range is not valid.params.reason: end_before_start, start_in_future, before_2020, too_long, day_requires_month, start_required or invalid_date
400step_not_servedA metric does not offer the requested step.params.metrics with the steps of every metric; hint.offered_common
400no_common_stepThe metrics share no step.params.metrics; hint.split
400over_budgetThe export is larger than a limit.params.values, limit, queries, query_limit, columns, column_limit, parks; with more than 50 plants params.parks and park_limit; for a raw query params.series; hint.step, hint.max_days, hint.lane_limit, hint.reduce
400unknown_laneA component reference belongs to none of the plants.params.refs
400expr_invalidA raw query cannot be run.params.expr, params.reason: empty, syntax (with detail), too_long, too_large, store (with the store's detail) or parser_unavailable
400expr_forbidden_labelA raw query names a plant, park or organization itself.params.expr, params.labels
400expr_too_many_seriesA raw query answers more than 500 series on one plant.params.expr, params.park, params.series, params.limit; hint.reduce
400separator_conflictColumn separator and decimal separator are the same.—
400invalid_datetime_formatdatetime_format is not a valid pattern.hint.example
400template_is_legacyThe template is a legacy template.params.legacy_url
403no_accessible_parksYou cannot read any of the selected plants.—
403metric_forbiddenA metric of your organization was requested with the organization role External.params.ids
404template_not_found, park_not_foundThe template or the plant does not exist, or you cannot read it.—
409name_conflictA template with this name exists.params.name
422—A parameter has a value outside its list, or metrics holds more than 20 ids.the field and the reason
422spec_invalid, use_spec, nothing_to_convertA template cannot be saved or converted as sent.params.problems
429busyToo many exports are running.header Retry-After
429rate_limitedThe hourly allowance is used up.header Retry-After
502store_errorThe measurement store answered with an error. Nothing was exported; a value is never replaced by zero.params.metric
503store_timeoutThe measurement store did not answer in time.hint.step with a coarser step

401 means that the token is missing, expired or revoked.

Ids of the Previous Export

The parameter metrics also accepts the ids of the previous export, such as energy_grid_daily or raw_grid_power. An id with a counterpart is translated to its metric, in the value mode that comes closest to the previous number, and the note legacy_id_mapped says which metric answered and whether the number is the same (exact) or the same quantity read in a better way (approximate).

An id without a counterpart answers 400 legacy_metric_id. hint.reason says why, hint.closest names the nearest metric where there is one, hint.pending names the metric that is planned to carry it, and legacy_url is the link of the previous export that still delivers the id. With more plants than a link can name, legacy_url names the first plant and params.legacy_url_scope is first. A component id of a battery level has no link of the previous export; hint.legacy_route is none then. The migration guide lists every id.

Excel and Scripts

  • Metric Export for Excel — recipes, and the Power Query connection with the Authorization header
  • External Report Generator — a complete Python example

Related Features

  • Metric Export — the Data Export page
  • Migrating to the Metric Export — old ids, new metrics and what changes
  • Legacy Export API — the previous export links
  • Metrics — define metrics of your own and export them
  • API Tokens — create the Metric Export token
  • API Overview — the interactive reference of all routes
Prev
Metric Export
Next
Migrating to the Metric Export
© 2026 Mirox Verwaltungs GmbH. All rights reserved. | Privacy Policy