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
  • Reporting

    • External Report Generator
    • Metric Export for Excel

External Report Generator

This example pulls the data of one plant from Mirox and builds a report of its own from it: first the three requests with curl, then a complete Python report generator that turns them into a PDF file.

Looking for Spreadsheet Work Instead?

For Excel — production curves, several plants side by side, single inverters, sensors, turbines — see Metric Export for Excel.

Prerequisites

  1. A Mirox account that may read the plant.
  2. The UID of the plant — the unique identifier of the plant resource you want to report on.
  3. An API token of the group Metric Export — see API Token Usage.

The Three Requests

DataRequestAnswer
Plant informationGET /v1/export/report/{park_uid}/infoJSON
EventsGET /v1/export/report/{park_uid}/events.csvCSV
Production figuresGET /v1/export/series/template/{template_uid}CSV, or JSON with format=json

All paths follow https://service.mirox.io/api. The parameters of the third request are described in the Metric Export API, the first two in the Legacy Export API.

Example 1: Plant Information

curl "https://service.mirox.io/api/v1/export/report/ABC123DEF456/info" \
  -H "Authorization: Bearer YOUR_API_TOKEN"
{
  "uid": "ABC123DEF456",
  "name": "Sunnyside Solar Park",
  "type": "solar",
  "description": "Sunnyside Solar Park is a 42 MW photovoltaic installation...",
  "latitude": 48.7511,
  "longitude": 9.1225,
  "timezone": "Europe/Berlin",
  "peak_production_w": 42000000,
  "active": true,
  "created_at": "2024-05-16T10:30:25.104830Z",
  "portfolio": {
    "uid": "GHI789JKL012",
    "name": "Renewable South"
  },
  "organization": {
    "uid": "MNO345PQR678",
    "name": "GreenPower Inc."
  },
  "address": {
    "address1": "123 Solar Way",
    "zip_code": "70123",
    "city": "Sunnyville",
    "country": "Germany"
  }
}

Example 2: Events

curl "https://service.mirox.io/api/v1/export/report/ABC123DEF456/events.csv?year=2026&quarter=1&separator_csv=,&separator_decimal=." \
  -H "Authorization: Bearer YOUR_API_TOKEN"
Event ID,Start Date,End Date,Duration (hours),Type,Creator,Description,Priority
9876543210123456789,2026-01-15 08:45,Ongoing,720.25,Sensor Error,System,Irradiation sensor malfunction detected,1200
8765432101234567890,2026-02-10 14:30,2026-02-15 09:15,114.75,Data Availability,System,Connection issues with data acquisition system,1100
  • year, quarter and month select the period. Without them, the export covers the current year.
  • Without the two separator parameters, the columns are separated by ; and the decimal mark is ,.
  • The end date of an event that is still open is Ongoing.

Filter Events by Priority

A Priority of 1000 or more marks an important event, such as a shutdown that costs production or an alarm. Lower values are informative, such as a connection that came back.

Example 3: Monthly Production Figures

The system template Report Technical (ABCD12340002) for the first quarter, per month, with ids as column headers:

curl --compressed "https://service.mirox.io/api/v1/export/series/template/ABCD12340002?park=ABC123DEF456&year=2026&quarter=1&step=month&header=id&separator_csv=,&separator_decimal=." \
  -H "Authorization: Bearer YOUR_API_TOKEN"
timestamp,plant.grid_feedin,plant.rad_pyranometer,plant.rad_weather,availability.sunhours,availability.inverter_park,plant.shutdown_grid,plant.shutdown_external,plant.expected_weather,plant.expected_pyranometer,plant.pr_weather,plant.pr_pyranometer,plant.specific_yield
2026-01,950000.4,18.4,18.1,62.5,99.1,15000.5,25000.8,980000.0,975000.0,81.2,82.0,22.6
2026-02,1250000.3,22.8,22.5,96.0,99.4,2000.3,18500.4,1300000.0,1290000.0,81.0,81.6,29.8
2026-03,1850000.8,35.4,35.0,148.3,98.9,45000.2,30000.7,1900000.0,1885000.0,80.7,81.3,44.0
  • header=id gives column headers that never change. With header=name, the default, the headers are the names of the metrics in the language you ask for, such as Grid feed-in (kWh).
  • An empty cell means that there is no value. It does not mean zero.
  • Several plants or a whole portfolio go into one request: park=ABC123DEF456,DEF456ABC123 or portfolio=<uid>, with multi_park_agg=split for one column per plant.
  • The columns of the template are listed in the migration guide.

