Openingsuren API
Opgeloste openingsuren en komende feestdagen ophalen voor een website
Gebruik de opgeloste openingsuren-API als je seizoensuren (bijvoorbeeld Zomer / Winter) of komende feestdagen op een publieke site toont. Tillor past al uitzonderingen, seizoensperiodes en het gewone weekrooster toe, en voegt wettelijke feestdagen in de gevraagde range toe. Je hoeft dat niet opnieuw te implementeren.
Permissie: organization:settings:read of organization:settings:write
API-sleutel blijft server-side
Roep Tillor alleen aan vanuit een server (Next.js Route Handler, Server Component of backend). Zet de sleutel in omgevingsvariabelen. Stuur hem nooit naar de browser.
Authenticatie: zie HTTP API. Probeer het endpoint in de API Playground of via OpenAPI (tag organization-settings).
Endpoint
GET https://tillor.eu/api/orgs/org_abc123/organization-settings/opening-hoursHeaders:
x-api-key: tkn_xxx
X-Tillor-Org-Id: org_abc123Vervang org_abc123 door het organisatie-ID (hetzelfde als in X-Tillor-Org-Id).
Queryparameters
Gebruik of date, of from/to. Combineer ze niet.
| Parameter | Betekenis |
|---|---|
| (geen) | Vandaag in de timezone van de organisatie |
date | Eén kalenderdag (YYYY-MM-DD) |
from | Begindag (inclusief). Zonder to: alleen die dag |
to | Einddag (inclusief). Vereist from. Maximaal 366 dagen |
languageIsoCode | Taal voor feestdagnamen (NL, FR, …). Standaard: locale van de organisatie |
Response
Elk item is één kalenderdag, al opgelost:
| Veld | Betekenis |
|---|---|
timeZone | IANA-timezone van de organisatie |
from / to | Gevraagde range |
holidays | Wettelijke feestdagen die overlap hebben met from–to |
items[].date | Kalenderdag YYYY-MM-DD |
items[].weekday | monday … sunday |
items[].source | exception, period of regular |
items[].periodLabel | Alleen bij source: "period": het label uit Tillor, bijvoorbeeld "Zomer" of "Winter" |
items[].holiday | Alleen als die dag een wettelijke feestdag is: { id, name, startDate, endDate } |
items[].blocks | Tijdvakken in minuten vanaf middernacht |
items[].closed | true als blocks leeg is |
Prioriteit: uitzondering (feestdag of custom range) → laatste matching seizoensperiode → gewoon weekrooster.
Seizoenslabels komen uit Instellingen > Openingsuren. Periodes mogen over de jaarwisseling lopen (bijvoorbeeld 1 november t/m 31 maart). Dagen buiten elke periode vallen terug op het gewone weekrooster (source: "regular", geen periodLabel).
Minuten naar kloktijd
startMinutes / endMinutes zijn minuten vanaf 00:00.
| Minuten | Tijd |
|---|---|
| 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")}`;
}Voorbeelden
Dag in een seizoensperiode
curl -X GET "https://tillor.eu/api/orgs/org_abc123/organization-settings/opening-hours?date=2026-07-15" \
-H "x-api-key: tkn_xxx" \
-H "X-Tillor-Org-Id: org_abc123"{
"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, Zomeruren.
Dag buiten seizoensperiodes
curl -X GET "https://tillor.eu/api/orgs/org_abc123/organization-settings/opening-hours?date=2026-01-15" \
-H "x-api-key: tkn_xxx" \
-H "X-Tillor-Org-Id: org_abc123"{
"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 en 13:00–17:00.
Range over een periodegrens
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" \
-H "X-Tillor-Org-Id: org_abc123"| Datum | source | periodLabel |
|---|---|---|
| 2026-03-30 | regular | — |
| 2026-03-31 | regular | — |
| 2026-04-01 | period | Zomer |
| 2026-04-02 | period | Zomer |
Komende feestdagen
Wettelijke feestdagen zitten in dezelfde response: holidays voor een lijst (naam + datums), items[].holiday als die kalenderdag een feestdag is. Uren blijven het opgeloste rooster; een feestdag zonder ingevulde uitzondering in Tillor volgt het seizoen- of weekrooster (source is dan niet "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" \
-H "X-Tillor-Org-Id: org_abc123"{
"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
}
]
}Het items-voorbeeld hierboven is ingekort; de echte response bevat elke dag in de range. Schoolvakanties zitten niet in dit endpoint; die blijven GET /holidays?kind=school.
Next.js (server)
Voor een weekwidget of “nu open” op een publieke site:
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 ?? "",
"X-Tillor-Org-Id": ORGANIZATION_ID,
},
next: { tags: ["opening-hours"], revalidate: 3600 },
});
if (!response.ok) {
throw new Error(`Tillor opening hours ${response.status}`);
}
return response.json() as Promise<OpeningHoursResponse>;
}holidays is de lijst voor een “komende feestdagen”-blok. items[].holiday is handig in een weekkalender. items[].periodLabel is seizoenstekst (bijvoorbeeld "Zomer" of "Winter"). Cache 1 uur is meestal genoeg.
Cache ongeldig maken (webhook)
Bij elke wijziging van organisatie-instellingen stuurt Tillor organizationSettings:updated (webhook en SSE). Abonneer daarop en haal openingsuren opnieuw op. De payload is expres klein (geen printer-IP’s of het volledige rooster):
{
"event": "organizationSettings:updated",
"data": {
"openingHoursChanged": true
},
"timestamp": 1787829600000
}openingHoursChanged is true als het openingsurenrooster, de timezone of het standaardland wijzigt — dat is wat GET .../opening-hours beïnvloedt. Bij false kun je de openingsuren-cache laten staan.
Voorbeeld 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 aanmaken: zie Webhooks. Event key: organizationSettings:updated (permissie organization:settings:read of organization:settings:write).
Volledig rooster (optioneel)
Alleen nodig als je de seizoenskalender zelf wilt tonen (labels + fromMonth/untilDay), zonder per dag op te lossen:
GET https://tillor.eu/api/orgs/org_abc123/organization-settingsLees openingHoursSchedule.periods (labels zoals "Zomer") en openingHoursSchedule.weekdays (gewoon rooster). Voor de website zelf blijft GET .../opening-hours de eenvoudigste bron.
MCP
In Cursor of Claude: endpoint organizationSettings_listOpeningHours (categorie organizationSettings), argumenten organizationId, optioneel date of from/to, optioneel languageIsoCode.
Gerelateerd
- HTTP API — authenticatie en headers
- HTTP-voorbeelden — algemene cURL-voorbeelden
- Webhooks —
organizationSettings:updatedvoor cache-revalidatie - Organisatie-instellingen — openingsuren instellen in Tillor