Wie Datum und Zeit behandelt werden
Die Sally API nutzt überall ein einziges Format, in beide Richtungen: ISO-8601 in UTC mit abschließendem Z. Diese Seite nennt die Regeln, die Parameter, die nach Datum filtern, und die eine Falle, die du beim Filtern nach Tagen vermeiden solltest.
Die Beispiele zeigen, wie du einen Tag in deiner Zeitzone in genaue UTC-Grenzen umrechnest und Zeitstempel aus einer Antwort für die Anzeige zurückrechnest. Sie funktionieren so, wie sie dastehen, sobald SALLY_TOKEN und DIRECTORY_ID gesetzt sind, siehe Schnellstart.
Schnellnavigation
1. Das Format
Jeder Zeitstempel hat die Form YYYY-MM-DDTHH:MM:SSZ:
2026-08-27T14:30:00Z
Das gilt für jedes Datums-Zeit-Feld in einer Antwort, etwa createdOn oder startTime, und für jede Datumsangabe in einem Query-String oder Body.
followUpMeetingStartTime und followUpMeetingEndTime an einem Abschnittseintrag einer Zusammenfassung mit sectionType: appointment sind ein lokales Datum mit Uhrzeit ohne Zeitzone, zum Beispiel 2026-10-16T09:00:00. Vereinbart hat das Meeting eine Uhrzeit, Donnerstag um neun, und eine Zeitzone würde diese Uhrzeit für jeden Leser in einer anderen Zone verschieben. Wende die Zeitzone der Beteiligten an, statt den Wert als UTC zu lesen. Zusammenfassungen abrufen beschreibt diese Felder.
2. Die Regeln
- Zeitstempel in Antworten kommen immer in UTC. Die einzige Ausnahme sind die beiden Folgetermin-Felder oben.
- Eingaben müssen UTC sein. Ein Wert ohne Zeitzonen-Endung wird als UTC gelesen, nie als Serverzeit.
- Ein ausdrücklicher Versatz wird in den passenden UTC-Zeitpunkt umgerechnet,
2026-08-27T16:30:00+02:00ist also derselbe Moment wie im Beispiel oben. - Ein Datum ohne Uhrzeit (
2026-08-27) gilt als Mitternacht UTC.
| Du schickst | Die API liest |
|---|---|
2026-08-27T14:30:00Z | 2026-08-27T14:30:00Z |
2026-08-27T16:30:00+02:00 | 2026-08-27T14:30:00Z |
2026-08-27T14:30:00 | 2026-08-27T14:30:00Z, ohne Endung heißt UTC |
2026-08-27 | 2026-08-27T00:00:00Z, Mitternacht UTC |
Schick immer die volle Form mit Z. Dann sagt deine Anfrage genau das, was die API liest, und niemand muss sich die Regeln oben merken.
3. Datumsfilter
Diese Parameter filtern nach Datum. Jede Grenze ist eingeschlossen:
| Endpunkt | Parameter | Filtert auf | Bedingung |
|---|---|---|---|
| Terminliste | from (Query) | Startzeit | ab diesem Zeitpunkt |
| Terminliste | to (Query) | Startzeit | bis zu diesem Zeitpunkt |
| Terminsuche | from (Body) | Startzeit | ab diesem Zeitpunkt |
| Terminsuche | to (Body) | Startzeit | bis zu diesem Zeitpunkt |
| Aufnahmeliste | createdAfter (Query) | Erstellzeit | ab diesem Zeitpunkt |
| Aufnahmeliste | createdBefore (Query) | Erstellzeit | bis zu diesem Zeitpunkt |
Diese Anfrage listet die Aufnahmen, die im September 2026 (UTC) erstellt wurden:
- cURL
- JavaScript
- Python
curl "https://api.sally.io/v1.0/directories/$DIRECTORY_ID/recordings?createdAfter=2026-09-01T00:00:00Z&createdBefore=2026-09-30T23:59:59Z" \
-H "Authorization: Bearer $SALLY_TOKEN"
const url = new URL(`https://api.sally.io/v1.0/directories/${directoryId}/recordings`);
url.searchParams.set('createdAfter', '2026-09-01T00:00:00Z');
url.searchParams.set('createdBefore', '2026-09-30T23:59:59Z');
const response = await fetch(url, {
headers: {Authorization: `Bearer ${process.env.SALLY_TOKEN}`},
});
const {items} = await response.json();
import os
import requests
response = requests.get(
f"https://api.sally.io/v1.0/directories/{directory_id}/recordings",
params={
"createdAfter": "2026-09-01T00:00:00Z",
"createdBefore": "2026-09-30T23:59:59Z",
},
headers={"Authorization": f"Bearer {os.environ['SALLY_TOKEN']}"},
)
items = response.json()["items"]
- GET
…/appointmentsDurchsucht Termine (Betreff, Teilnehmer, Zeitraum), paginiertAusprobieren - POST
…/appointments/searchDurchsucht Termine (Parameter im Body)Ausprobieren - GET
…/recordingsListet die Aufnahmen eines Unternehmenskontos auf (paginiert, optional nach Datum gefiltert)Ausprobieren
4. Nach Tagen filtern
Im Sommer beginnt ein Berliner Tag zwei Stunden vor Mitternacht UTC, from=2026-08-27 ist also nicht der deutsche 27. Rechne auf deiner Seite um und schick den genauen Zeitpunkt, den du meinst, zum Beispiel 2026-08-26T22:00:00Z.
| 27. August 2026 in Berlin (UTC+2) | Ortszeit | Zu schickende UTC-Zeit |
|---|---|---|
| Tagesbeginn | 2026-08-27 00:00:00 | 2026-08-26T22:00:00Z |
| Tagesende | 2026-08-27 23:59:59 | 2026-08-27T21:59:59Z |
Was from=2026-08-27 bedeutet | 2026-08-27 02:00:00 | 2026-08-27T00:00:00Z |
Dieser Code berechnet beide Grenzen für einen Tag in einer beliebigen Zeitzone und listet die Termine, die an diesem Tag beginnen:
- cURL
- JavaScript
- Python
# 27. August 2026 in Berlin (UTC+2) als genaue UTC-Grenzen
from="2026-08-26T22:00:00Z"
to="2026-08-27T21:59:59Z"
curl "https://api.sally.io/v1.0/directories/$DIRECTORY_ID/appointments?from=$from&to=$to" \
-H "Authorization: Bearer $SALLY_TOKEN"
// Rechnet eine lokale Uhrzeit in einer Zeitzone in einen UTC-Zeitstempel um.
function toUtc(localDateTime, timeZone) {
const guess = new Date(`${localDateTime}Z`);
const inZone = new Date(guess.toLocaleString('en-US', {timeZone}));
const inUtc = new Date(guess.toLocaleString('en-US', {timeZone: 'UTC'}));
const utc = new Date(guess.getTime() - (inZone - inUtc));
return utc.toISOString().replace('.000Z', 'Z');
}
const from = toUtc('2026-08-27T00:00:00', 'Europe/Berlin'); // 2026-08-26T22:00:00Z
const to = toUtc('2026-08-27T23:59:59', 'Europe/Berlin'); // 2026-08-27T21:59:59Z
const url = new URL(`https://api.sally.io/v1.0/directories/${directoryId}/appointments`);
url.searchParams.set('from', from);
url.searchParams.set('to', to);
const response = await fetch(url, {
headers: {Authorization: `Bearer ${process.env.SALLY_TOKEN}`},
});
const {items} = await response.json();
import os
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
import requests
berlin = ZoneInfo("Europe/Berlin")
def to_utc(local):
return local.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
start = to_utc(datetime(2026, 8, 27, 0, 0, 0, tzinfo=berlin)) # 2026-08-26T22:00:00Z
end = to_utc(datetime(2026, 8, 27, 23, 59, 59, tzinfo=berlin)) # 2026-08-27T21:59:59Z
response = requests.get(
f"https://api.sally.io/v1.0/directories/{directory_id}/appointments",
params={"from": start, "to": end},
headers={"Authorization": f"Bearer {os.environ['SALLY_TOKEN']}"},
)
items = response.json()["items"]
Nimm einen Zeitzonennamen wie Europe/Berlin, keinen festen Versatz. Der Name folgt der Sommerzeit, derselbe Code liefert also im Winter +01:00 und im Sommer +02:00.
5. Zeiten für Nutzer anzeigen
Jeder Zeitstempel in einer Antwort ist UTC:
{
"appointmentId": "d4398f97-cd92-4d21-a6ec-4aab0a85441b",
"subject": "Quartalsplanung",
"startTime": "2026-08-27T07:30:00Z",
"endTime": "2026-08-27T08:30:00Z"
}
Rechne ihn erst für die Anzeige in die Zeitzone des Nutzers um und behalte den UTC-Wert zum Speichern und Vergleichen:
- cURL
- JavaScript
- Python
# GNU date: 2026-08-27T07:30:00Z in Berliner Zeit
TZ=Europe/Berlin date -d '2026-08-27T07:30:00Z' '+%d.%m.%Y %H:%M'
# 27.08.2026 09:30
const startTime = new Date('2026-08-27T07:30:00Z');
console.log(startTime.toLocaleString('de-DE', {timeZone: 'Europe/Berlin'}));
// 27.8.2026, 09:30:00
from datetime import datetime
from zoneinfo import ZoneInfo
start_time = datetime.fromisoformat("2026-08-27T07:30:00Z".replace("Z", "+00:00"))
print(start_time.astimezone(ZoneInfo("Europe/Berlin")).strftime("%d.%m.%Y %H:%M"))
# 27.08.2026 09:30