Many Plants Over a Long Range

One plant over a whole year fits into one request, and so do 25 plants. A request that is too large answers 400 over_budget and names the longest range that fits. Request one quarter at a time then, or one portfolio at a time, and join the files. See Splitting a large export.

The Previous Template

Reports built on the previous template Report Technical v1 keep working. Its link and its columns are unchanged:

curl "https://service.mirox.io/api/v1/export/metrics/template/ABCD12340001?park=ABC123DEF456&resolution=monthly" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

What differs in the successor ABCD12340002:

ABCD12340001 (legacy)ABCD12340002
Link/v1/export/metrics/template/…/v1/export/series/template/…
Column headersthe names of the previous export, such as Energy Production (kWh)the names of the metric collection, such as Grid feed-in (kWh), or ids with header=id
First columnDate (YYYY-MM)Date, or timestamp with header=id
Extra columnDays in Month (d) at monthly resolutionnone
Missing value0empty
Days and monthsUTCthe local time of the plant
Calculated columnsincludedthe performance ratio, the expected production and the specific yield are included; the others are left out

Using the Requests in Other Tools

  • Python: the requests library, as in the script below.
  • Excel: Power Query with the Authorization header — see Excel with Power Query.
  • Power BI: the same Power Query connection as in Excel.
  • Tableau and others: any tool that reads a CSV or JSON link and can send a header.

Troubleshooting

AnswerMeaningWhat to do
401The token is missing, expired or revoked.Create a new token, or rotate the existing one.
403 no_accessible_parksYou cannot read the measurements of the plant.Check the UID and your role on the plant.
400 over_budgetThe export is too large.Use the step or the range the answer names in hint, or split the export.
400 step_not_servedThe template has no value at this step.Use one of the steps in hint.offered_common.
429Too many exports at once, or the hourly allowance is used up.Wait for the seconds in the header Retry-After.
Special characters look wrongThe files are UTF-8.Name the encoding when you import the file.

Python Example: SolarViz Report Generator

The script fetches the plant information, the important events of the current quarter and the monthly figures of the year so far, and builds a PDF with a summary, a chart and two tables.

Prerequisites

pip install requests pandas matplotlib reportlab
  • requests — the requests to Mirox
  • pandas — reading and adding up the CSV data
  • matplotlib — the chart
  • reportlab — the PDF file

The script reads the token from the environment variable MIROX_TOKEN:

export MIROX_TOKEN="YOUR_API_TOKEN"
python external_report_generator.py

Complete Example Code

You can also download the script.

#!/usr/bin/env python3
"""
SolarViz - Mirox External Report Generator

Fetches the data of one plant from the Mirox API and builds an energy
production report with a chart as a PDF file:

  * plant information          GET /api/v1/export/report/{plant}/info
  * events                     GET /api/v1/export/report/{plant}/events.csv
  * monthly production figures GET /api/v1/export/series/template/{template}

Requires: pip install requests pandas matplotlib reportlab
The API token is read from the environment variable MIROX_TOKEN.
"""

import io
import os
import sys
import time
from datetime import datetime, timezone

import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt
import pandas as pd
import requests
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import cm
from reportlab.platypus import Image, Paragraph, SimpleDocTemplate, Spacer, Table, TableStyle

