Skip to Content
Beispiele

Ö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-hours

Header:

x-api-key: tkn_xxx

Ersetzen Sie org_abc123 durch Ihre Organisations-ID.

Query-Parameter

Verwenden Sie entweder date oder from/to. Kombinieren Sie sie nicht.

ParameterBedeutung
(keiner)Heute in der Zeitzone der Organisation
dateEin Kalendertag (YYYY-MM-DD)
fromStarttag (einschließlich). Ohne to: nur dieser Tag
toEndtag (einschließlich). Erfordert from. Höchstens 366 Tage
languageIsoCodeSprache für Feiertagsnamen (NL, FR, …). Standard: Locale der Organisation

Response

Jedes Element ist ein Kalendertag, bereits aufgelöst:

FeldBedeutung
timeZoneIANA-Zeitzone der Organisation
from / toAngefragter Bereich
holidaysGesetzliche Feiertage, die sich mit from–to überschneiden
items[].dateKalendertag YYYY-MM-DD
items[].weekdaymonday … sunday
items[].sourceexception, period oder regular
items[].periodLabelNur bei source: "period": die Bezeichnung aus Tillor, zum Beispiel "Zomer" oder "Winter"
items[].holidayNur wenn dieser Tag ein gesetzlicher Feiertag ist: { id, name, startDate, endDate }
items[].blocksZeitfenster in Minuten ab Mitternacht
items[].closedtrue, 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.

MinutenUhrzeit
54009:00
60010:00
72012:00
78013:00
102017:00
114019: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"
DatumsourceperiodLabel
2026-03-30regular-
2026-03-31regular-
2026-04-01periodZomer
2026-04-02periodZomer

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-settings

Lesen 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

War diese Seite hilfreich?

Auf dieser Seite