Telemetry service
The endpoints of the telemetry service that the engine writes to and the website reads from.
The telemetry service is a separate application. The engine sends records to it; the website reads aggregates from it. This page lists the endpoints that are called from the engine or the website code, with the parameters those callers use. Endpoints or parameters that neither of them uses are not listed here.
script run (host, container) --POST--> telemetry service <--GET-- website server <-- browserA browser never talks to the telemetry service directly. It calls routes on
community-scripts.org, and the website server forwards the request.
Ingest
POST /telemetry
The one endpoint the engine uses.
| URL | https://telemetry.community-scripts.org/telemetry (TELEMETRY_URL in api/api.func) |
| Method | POST |
| Headers | Content-Type: application/json, User-Agent: community-scripts-core/3 |
| Body | One JSON record. Every field is described in Telemetry and diagnostics |
| Success | Any HTTP 2xx status. The engine reads only the status code, never the response body |
Several records with the same execution_id describe one run: the
installing record, progress records and pings, and the terminal record. The
engine sends the full record each time, except for the short pings from inside
a container.
The engine treats every other status, and every connection error, as "not delivered". It retries according to the table in Delivery and then gives up without affecting the install.
To send records somewhere else, set TELEMETRY_URL before starting a script.
Reading
The website server reads from the address in its TELEMETRY_SERVICE_URL
environment variable. All four endpoints are GET and return JSON.
Common parameters:
| Parameter | Values the website sends |
|---|---|
days | 1, 7, 30, 90, 365 |
repo | ProxmoxVE or DevScripts |
platform | pve, incus, or omitted for both |
GET /api/dashboard
Totals and distributions for the chosen period.
| Parameter | Sent by the website |
|---|---|
days, repo, platform | as above |
Fields the website reads from the response:
| Field | Content |
|---|---|
total_installs, total_all_time, sample_size | Counts |
success_count, failed_count, aborted_count, installing_count, success_rate | Outcome of the period |
avg_install_duration | Seconds |
top_apps | List of app, count |
os_distribution | List of os, count |
method_stats | List of method, count |
pve_versions | List of version, count |
platform_stats | List of platform, count |
type_stats | List of type, count |
gpu_stats | List of vendor, passthrough, count |
error_categories | List of category, count |
error_analysis | List of pattern, count, unique_apps, apps |
failed_apps | List of app, type, total_count, failed_count, failure_rate |
daily_stats | List of date, success, failed |
top_tools, total_tools | Host tool runs: tool, count |
top_addons, total_addons | Add-on runs: addon, count |
recent_records | List of records, same shape as in /api/records |
The website also calls /api/dashboard?days=1 on its own, to read
total_all_time, the all-time install total.
GET /api/records
The individual records, paged. This feeds the install log on the analytics page.
| Parameter | Sent by the website |
|---|---|
page | Page number, starting at 1 |
limit | Page size; the install log uses 25 |
days, repo, platform | as above |
status | success, failed, aborted or installing |
type | lxc, vm, pve, addon or turnkey |
search | Free text from the search box |
sort | Forwarded when present |
Response:
| Field | Content |
|---|---|
records | List of records |
page, limit, total, total_pages | Paging |
A record contains the fields the engine sent (random_id, execution_id,
type, nsapp, status, ct_type, disk_size, core_count, ram_size,
os_type, os_version, pve_version, method, exit_code, error,
error_category, error_message, error_step, error_phase,
failed_command, failed_line, failed_function, install_duration,
cpu_vendor, cpu_model, gpu_vendor, gpu_model, gpu_passthrough,
ram_speed, arch, platform, kernel_version, app_version,
payload_version, repo_source, repo_slug) plus id, created and
updated added by the service.
GET /api/scripts
Per-script statistics.
| Parameter | Sent by the website |
|---|---|
days, repo, platform | as above |
Fields the website reads:
| Field | Content |
|---|---|
total_scripts, total_installs | Counts |
top_scripts | List of app, type, total, success, failed, aborted, installing, success_rate, days_old, installs_per_day |
The website also calls /api/scripts?days=30&repo=ProxmoxVE on its own. The
30-day install counts shown for scripts come from the total values in that
response.
GET /api/errors
Failure analysis.
| Parameter | Sent by the website |
|---|---|
days, repo, platform | as above |
Fields the website reads:
| Field | Content |
|---|---|
total_errors, total_installs, overall_fail_rate, stuck_installing | Totals |
exit_code_stats | List of exit_code, count, description, category, percentage |
category_stats | List of category, count, percentage, top_apps |
app_errors | List of app, type, total_count, failed_count, aborted_count, failure_rate, top_exit_code, top_error, top_message, top_category |
recent_errors | List of nsapp, type, status, exit_code, error, error_category, error_message, error_step, error_phase, failed_function, os_type, os_version, platform, execution_id, created |
error_timeline | List of date, failed, aborted |
The website's own routes
These are what a browser on the analytics page calls. Each one validates its parameters and forwards to the endpoint of the same name.
| Website route | Forwards to | days default and range | Cached for |
|---|---|---|---|
/api/telemetry/dashboard | /api/dashboard | 1, 0 to 365 | 30 s up to 1 day, 120 s up to 7 days, otherwise 300 s |
/api/telemetry/records | /api/records | not checked | 15 s |
/api/telemetry/scripts | /api/scripts | 30, 0 to 365 | 30 s up to 1 day, 120 s up to 7 days, otherwise 300 s |
/api/telemetry/errors | /api/errors | 7, 1 to 365 | 120 s up to 7 days, otherwise 300 s |
repo defaults to ProxmoxVE on the dashboard, scripts and errors routes.
platform must be empty, pve or incus on all four; anything else is
rejected before the request leaves the website.
Error responses from these routes:
| Status | Body | When |
|---|---|---|
| 400 | {"error":"Invalid platform parameter"} | platform is not one of the three values |
| 400 | {"error":"Invalid days parameter"} | days is not a number in range |
| 502 | {"error":"Failed to connect to telemetry service"} | The service did not answer (dashboard, records and errors routes) |
| 503 | {"error":"Telemetry service not configured"} | TELEMETRY_SERVICE_URL is not set on the website server |
When the service answers with an error status, the dashboard, records and
errors routes pass that status on with {"error":"Telemetry service error"}.
The scripts route answers 502 in that case, with
{"error":"Failed to fetch script stats from telemetry service"}; when the
service does not answer at all its body is
{"error":"Failed to query script stats"}.
/api/telemetry/scripts also reshapes the response: it returns
total_scripts, total_installs, top_scripts and an empty recent_scripts
list.
These routes exist for the website's own pages. Their shape can change with the site; do not build scripts on them.
Source
- Engine client:
api/telemetry.func,lxc/install.func - Website routes:
app/api/telemetry/and response types inlib/telemetry-types.tsof the website repository