# Configuration - replace with your values
API_URL = "https://service.mirox.io"
API_TOKEN = os.environ.get("MIROX_TOKEN", "YOUR_API_TOKEN")  # group "Metric Export"
PARK_UID = "ABC123DEF456"  # the UID of the plant
TEMPLATE_UID = "ABCD12340002"  # system template "Report Technical"

# The report covers this year so far; the events are those of the current quarter
YEAR = datetime.now(timezone.utc).year
QUARTER = (datetime.now(timezone.utc).month - 1) // 3 + 1

HEADERS = {"Authorization": f"Bearer {API_TOKEN}", "Accept-Encoding": "gzip"}

# One CSV dialect for every request, independent of regional settings
CSV_FORMAT = {"separator_csv": ",", "separator_decimal": "."}

# The columns the report reads, by metric id (header=id)
PRODUCTION = "plant.grid_feedin"
EXPECTED = "plant.expected_weather"
LOSS_GRID = "plant.shutdown_grid"
LOSS_MARKETER = "plant.shutdown_external"
PERFORMANCE_RATIO = "plant.pr_weather"


class ExportRefused(Exception):
    """A coded refusal of the Metric Export: what was wrong, and the way out."""

    def __init__(self, status, detail):
        self.status = status
        self.code = detail.get("code", "")
        self.params = detail.get("params", {})
        self.hint = detail.get("hint", {})
        super().__init__(f"{status} {self.code}: {detail.get('message', '')} "
                         f"params={self.params} hint={self.hint}")


def get(path, params=None, retries=3):
    """GET with the token. Waits and repeats when the export is busy (429)."""
    for _attempt in range(retries):
        response = requests.get(f"{API_URL}{path}", headers=HEADERS, params=params, timeout=90)
        if response.status_code == 429:
            time.sleep(int(response.headers.get("Retry-After", "5")))
            continue
        if response.status_code >= 400:
            try:
                detail = response.json().get("detail")
            except ValueError:
                detail = None
            if isinstance(detail, dict):
                raise ExportRefused(response.status_code, detail)
            response.raise_for_status()
        return response
    raise RuntimeError(f"{path}: still busy after {retries} attempts")


def fetch_park_info():
    """Plant information as a dictionary."""
    return get(f"/api/v1/export/report/{PARK_UID}/info").json()


def fetch_events(year, quarter):
    """The important events of a quarter as a DataFrame."""
    response = get(f"/api/v1/export/report/{PARK_UID}/events.csv",
                   {"year": year, "quarter": quarter, **CSV_FORMAT})
    events = pd.read_csv(io.StringIO(response.content.decode("utf-8")))
    if events.empty:
        return events
    # A priority of 1000 or more marks an important event
    events = events[events["Priority"] >= 1000]
    return events.drop(columns=["Event ID", "Priority"], errors="ignore")


def fetch_metrics(year):
    """Monthly figures of the template for the year so far.

    header=id gives column names that never change. A year in progress ends
    now; the notes of the answer say so.
    """
    response = get(f"/api/v1/export/series/template/{TEMPLATE_UID}", {
        "park": PARK_UID, "year": year, "step": "month", "header": "id", **CSV_FORMAT})
    for note in filter(None, response.headers.get("X-Mirox-Notes", "").split(";")):
        print(f"  note: {note}")
    metrics = pd.read_csv(io.StringIO(response.content.decode("utf-8")))
    # An empty cell means "no data"; it is read as NaN and left out of the sums
    return metrics.rename(columns={"timestamp": "month"})


