Auf dieser Seite
telo · Personal API · Pro

Deine Daten aus der Health-App, per REST.

Lies deinen eigenen synchronisierten Gesundheitsverlauf in Dashboards, Skripten und Agenten. Sechs schreibgeschützte Endpoints, enthalten in einem aktiven, bezahlten telo-Pro-Abo.

Vollständige Parameter- und Antwortschemas (OpenAPI 3.1)

Deine erste Anfrage

  1. Schließ Pro in der telo-App auf dem iPhone unter Konto → Tarif ab und synchronisiere dann deinen Verlauf.
  2. Öffne Konto im Web-Dashboard und erstelle einen Schlüssel für dein Projekt. Speichere ihn sofort: Das vollständige Geheimnis wird nur einmal angezeigt.
  3. Setze TELO_API_KEY in der Umgebung deines Servers oder deiner lokalen Shell und führe dann die Anfrage unten aus.
curl --fail-with-body 'https://telo.health/api/v1/list_metrics' \
  -H "Authorization: Bearer $TELO_API_KEY"

Authentifizierung

Sende bei jeder Anfrage Authorization: Bearer <key>. Jeder Schlüssel liest nur sein eigenes Konto. Bewahre ihn auf deinem Server oder lokalen Rechner auf, nie im Browser-Code, in einem öffentlichen Repository oder in einer URL. Cookies und iPhone-Tokens authentifizieren diese API nicht.

Erstelle bis zu fünf Schlüssel und widerrufe jedes Projekt einzeln unter Konto. Widerrufen bleibt auch nach Ablauf von Pro möglich. Ein bezahltes Pro-Abo ist auch für Konten von Gründungsmitgliedern erforderlich; Erstattungen und Abo-Änderungen folgen dem bestehenden Abrechnungs-Cache von bis zu 15 Minuten, der per Webhook invalidiert wird.

API-Schlüssel verwalten

Endpoints

Basis-URL: https://telo.health/api/v1. Jeder Endpoint nutzt GET und liefert dieselbe JSON-Payload wie das entsprechende MCP-Lese-Tool, ohne den MCP-Umschlag. Datumsangaben nutzen YYYY-MM-DD. Listen werden durch Kommas getrennt; Booleans sind true oder false. Unbekannte oder wiederholte Parameter werden abgelehnt.

GET /data_status

Prüfe Abdeckung, Importfortschritt und die letzte Synchronisierung, bevor du fehlende Einträge interpretierst.

Erforderlich
Keine
Optional
Keine
curl --fail-with-body 'https://telo.health/api/v1/data_status' \
  -H "Authorization: Bearer $TELO_API_KEY"

GET /list_metrics

Finde die Namen, Einheiten und Zeiträume der Werte, die in deinem Konto verfügbar sind.

Erforderlich
Keine
Optional
Keine
curl --fail-with-body 'https://telo.health/api/v1/list_metrics' \
  -H "Authorization: Bearer $TELO_API_KEY"

GET /query_daily

Lies Tageswerte oder fasse sie nach Woche oder Monat zusammen. Fehlende Zeiträume fehlen in der Antwort, sie sind nicht 0.

Erforderlich
metrics, from, to
Optional
granularity=day|week|month
curl --fail-with-body 'https://telo.health/api/v1/query_daily?metrics=steps&from=2026-11-01&to=2026-11-08&granularity=day' \
  -H "Authorization: Bearer $TELO_API_KEY"

GET /sessions

Liste Schlafnächte oder Trainings auf. Trainingsfilter und wöchentliche Gruppierung erfordern kind=workout.

Erforderlich
kind=sleep|workout, from, to
Optional
activity, granularity=session|week, max_hr
curl --fail-with-body 'https://telo.health/api/v1/sessions?kind=workout&from=2026-11-01&to=2026-11-08' \
  -H "Authorization: Bearer $TELO_API_KEY"

GET /workout_detail

Lies die Zusammenfassung eines Trainings, seine Ereignisse und verfügbaren Verläufe. Nutze eine UUID, die sessions geliefert hat.

Erforderlich
uuid
Optional
metrics, offset, event_offset, limit, max_hr, wall_tolerance_s
curl --fail-with-body 'https://telo.health/api/v1/workout_detail?uuid=WORKOUT_UUID&limit=500' \
  -H "Authorization: Bearer $TELO_API_KEY"

