Öffnungszeiten-API
Aufgelöste Öffnungszeiten und kommende Feiertage für eine Website abrufen
Zuletzt aktualisiert am
Verwenden Sie die API für aufgelöste Öffnungszeiten, wenn Sie auf einer öffentlichen Website Saisonzeiten (zum Beispiel Sommer / Winter) oder kommende Feiertage anzeigen. Tillor wendet Ausnahmen, Saisonzeiträume und den gewöhnlichen Wochenplan bereits an und fügt gesetzliche Feiertage im angefragten Bereich hinzu. Das müssen Sie nicht selbst nachbauen.
Berechtigung: organization:settings:read oder organization:settings:write
API-Schlüssel bleibt serverseitig
Rufen Sie Tillor nur von einem Server aus auf (Next.js Route Handler, Server Component oder Backend). Legen Sie den Schlüssel in Umgebungsvariablen ab. Senden Sie ihn nie an den Browser.
Authentifizierung: siehe HTTP API. Probieren Sie den Endpunkt in der API-Referenz oder über OpenAPI aus (Tag organization-settings).
Endpunkt
GET https://tillor.eu/api/orgs/org_abc123/organization-settings/opening-hoursHeader:
x-api-key: tkn_xxxErsetzen Sie org_abc123 durch Ihre Organisations-ID.
Query-Parameter
Verwenden Sie entweder date oder from/to. Kombinieren Sie sie nicht.
| Parameter | Bedeutung |
|---|---|
| (keiner) | Heute in der Zeitzone der Organisation |
date | Ein Kalendertag (YYYY-MM-DD) |
from | Starttag (einschließlich). Ohne to: nur dieser Tag |
to | Endtag (einschließlich). Erfordert from. Höchstens 366 Tage |
languageIsoCode | Sprache für Feiertagsnamen (NL, FR, …). Standard: Locale der Organisation |
Response
Jedes Element ist ein Kalendertag, bereits aufgelöst:
| Feld | Bedeutung |
|---|---|
timeZone | IANA-Zeitzone der Organisation |
from / to | Angefragter Bereich |
holidays | Gesetzliche Feiertage, die sich mit from–to überschneiden |
items[].date | Kalendertag YYYY-MM-DD |
items[].weekday | monday … sunday |
items[].source | exception, period oder regular |
items[].periodLabel | Nur bei source: "period": die Bezeichnung aus Tillor, zum Beispiel "Zomer" oder "Winter" |
items[].holiday | Nur wenn dieser Tag ein gesetzlicher Feiertag ist: { id, name, startDate, endDate } |
items[].blocks | Zeitfenster in Minuten ab Mitternacht |
items[].closed | true, wenn blocks leer ist |
Priorität: Ausnahme (Feiertag oder benutzerdefinierter Bereich) → letzter passender Saisonzeitraum → gewöhnlicher Wochenplan.
Saisonbezeichnungen stammen aus Einstellungen > Öffnungszeiten. Zeiträume dürfen über den Jahreswechsel laufen (zum Beispiel 1. November bis 31. März). Tage außerhalb jedes Zeitraums fallen auf den gewöhnlichen Wochenplan zurück (source: "regular", kein periodLabel).
Minuten in Uhrzeit
startMinutes / endMinutes sind Minuten ab 00:00.
| Minuten | Uhrzeit |
|---|---|
| 540 | 09:00 |
| 600 | 10:00 |
| 720 | 12:00 |
| 780 | 13:00 |
| 1020 | 17:00 |
| 1140 | 19:00 |
function formatMinutes(minutes: number): string {
const hour = Math.floor(minutes / 60);
const minute = minutes % 60;
return `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
}Beispiele
Tag in einem Saisonzeitraum
curl -X GET "https://tillor.eu/api/orgs/org_abc123/organization-settings/opening-hours?date=2026-07-15" \
-H "x-api-key: tkn_xxx"{
"timeZone": "Europe/Brussels",
"from": "2026-07-15",
"to": "2026-07-15",
"holidays": [],
"items": [
{
"date": "2026-07-15",
"weekday": "wednesday",
"source": "period",
"periodLabel": "Zomer",
"blocks": [{ "startMinutes": 540, "endMinutes": 720 }],
"closed": false
}
]
}09:00–12:00, Sommerzeiten.
Tag außerhalb der Saisonzeiträume
curl -X GET "https://tillor.eu/api/orgs/org_abc123/organization-settings/opening-hours?date=2026-01-15" \
-H "x-api-key: tkn_xxx"{
"timeZone": "Europe/Brussels",
"from": "2026-01-15",
"to": "2026-01-15",
"holidays": [],
"items": [
{
"date": "2026-01-15",
"weekday": "thursday",
"source": "regular",
"blocks": [
{ "startMinutes": 540, "endMinutes": 720 },
{ "startMinutes": 780, "endMinutes": 1020 }
],
"closed": false
}
]
}09:00–12:00 und 13:00–17:00.
Bereich über eine Zeitraumgrenze
curl -X GET "https://tillor.eu/api/orgs/org_abc123/organization-settings/opening-hours?from=2026-03-30&to=2026-04-02" \
-H "x-api-key: tkn_xxx"| Datum | source | periodLabel |
|---|---|---|
| 2026-03-30 | regular | - |
| 2026-03-31 | regular | - |
| 2026-04-01 | period | Zomer |
| 2026-04-02 | period | Zomer |
Kommende Feiertage
Gesetzliche Feiertage sind in derselben Response enthalten: holidays für eine Liste (Name + Daten), items[].holiday, wenn dieser Kalendertag ein Feiertag ist. Die Zeiten bleiben der aufgelöste Plan; ein Feiertag ohne eingetragene Ausnahme in Tillor folgt dem Saison- oder Wochenplan (source ist dann nicht "exception").
curl -X GET "https://tillor.eu/api/orgs/org_abc123/organization-settings/opening-hours?from=2026-08-27&to=2026-12-31&languageIsoCode=NL" \
-H "x-api-key: tkn_xxx"{
"timeZone": "Europe/Brussels",
"from": "2026-08-27",
"to": "2026-12-31",
"holidays": [
{
"id": "0fad0035-6b77-404a-953d-c66dac014483",
"name": "Allerheiligen",
"startDate": "2026-11-01",
"endDate": "2026-11-01"
},
{
"id": "d90e5f53-bc92-4860-bdae-f7e75935848d",
"name": "Kerstmis",
"startDate": "2026-12-25",
"endDate": "2026-12-25"
}
],
"items": [
{
"date": "2026-11-01",
"weekday": "sunday",
"source": "regular",
"holiday": {
"id": "0fad0035-6b77-404a-953d-c66dac014483",
"name": "Allerheiligen",
"startDate": "2026-11-01",
"endDate": "2026-11-01"
},
"blocks": [],
"closed": true
}
]
}Das items-Beispiel oben ist gekürzt; die echte Response enthält jeden Tag im Bereich. Schulferien sind in diesem Endpunkt nicht enthalten; dafür bleibt GET /holidays?kind=school.
Next.js (Server)
Für ein Wochen-Widget oder „jetzt geöffnet“ auf einer öffentlichen Website:
const TILLOR_API_URL = "https://tillor.eu";
const ORGANIZATION_ID = process.env.TILLOR_ORG_ID ?? "";
type OpeningHoursBlock = {
startMinutes: number;
endMinutes: number;
};
type OpeningHoursHoliday = {
id: string;
name: string;
startDate: string;
endDate: string;
};
type OpeningHoursItem = {
date: string;
weekday: string;
source: "exception" | "period" | "regular";
periodLabel?: string;
holiday?: OpeningHoursHoliday;
blocks: OpeningHoursBlock[];
closed: boolean;
};
type OpeningHoursResponse = {
timeZone: string;
from: string;
to: string;
holidays: OpeningHoursHoliday[];
items: OpeningHoursItem[];
};
export async function getOpeningHours(
from: string,
to: string,
): Promise<OpeningHoursResponse> {
const url = new URL(
`${TILLOR_API_URL}/api/orgs/${ORGANIZATION_ID}/organization-settings/opening-hours`,
);
url.searchParams.set("from", from);
url.searchParams.set("to", to);
url.searchParams.set("languageIsoCode", "NL");
const response = await fetch(url, {
headers: {
"x-api-key": process.env.TILLOR_API_KEY ?? "",
},
next: { tags: ["opening-hours"], revalidate: 3600 },
});
if (!response.ok) {
throw new Error(`Tillor opening hours ${response.status}`);
}
return response.json() as Promise<OpeningHoursResponse>;
}holidays ist die Liste für einen Block „Kommende Feiertage“. items[].holiday ist in einem Wochenkalender praktisch. items[].periodLabel ist der Saisontext (zum Beispiel "Zomer" oder "Winter"). Ein Cache von 1 Stunde reicht meistens aus.
Cache ungültig machen (Webhook)
Bei jeder Änderung der Organisationseinstellungen sendet Tillor organizationSettings:updated (Webhook und SSE). Abonnieren Sie es und rufen Sie die Öffnungszeiten erneut ab. Die Payload ist absichtlich klein (keine Drucker-IPs oder der vollständige Plan):
{
"event": "organizationSettings:updated",
"data": {
"openingHoursChanged": true
},
"timestamp": 1787829600000
}openingHoursChanged ist true, wenn sich der Öffnungszeitenplan, die Zeitzone oder das Standardland ändert - das beeinflusst GET .../opening-hours. Bei false können Sie den Öffnungszeiten-Cache stehen lassen.
Beispiel Next.js Route Handler:
import { revalidateTag } from "next/cache";
export async function POST(request: Request) {
const body = (await request.json()) as {
event?: string;
data?: { openingHoursChanged?: boolean };
};
if (body.event === "organizationSettings:updated" && body.data?.openingHoursChanged) {
await revalidateTag("opening-hours");
}
return new Response(null, { status: 204 });
}Webhook anlegen: siehe Webhooks. Event-Key: organizationSettings:updated (Berechtigung organization:settings:read oder organization:settings:write).
Vollständiger Plan (optional)
Nur nötig, wenn Sie den Saisonkalender selbst anzeigen möchten (Bezeichnungen + fromMonth/untilDay), ohne pro Tag aufzulösen:
GET https://tillor.eu/api/orgs/org_abc123/organization-settingsLesen Sie openingHoursSchedule.periods (Bezeichnungen wie "Zomer") und openingHoursSchedule.weekdays (gewöhnlicher Plan). Für die Website selbst bleibt GET .../opening-hours die einfachste Quelle.
MCP
In Cursor oder Claude: Endpunkt organizationSettings_listOpeningHours (Kategorie organizationSettings), Argumente organizationId, optional date oder from/to, optional languageIsoCode.
Verwandt
- HTTP API - Authentifizierung und Header
- HTTP-Beispiele - Allgemeine cURL-Beispiele
- Webhooks -
organizationSettings:updatedzur Cache-Revalidierung - Organisationseinstellungen - Öffnungszeiten in Tillor einstellen