def create_production_chart(metrics):
    """Monthly production with the shutdown losses stacked, against the expectation."""
    plt.figure(figsize=(8, 4))
    positions = range(len(metrics))
    production = metrics[PRODUCTION].fillna(0)
    loss_grid = metrics[LOSS_GRID].fillna(0)
    loss_marketer = metrics[LOSS_MARKETER].fillna(0)

    plt.bar(positions, production, color="#2986cc", label="Grid feed-in")
    plt.bar(positions, loss_grid, bottom=production, color="#e06666",
            label="Shutdown loss, grid operator")
    plt.bar(positions, loss_marketer, bottom=production + loss_grid, color="#f1c232",
            label="Shutdown loss, direct marketer")
    plt.plot(positions, metrics[EXPECTED], marker="o", color="#6aa84f", linewidth=2,
             label="Expected production")

    plt.title("Monthly production and shutdown losses")
    plt.xlabel("Month")
    plt.ylabel("Energy (kWh)")
    plt.xticks(positions, metrics["month"], rotation=45)
    plt.grid(axis="y", alpha=0.3)
    plt.legend(loc="upper left")
    plt.tight_layout()

    buffer = io.BytesIO()
    plt.savefig(buffer, format="png", dpi=300)
    buffer.seek(0)
    plt.close()
    return buffer


def calculate_performance(metrics):
    """The figures of the summary table."""
    production = metrics[PRODUCTION].sum()
    expected = metrics[EXPECTED].sum()
    loss_grid = metrics[LOSS_GRID].sum()
    loss_marketer = metrics[LOSS_MARKETER].sum()
    losses = loss_grid + loss_marketer
    return {
        "production": production,
        "expected": expected,
        "production_vs_expected": production / expected * 100 if expected else None,
        "loss_grid": loss_grid,
        "loss_marketer": loss_marketer,
        "losses": losses,
        "loss_share": losses / (production + losses) * 100 if production + losses else None,
    }


def number(value, unit="", digits=2):
    if value is None or pd.isna(value):
        return "-"
    return f"{value:,.{digits}f}{unit}"


def plain_table(rows, widths):
    table = Table(rows, colWidths=widths)
    table.setStyle(TableStyle([
        ("FONTNAME", (0, 0), (0, -1), "Helvetica-Bold"),
        ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
        ("TOPPADDING", (0, 0), (-1, -1), 3),
        ("BOTTOMPADDING", (0, 0), (-1, -1), 3),
    ]))
    return table


def grid_table(rows, font_size=9):
    table = Table(rows, repeatRows=1)
    table.setStyle(TableStyle([
        ("BACKGROUND", (0, 0), (-1, 0), colors.lightgrey),
        ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
        ("ALIGN", (0, 0), (-1, 0), "CENTER"),
        ("ALIGN", (1, 1), (-1, -1), "RIGHT"),
        ("GRID", (0, 0), (-1, -1), 0.5, colors.grey),
        ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
        ("FONTSIZE", (0, 0), (-1, -1), font_size),
    ]))
    return table