GET /derived_metrics

Lies die dauerbasierte Trainingsbelastung und persönliche Basiswerte für HRV und Ruheherzfrequenz. Gehen ist standardmäßig ausgeschlossen.

Erforderlich
from, to
Optional
baseline_days=30..60 (60), include_walking=false, include_trimp=false, max_hr
curl --fail-with-body 'https://telo.health/api/v1/derived_metrics?from=2026-11-01&to=2026-11-08&include_trimp=true' \
  -H "Authorization: Bearer $TELO_API_KEY"

Codebeispiele

Die Beispiele lesen nur den Katalog. Dein API-Schlüssel gehört in die Umgebung, nicht in die Quelldatei. HTTP-Fehler müssen behandelt werden, bevor du die Antwort verwendest.

Python

import json
import os
from urllib.request import Request, urlopen

request = Request(
    "https://telo.health/api/v1/list_metrics",
    headers={"Authorization": "Bearer " + os.environ["TELO_API_KEY"]},
)
# urlopen raises HTTPError for non-success responses.
with urlopen(request, timeout=30) as response:
    catalog = json.load(response)
print(catalog)

JavaScript (Node.js)

// Node.js, server-side only.
const response = await fetch("https://telo.health/api/v1/list_metrics", {
  headers: { Authorization: `Bearer ${process.env.TELO_API_KEY}` },
  signal: AbortSignal.timeout(30_000),
});
if (!response.ok) throw new Error(`telo HTTP ${response.status}`);
const catalog = await response.json();
console.log(catalog);

Die Antwort lesen

Beispielantwort von query_daily mit fiktiven Daten:

{
  "rows": [
    {
      "period": "2026-11-01",
      "metric": "steps",
      "unit": "count",
      "value": 8200,
      "aggregation": "sum",
      "days_present": 1,
      "days_expected": 1,
      "period_start": "2026-11-01",
      "period_end": "2026-11-01",
      "daily_min": 8200,
      "daily_max": 8200
    }
  ],
  "truncated": false
}

days_present zählt Tage mit gespeicherten Werten; days_expected beschreibt die angefragte Kalenderabdeckung. Fehlende Daten und null bedeuten nicht 0. Behalte Einheiten und den lokalen Offset der Zeitstempel bei. Die API liest, was das iPhone synchronisiert hat; ein Aufruf löst keine Synchronisierung aus. Trainingszusammenfassungen bleiben dauerhaft erhalten, Rohverläufe 30 Tage lang. GPS ist nicht enthalten.

Limits und Paginierung

  • 60 Anfragen pro Minute pro Konto, geteilt von allen Schlüsseln. Warte bei 429 so viele Sekunden, wie Retry-After angibt.
  • Höchstens 3.660 Tage pro Datumsabfrage, oder 366 bei derived_metrics. query_daily akzeptiert bis zu 256 durch Kommas getrennte Wertnamen.
  • Datumsbasierte Abfragen liefern bis zu 500 Zeilen. Wenn truncated true ist, verwirf die unvollständige Antwort und frag weniger Werte oder kleinere, nicht überlappende Zeiträume ab, ausgerichtet an vollständigen Wochen oder Monaten. Behandle einen Teildurchschnitt nicht als vollständigen Zeitraum.
  • workout_detail nutzt getrennte Werte für next_offset und next_event_offset. Folge beiden unabhängig voneinander, bis beide null sind. Standardwerte: offset=0, event_offset=0, limit=360; limit ist höchstens 500. Ein leeres metrics= liefert Metadaten und Ereignisse ohne Verläufe.

Fehler

400
Ungültige Parameter, Daten oder Zeiträume. Sieh in der OpenAPI-Referenz nach.
401
Persönlicher Schlüssel fehlt, ist ungültig oder widerrufen. Erstelle bei Bedarf einen neuen.
403
Kein aktives, bezahltes Pro-Abo. Prüfe Konto → Tarif auf dem iPhone.
429
Limit erreicht. Warte die Sekunden aus Retry-After, bevor du es erneut versuchst.
500
Interner Fehler. Versuch es später erneut; deute die Antwort nicht als leere Gesundheitsdaten.
503
Die Abo-Prüfung ist nicht verfügbar. Versuch es später erneut.