Skip to Content
Esempi

API degli orari di apertura

Recuperare per un sito web gli orari di apertura risolti e i prossimi festivi

Ultimo aggiornamento il

Usa l'API degli orari di apertura risolti se su un sito pubblico mostri orari stagionali (ad esempio Estate / Inverno) o i prossimi festivi. Tillor applica già eccezioni, periodi stagionali e il normale orario settimanale, e aggiunge i festivi legali nell'intervallo richiesto. Non devi implementarlo di nuovo.

Permesso: organization:settings:read oppure organization:settings:write

La chiave API resta lato server

Chiama Tillor solo da un server (Route Handler di Next.js, Server Component o backend). Metti la chiave nelle variabili d'ambiente. Non inviarla mai al browser.

Autenticazione: vedi API HTTP. Prova l'endpoint nel riferimento API o tramite OpenAPI (tag organization-settings).

Endpoint

GET https://tillor.eu/api/orgs/org_abc123/organization-settings/opening-hours

Header:

x-api-key: tkn_xxx

Sostituisci org_abc123 con l'ID della tua organizzazione.

Parametri di query

Usa o date, o from/to. Non combinarli.

ParametroSignificato
(nessuno)Oggi nel fuso orario dell'organizzazione
dateUn singolo giorno di calendario (YYYY-MM-DD)
fromGiorno iniziale (incluso). Senza to: solo quel giorno
toGiorno finale (incluso). Richiede from. Al massimo 366 giorni
languageIsoCodeLingua dei nomi dei festivi (NL, FR, …). Predefinito: locale dell'organizzazione

Risposta

Ogni elemento è un giorno di calendario, già risolto:

CampoSignificato
timeZoneFuso orario IANA dell'organizzazione
from / toIntervallo richiesto
holidaysFestivi legali che si sovrappongono a from–to
items[].dateGiorno di calendario YYYY-MM-DD
items[].weekdaymonday … sunday
items[].sourceexception, period o regular
items[].periodLabelSolo con source: "period": l'etichetta da Tillor, ad esempio "Zomer" o "Winter"
items[].holidaySolo se quel giorno è un festivo legale: { id, name, startDate, endDate }
items[].blocksFasce orarie in minuti dalla mezzanotte
items[].closedtrue se blocks è vuoto

Priorità: eccezione (festivo o intervallo personalizzato) → ultimo periodo stagionale corrispondente → normale orario settimanale.

Le etichette stagionali provengono da Impostazioni > Orari di apertura. I periodi possono attraversare il cambio d'anno (ad esempio dal 1° novembre al 31 marzo). I giorni fuori da ogni periodo ricadono sul normale orario settimanale (source: "regular", nessun periodLabel).

Dai minuti all'ora dell'orologio

startMinutes / endMinutes sono minuti dalle 00:00.

MinutiOra
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")}`;
}

Esempi

Giorno in un periodo stagionale

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, orari estivi.

Giorno fuori dai periodi stagionali

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 e 13:00–17:00.

Intervallo a cavallo di un confine di periodo

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"
DatasourceperiodLabel
2026-03-30regular-
2026-03-31regular-
2026-04-01periodZomer
2026-04-02periodZomer

Prossimi festivi

I festivi legali sono nella stessa risposta: holidays per un elenco (nome + date), items[].holiday se quel giorno di calendario è un festivo. Gli orari restano l'orario risolto; un festivo senza eccezione compilata in Tillor segue l'orario stagionale o settimanale (source non è allora "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
    }
  ]
}

L'esempio di items qui sopra è abbreviato; la risposta reale contiene ogni giorno dell'intervallo. Le vacanze scolastiche non sono in questo endpoint; restano GET /holidays?kind=school.

Next.js (server)

Per un widget settimanale o un "ora aperto" su un sito pubblico:

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 è l'elenco per un blocco "prossimi festivi". items[].holiday è utile in un calendario settimanale. items[].periodLabel è il testo stagionale (ad esempio "Zomer" o "Winter"). Una cache di 1 ora di solito basta.

Invalidare la cache (webhook)

A ogni modifica delle impostazioni dell'organizzazione Tillor invia organizationSettings:updated (webhook e SSE). Iscriviti a questo evento e recupera di nuovo gli orari di apertura. Il payload è volutamente piccolo (niente IP delle stampanti né l'intero orario):

{
  "event": "organizationSettings:updated",
  "data": {
    "openingHoursChanged": true
  },
  "timestamp": 1787829600000
}

openingHoursChanged è true se cambiano l'orario di apertura, il fuso orario o il paese predefinito: è ciò che influenza GET .../opening-hours. Con false puoi lasciare la cache degli orari di apertura com'è.

Esempio di Route Handler di Next.js:

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 });
}

Creare un webhook: vedi Webhook. Chiave dell'evento: organizationSettings:updated (permesso organization:settings:read oppure organization:settings:write).

Orario completo (facoltativo)

Serve solo se vuoi mostrare tu stesso il calendario stagionale (etichette + fromMonth/untilDay), senza risolvere giorno per giorno:

GET https://tillor.eu/api/orgs/org_abc123/organization-settings

Leggi openingHoursSchedule.periods (etichette come "Zomer") e openingHoursSchedule.weekdays (orario normale). Per il sito web stesso GET .../opening-hours resta la fonte più semplice.

MCP

In Cursor o Claude: endpoint organizationSettings_listOpeningHours (categoria organizationSettings), argomenti organizationId, facoltativamente date oppure from/to, facoltativamente languageIsoCode.

Correlati

Questa pagina è stata utile?

In questa pagina