def generate_pdf_report(park_info, events, metrics, performance, chart):
    """Build the PDF and return its file name."""
    output_file = f"SolarViz_Report_{park_info['name'].replace(' ', '_')}_{YEAR}_Q{QUARTER}.pdf"
    doc = SimpleDocTemplate(output_file, pagesize=A4)
    styles = getSampleStyleSheet()
    styles["Title"].fontSize = 18
    address = park_info.get("address") or {}
    portfolio = park_info.get("portfolio") or {}
    organization = park_info.get("organization") or {}

    elements = [
        Paragraph(f"Energy Production Report: {park_info['name']}", styles["Title"]),
        Spacer(1, 0.5 * cm),
        Paragraph("Plant Information", styles["Heading2"]),
        plain_table([
            ["Name:", park_info["name"]],
            ["Type:", park_info.get("type", "")],
            ["Location:", f"{address.get('city', '')}, {address.get('country', '')}"],
            ["Peak power:", number((park_info.get("peak_production_w") or 0) / 1e6, " MW")],
            ["Portfolio:", portfolio.get("name", "")],
            ["Organization:", organization.get("name", "")],
        ], [3 * cm, 10 * cm]),
        Spacer(1, 0.5 * cm),
        Paragraph(f"Summary ({YEAR} to date)", styles["Heading2"]),
        plain_table([
            ["Grid feed-in:", number(performance["production"], " kWh")],
            ["Expected production:", number(performance["expected"], " kWh")],
            ["Feed-in against expectation:", number(performance["production_vs_expected"], " %")],
            ["Shutdown losses:", number(performance["losses"], " kWh")],
            ["  by the grid operator:", number(performance["loss_grid"], " kWh")],
            ["  by the direct marketer:", number(performance["loss_marketer"], " kWh")],
            ["Share of the losses:", number(performance["loss_share"], " %")],
        ], [6 * cm, 7 * cm]),
        Spacer(1, 0.5 * cm),
        Paragraph("Monthly Production", styles["Heading2"]),
        Image(chart, width=16 * cm, height=8 * cm),
        Spacer(1, 0.5 * cm),
    ]

    rows = [["Month", "Feed-in (kWh)", "Expected (kWh)", "Loss grid (kWh)",
             "Loss marketer (kWh)", "PR (%)"]]
    for _, row in metrics.iterrows():
        rows.append([row["month"], number(row[PRODUCTION]), number(row[EXPECTED]),
                     number(row[LOSS_GRID]), number(row[LOSS_MARKETER]),
                     number(row[PERFORMANCE_RATIO], digits=1)])
    elements += [grid_table(rows), Spacer(1, 0.5 * cm),
                 Paragraph("Important Events", styles["Heading2"])]

    if events.empty:
        elements.append(Paragraph("No important events in this quarter.", styles["Normal"]))
    else:
        elements.append(grid_table([events.columns.tolist()] + events.values.tolist(), 8))

    elements += [
        Spacer(1, 1 * cm),
        Paragraph("Data Source", styles["Heading2"]),
        Paragraph(
            "Data exported from the Mirox platform through the Metric Export API.<br/>"
            f"Created: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M')} UTC<br/><br/>"
            "<i>Generated by SolarViz - External Reporting Tool</i>", styles["Normal"]),
    ]
    doc.build(elements)
    return output_file


def main():
    try:
        print("Fetching plant information...")
        park_info = fetch_park_info()

        print("Fetching events...")
        events = fetch_events(YEAR, QUARTER)

        print("Fetching monthly figures...")
        metrics = fetch_metrics(YEAR)

        print("Building the report...")
        performance = calculate_performance(metrics)
        chart = create_production_chart(metrics)
        output_file = generate_pdf_report(park_info, events, metrics, performance, chart)
        print(f"Report created: {output_file}")
    except ExportRefused as refused:
        print(f"The export was refused: {refused}")
        if refused.code == "over_budget":
            print("Use a coarser step or a shorter range, see hint.step and hint.max_days.")
        sys.exit(1)
    except requests.RequestException as error:
        print(f"The request failed: {error}")
        sys.exit(1)


if __name__ == "__main__":
    main()

How It Works

  1. Configuration. The address of Mirox, the plant and the template stand at the top. The token comes from the environment, so it never ends up in a file you share.
  2. One function for all requests. get sends the token, waits and repeats when Mirox answers 429, and turns a refusal of the export into an error that carries code, params and hint.
  3. Monthly figures. fetch_metrics asks for the template over the year with step=month and header=id, and prints the notes of the answer. In a year that is still running, the range ends now.
  4. Figures. Empty cells are read as "no data" and left out of the sums.
  5. Report. ReportLab builds the PDF: plant information, summary, chart, monthly table and important events.

Customization

  • Period: change YEAR for the figures and QUARTER for the events.
  • Columns: use another template, or request metrics directly with GET /v1/export/series and metrics=….
  • Finer data: step=day gives daily rows. For 15-minute curves, request the power metrics with GET /v1/export/series.
  • Several plants: pass several UIDs in park, or a portfolio.
  • Automation: run the script from a scheduler, with the token in the environment of the job.

Related Features

  • Metric Export for Excel — recipes and Power Query
  • External Report Generation — when to build reports outside Mirox
  • Metric Export API — the reference of the requests used here
  • API Token Usage — create and manage the token
  • Reports — the reports Mirox generates itself
Next
Metric Export for Excel
© 2026 Mirox Verwaltungs GmbH. All rights reserved. | Privacy Policy