Flusso di prenotazione

Endpoint orientati al consumer per la prenotazione di appuntamenti. Questi endpoint vengono utilizzati anche dal widget BookingJS e sono ottimizzati per le integrazioni frontend.

Nessuna autenticazione richiesta

Gli endpoint di prenotazione per i consumer non richiedono una API key. Sono accessibili pubblicamente, poiché sono pensati per i consumer finali. Il controllo degli accessi avviene tramite le impostazioni del canale e i riferimenti alle risorse.

Panoramica

Il flusso di prenotazione standard è composto da tre passaggi:

  1. Recuperare gli appuntamenti disponibili - elenco di tutti gli slot prenotabili
  2. Prenotare l'appuntamento - blocco di 3 minuti per lo slot selezionato
  3. Completare la prenotazione - finalizzare l'appuntamento con i dati del consumer
MetodoEndpointDescrizione
GET/resources/:ref/upcoming_bookablesRecuperare gli appuntamenti disponibili
POST/rest/1/resources/:ref/reserve_appointmentPrenotare l'appuntamento (3 min)
POST/resources/:ref/create_appointment_with_consumerCompletare la prenotazione
POST/products/active_productsRecuperare i prodotti attivi
POST/resources/public_dataDati pubblici delle risorse
OPTIONS/resources/:ref/upcoming_bookablesPreflight CORS

1. Recuperare gli appuntamenti disponibili

Recupera tutte le fasce orarie prenotabili per una o più risorse. I risultati sono raggruppati secondo un formato di data configurabile, per facilitare una UI a due livelli (ad es. vista mensile → elenco giornaliero).

Endpoint
GET /resources/{ref}/upcoming_bookables

Parametri del percorso

ParametroTipoDescrizione
refstringRiferimento risorsa o UUID. Formati: resourceId@providerUuid@platform - riferimento completo; resourceId@platform - forma breve; uuid - UUID diretto della risorsa

Parametri della query

ParametroTipoObbligatorioDescrizione
groupFormatstringNoFormato Joda-Time per il raggruppamento. Tutti i bookable con lo stesso valore finiscono nello stesso gruppo. Predefinito: yyyy-MM-dd. Esempi: MM-yyyy (mensile), MMMM (nome del mese)
timeFormatstringNoFormato per formattedStart/formattedEnd. Predefinito: yyyy-MM-dd HH:mm
languageTagstringNoLanguage tag IETF BCP 47 per la traduzione lato server (ad es. nomi dei mesi). Esempio: de_DE, fr_FR
channelKeystringNoCanale di prenotazione. Predefinito: RESOURCE_PUBLIC. Vedere Channel Keys
refstringNoRiferimenti risorsa aggiuntivi. Può essere specificato più volte per caricare i bookable di più risorse contemporaneamente
prdRefstringNoRiferimento prodotto o UUID. Filtra i bookable che supportano questo prodotto. Tiene conto anche di leadTime/followUpTime del prodotto

Request

Esempio: raggruppamento mensile in francese
curl -X GET "https://www.timum.de/resources/my-resource@myPlatform/upcoming_bookables?groupFormat=MMMM&languageTag=fr_FR"

Response

La response è un oggetto con chiavi dinamiche basate su groupFormat. Contiene inoltre un flag public_visible.

Response (200 OK)
{
  "avril 18": [
    {
      "formattedStart": "2018-04-30 14:00",
      "formattedEnd": "2018-04-30 14:30",
      "start": "2018-04-30T14:00:00+02:00",
      "end": "2018-04-30T14:30:00+02:00",
      "timeslot_uuid": "6cb6df60-48d8-11e8-a5e5-263fa1a58213",
      "product_uuid": "7fc85970-a2d0-11e2-9cd0-1231430706c1",
      "resource_uuid": "636627f0-006c-11ec-a5c8-02e4d9518b64",
      "product_name": "Gesellschaftsspiele spielen",
      "resource_name": "2nd Level Support",
      "contact_channel": null,
      "capacity": 1,
      "capacity_left": 1,
      "products": [],
      "kind": "models.Bookable"
    }
  ],
  "mai 18": [
    {
      "appointment_uuid": "864b80c0-483f-11f0-b6e3-72fe2304273f",
      "formattedStart": "2018-05-02 14:00",
      "formattedEnd": "2018-05-02 14:30",
      "start": "2018-05-02T14:00:00+02:00",
      "end": "2018-05-02T14:30:00+02:00",
      "timeslot_uuid": "267b2d70-48d9-11e8-a5e5-263fa1a58213",
      "product_uuid": "0bd09a60-1d8f-11e9-bf75-06ecf2a1ba22",
      "resource_uuid": "636627f0-006c-11ec-a5c8-02e4d9518b64",
      "product_name": "Video Call 30",
      "resource_name": "2nd Level Support",
      "contact_channel": {
        "type": "location",
        "value": "Telefon und Bildschirmfreigabe (wir rufen Sie an)"
      },
      "capacity": 5,
      "capacity_left": 3,
      "products": [
        { "uuid": "0bd09a60-1d8f-11e9-bf75-06ecf2a1ba22", "name": "Video Call 30" }
      ],
      "kind": "models.LotAppointment"
    }
  ],
  "public_visible": true
}

Tipi di Bookable

kindSignificatoParticolarità
models.BookableSlot proveniente da una disponibilità (timeslot)Diventa un LotAppointment con la prima prenotazione. Usare timeslot_uuid per reserve/create
models.LotAppointmentAppuntamento di gruppo esistente con capacità residuaAppuntamento già creato. Usare appointment_uuid per reserve/create

Bookable vs LotAppointment

Un models.Bookable è uno slot potenziale proveniente da una disponibilità. Non appena il primo consumer prenota, diventa un models.LotAppointment con un nuovo appointment_uuid. Per ulteriori prenotazioni dello stesso slot, è necessario usare questo nuovo UUID!

Campi della response

CampoTipoDescrizione
start / endstringTimestamp ISO 8601 con fuso orario
formattedStart / formattedEndstringOrario formattato secondo timeFormat
timeslot_uuidstringUUID della disponibilità sottostante
appointment_uuidstring?UUID dell'appuntamento (solo per LotAppointment)
product_uuidstring?UUID del prodotto, o null
resource_uuidstringUUID della risorsa
capacitynumberCapacità totale dello slot
capacity_leftnumberPosti liberi residui
contact_channelobject?Canale di contatto con type e value
productsarrayElenco dei prodotti disponibili per questo slot
kindstringmodels.Bookable o models.LotAppointment

Codici di stato

CodiceSignificato
200Riuscito, bookable restituiti
204Nessun bookable disponibile (response vuota)

2. Prenotare l'appuntamento

Prenota temporaneamente un appuntamento per 3 minuti. Durante questo periodo, lo slot può essere prenotato solo dal customer che ha effettuato la prenotazione. Questo evita doppie prenotazioni durante la compilazione del modulo.

Endpoint
POST /rest/1/resources/{ref}/reserve_appointment

Richiamare sempre prima della prenotazione

Richiami sempre questo endpoint prima di usare create_appointment_with_consumer! Anche dopo la scadenza dei 3 minuti è ancora possibile completare la prenotazione - ma se un altro customer è stato più veloce, l'operazione fallisce.

Parametri della query

ParametroTipoObbligatorioDescrizione
refstringNoRiferimento risorsa o canale
channelKeystringNoCanale di prenotazione. Predefinito: RESOURCE_PUBLIC

Request Body

CampoTipoObbligatorioDescrizione
timeslot_uuidstringCondizionale*UUID del timeslot (disponibilità). Da usare per models.Bookable. Applica le impostazioni predefinite della disponibilità al nuovo appuntamento
appointment_uuidstringCondizionale*UUID dell'appuntamento esistente. Obbligatorio per models.LotAppointment
product_uuidstringUUID del prodotto da prenotare
fromstringOrario di inizio del bookable (ISO 8601, UTC)
tostringOrario di fine del bookable (ISO 8601, UTC)

* Per models.Bookable inviare timeslot_uuid. Per models.LotAppointment, appointment_uuid è obbligatorio.

Request

Prenotare l'appuntamento
curl -X POST "https://www.timum.de/rest/1/resources/my-resource@myPlatform/reserve_appointment" \
  -H "Content-Type: application/json" \
  -d '{
    "timeslot_uuid": "6cb6df60-48d8-11e8-a5e5-263fa1a58213",
    "product_uuid": "7fc85970-a2d0-11e2-9cd0-1231430706c1",
    "from": "2025-01-15T13:00:00Z",
    "to": "2025-01-15T13:30:00Z"
  }'

Response

Response (200 OK)
{
  "api-info": { "version": "1" },
  "participation": {
    "uuid": "a48dcf00-483c-11f0-b6e3-72fe2304273f",
    "appointment_uuid": "a48d0bb0-483c-11f0-b6e3-72fe2304273f",
    "timeslot_uuid": "a48e6b40-483c-11f0-b6e3-72fe2304273f",
    "resource_uuid": "636627f0-006c-11ec-a5c8-02e4d9518b64",
    "product_uuid": "0bd09a60-1d8f-11e9-bf75-06ecf2a1ba22",
    "from": "2025-06-16T12:25:00Z",
    "to": "2025-06-16T12:55:00Z",
    "appointment_capacity": 1,
    "appointment_capacity_left": 0,
    "customer_uuid": "a48df610-483c-11f0-b6e3-72fe2304273f",
    "customer_mobile": null,
    "customer_fullName": null,
    "customer_email": null,
    "customer_note": null,
    "state": "RESERVED",
    "formatedAddress": "Telefon und Bildschirmfreigabe (wir rufen Sie an)",
    "messages": []
  },
  "appointments": [
    {
      "uuid": "a48d0bb0-483c-11f0-b6e3-72fe2304273f",
      "kind": "models.LotAppointment",
      "product_id": "0bd09a60-1d8f-11e9-bf75-06ecf2a1ba22",
      "product_name": "Video Call 30",
      "resource_id": "636627f0-006c-11ec-a5c8-02e4d9518b64",
      "from": "2025-06-16T12:25:00Z",
      "to": "2025-06-16T12:55:00Z",
      "state": "ACTIVE",
      "capacity": 1,
      "capacity_left": 0,
      "customers": [
        {
          "customer_placeholder_id": "a48df610-483c-11f0-b6e3-72fe2304273f",
          "customer_uuid": "a48df610-483c-11f0-b6e3-72fe2304273f",
          "participationState": "RESERVED",
          "participation_id": "a48dcf00-483c-11f0-b6e3-72fe2304273f"
        }
      ]
    }
  ]
}

Salvare customer_uuid

Salvi participation.customer_uuid dalla response! Questo valore serve come placeholder_id per la chiamata a create_appointment_with_consumer.

Comportamento della prenotazione

  • La prenotazione è valida per 3 minuti
  • Lo state è RESERVED
  • Alla scadenza, la prenotazione viene eliminata automaticamente
  • capacity_left viene ridotto durante la prenotazione
  • È possibile prenotare anche dopo il timeout - ma senza protezione dalla doppia prenotazione

3. Completare la prenotazione

Conclude la prenotazione con i dati del consumer. Se esiste già un utente con l'email o il numero di telefono indicati, l'appuntamento viene associato a quell'account. In caso contrario, viene creato un nuovo account.

Endpoint
POST /resources/{ref}/create_appointment_with_consumer

Parametri della query

ParametroTipoObbligatorioDescrizione
timeFormatstringNoFormato per gli orari nella response

Request Body

CampoTipoObbligatorioDescrizione
startstringOrario di inizio (ISO 8601)
endstringOrario di fine (ISO 8601)
timeslot_uuidstringUUID del timeslot o dell'appuntamento
product_uuidstringNoUUID del prodotto
placeholder_idstringNo*participation.customer_uuid dalla response di reserve. Identifica la prenotazione
emailstringEmail del consumer
firstnamestringNome del consumer
lastnamestringCognome del consumer
mobilestringNoNumero di cellulare del consumer
messagestringNoMessaggio facoltativo (max. 1024 caratteri)
localestringNoCodice lingua (ad es. de, en). Determina la lingua delle email transazionali
channelKeystringNoCanale di prenotazione. Predefinito: RESOURCE_PUBLIC

* placeholder_id è tecnicamente facoltativo, ma dovrebbe essere sempre inviato per garantire che venga usata la prenotazione del proprio utente.

Request

Completare la prenotazione
curl -X POST "https://www.timum.de/resources/my-resource@myPlatform/create_appointment_with_consumer" \
  -H "Content-Type: application/json" \
  -d '{
    "start": "2025-01-15T13:00:00Z",
    "end": "2025-01-15T13:30:00Z",
    "timeslot_uuid": "6cb6df60-48d8-11e8-a5e5-263fa1a58213",
    "product_uuid": "7fc85970-a2d0-11e2-9cd0-1231430706c1",
    "placeholder_id": "a48df610-483c-11f0-b6e3-72fe2304273f",
    "channelKey": "RESOURCE_PUBLIC",
    "email": "max@example.com",
    "firstname": "Max",
    "lastname": "Mustermann",
    "mobile": "0173 1234567",
    "locale": "de",
    "message": "Ich freue mich auf den Termin."
  }'

Response (Successo)

Response (201 Created)
{
  "api-info": { "version": "1" },
  "createdAppointment": {
    "appointment_uuid": "864b80c0-483f-11f0-b6e3-72fe2304273f",
    "start": "2025-06-17T11:05:00+02:00",
    "end": "2025-06-17T12:05:00+02:00",
    "timeslot_uuid": "864c4410-483f-11f0-b6e3-72fe2304273f",
    "product_uuid": "0bd09a60-1d8f-11e9-bf75-06ecf2a1ba22",
    "resource_uuid": "636627f0-006c-11ec-a5c8-02e4d9518b64",
    "contact_channel": {
      "type": "location",
      "value": "Telefon und Bildschirmfreigabe (wir rufen Sie an)"
    },
    "product_name": "Video Call 30",
    "resource_name": "2nd Level Support",
    "capacity": 1,
    "capacity_left": 0,
    "products": [
      { "uuid": "0bd09a60-1d8f-11e9-bf75-06ecf2a1ba22", "name": "Video Call 30" }
    ],
    "kind": "models.LotAppointment",
    "cancelLink": "https://www.timum.de/rebook/6366c430-006c-11ec-a5c8-02e4d9518b64?..."
  }
}

cancelLink

La response include un cancelLink. Questo link firmato consente al consumer di annullare autonomamente il proprio appuntamento. Può usare questo link nella sua email di conferma.

Response (Errore)

Response (412 Precondition Failed)
{
  "api-info": { "version": "1" },
  "errors": [
    {
      "errorCode": "201",
      "message": "Das überlappt mit einem anderen Termin."
    }
  ]
}

Dettagli dell'algoritmo

  • Se esiste già un utente con l'email o il numero di cellulare, l'appuntamento viene associato a quell'account
  • Gli attributi mancanti (firstname, lastname, mobile) vengono aggiunti all'utente esistente, ma non sovrascritti
  • La lingua del nuovo utente viene ripresa dall'actor CRM (oppure tramite il parametro locale)
  • Per gli appuntamenti di gruppo: la prima prenotazione crea l'appuntamento, le successive aumentano il numero di partecipanti

Codici di stato

CodiceSignificato
201Appuntamento creato con successo
400Campo obbligatorio mancante o non valido
412Slot già prenotato (errorCode 201)

Risoluzione dei problemi

ProblemaCausaSoluzione
"Das überlappt mit einem anderen Termin" (errorCode 201)Slot di una disponibilità già prenotato. La prima prenotazione genera un nuovo appuntamento con un nuovo UUIDUsare il nuovo timeslot_uuid dalla prima response di prenotazione per le prenotazioni successive
"Email mancante" anche se è presente nel bodyProblema di redirect dovuto alla mancanza di www.Assicurarsi di usare https://www.timum.de (con www.)
Redirect 301 senza responsewww. mancante nell'URLUsare sempre https://www.timum.de
AppointmentAlreadyBookedExceptionIl consumer partecipa già a questo appuntamentoUn utente non può partecipare due volte allo stesso appuntamento. Verificare la presenza di duplicati

4. Recuperare i prodotti attivi

Recupera tutti i prodotti attivi/abilitati di una risorsa. L'elenco dei risultati può essere filtrato in base alle impostazioni del canale.

Endpoint
POST /products/active_products

Parametri della query

ParametroTipoObbligatorioDescrizione
refstringCondizionale*Riferimento risorsa o canale. Può essere specificato più volte
tslRefsstringCondizionale*Riferimento appuntamento o disponibilità. Può essere specificato più volte
channelKeystringNoCanale di prenotazione. Predefinito: RESOURCE_PUBLIC

* Deve essere specificato almeno ref o tslRefs.

Request

Recuperare i prodotti
curl -X POST "https://www.timum.de/products/active_products?ref=my-resource@myPlatform&channelKey=RESOURCE_PUBLIC"

Response

Response (200 OK)
{
  "products": [
    {
      "uuid": "92867f70-4836-11e5-bc04-021a52c25043",
      "name": "Besichtigung",
      "description": "",
      "minDuration": 30,
      "maxDuration": 45,
      "leadTimeMinutes": 0,
      "followUpTimeMinutes": 20,
      "exclusive": false
    },
    {
      "uuid": "0bb978c0-5740-11eb-8b95-024759471364",
      "name": "Beratungsgespräch",
      "description": "Ausführliches Beratungsgespräch",
      "minDuration": 60,
      "maxDuration": 90,
      "leadTimeMinutes": null,
      "followUpTimeMinutes": null,
      "exclusive": true
    }
  ]
}

Campi della response

CampoTipoDescrizione
uuidstringID univoco del prodotto
namestringNome visualizzato del prodotto
descriptionstringDescrizione del prodotto (per note ai clienti)
minDurationnumber?Durata minima in minuti
maxDurationnumber?Durata massima in minuti
leadTimeMinutesnumber?Tempo di anticipo (viaggio/preparazione) in minuti
followUpTimeMinutesnumber?Tempo successivo (ritorno/chiusura) in minuti
exclusivebooleanIndica se il prodotto è esclusivo (solo per determinati canali)

5. Recuperare i dati pubblici

Recupera informazioni pubbliche su provider, risorsa, impostazioni del canale e persona di contatto. Utile per la visualizzazione dei widget di prenotazione.

Endpoint
POST /resources/public_data

Parametri della query

ParametroTipoObbligatorioDescrizione
refstringCondizionale*Riferimento risorsa o canale. Può essere specificato più volte
tslRefsstringCondizionale*Riferimento appuntamento o disponibilità. Può essere specificato più volte
channelKeystringNoCanale di prenotazione. Predefinito: RESOURCE_PUBLIC

* Deve essere specificato almeno ref o tslRefs.

Request

Recuperare i dati pubblici
curl -X POST "https://www.timum.de/resources/public_data?ref=my-resource@myPlatform&channelKey=RESOURCE_PUBLIC"

Response

Response (200 OK)
{
  "contact": {
    "name": "Max Makler",
    "email": "kontakt@example.de",
    "mobile": "0173 1234567",
    "phone": "030 12345678"
  },
  "resource": {
    "uuid": "636627f0-006c-11ec-a5c8-02e4d9518b64",
    "name": "Musterstraße 1",
    "description": "Schöne 3-Zimmer-Wohnung mit Balkon",
    "contactChannelType": "",
    "msgHelpText": "",
    "url": "https://example.com/expose/123",
    "imgUrl": "https://cdn.example.com/images/123.jpg"
  },
  "provider": {
    "name": "Mustermakler GmbH",
    "description": "Ihr Partner für Immobilien in Berlin",
    "isThemingAllowed": true,
    "isLocalisationAllowed": true,
    "areCustomFieldsAllowed": true
  },
  "channel": {
    "bookingProcess": "IMMEDIATE"
  }
}

Struttura della response

contact

CampoDescrizione
nameNome della persona di contatto (dal contact profile)
emailIndirizzo email pubblico
mobileNumero di cellulare
phoneNumero di telefono fisso

resource

CampoDescrizione
uuidID univoco della risorsa
nameNome pubblico della risorsa
descriptionDescrizione della risorsa
urlURL esterno (ad es. link all'annuncio immobiliare)
imgUrlURL dell'immagine della risorsa

provider

CampoDescrizione
nameNome calendario/azienda
descriptionDescrizione del provider
isThemingAllowedIndica se è consentito il theming personalizzato
isLocalisationAllowedIndica se è consentita la localizzazione personalizzata
areCustomFieldsAllowedIndica se sono consentiti i campi personalizzati

channel

CampoDescrizione
bookingProcessIMMEDIATE = prenotazione diretta, REQUESTED = richiesta di appuntamento

6. Preflight CORS

I browser inviano automaticamente richieste OPTIONS prima delle richieste cross-origin. timum risponde automaticamente a queste richieste per tutti gli endpoint di prenotazione per i consumer.

Endpoint
OPTIONS /resources/{ref}/upcoming_bookables

Response Headers

CORS Response Headers
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, X-Auth-Token
Access-Control-Max-Age: 36

Supporto CORS automatico

Le richieste cross-origin da qualsiasi origine vengono accettate. Non è necessario configurare nulla di particolare. I browser eseguono automaticamente queste richieste preflight.

Channel Keys

timum supporta 4 canali di prenotazione diversi. Ogni canale ha impostazioni proprie per visibilità, processo di prenotazione e filtro dei prodotti.

channelKeyNome (UI)Utilizzo
RESOURCE_PUBLICLink di prenotazione pubblicoCanale predefinito. Può essere pubblicato pubblicamente
RESOURCE_EXCLUSIVEAccesso di prenotazione esclusivoPer clienti accettati (rubrica)
RESOURCE_REFERENCECalendario di prenotazione incorporatoPer embed generati automaticamente (ad es. portali immobiliari)
CALENDAR_PUBLICPlugin per sito web e calendario complessivoPer plugin per sito web con tutte le risorse

Le impostazioni del canale possono essere configurate nel frontend timum in Risorsa → Abilita prenotazione appuntamenti.

Processi di prenotazione

ProcessoDescrizione
IMMEDIATEPrenotazione diretta. L'appuntamento viene confermato immediatamente. Il consumer riceve una conferma, il provider riceve una notifica
REQUESTEDRichiesta di appuntamento. L'appuntamento deve essere confermato dal provider. Il consumer riceve "Richiesta ricevuta", il provider riceve la richiesta da confermare

Flusso di prenotazione completo

Ecco il flusso completo per la prenotazione di un appuntamento:

Passaggio 1: caricare i bookable

curl "https://www.timum.de/resources/immobilie-123@is24/upcoming_bookables?groupFormat=yyyy-MM-dd&prdRef=besichtigung-30min@is24"

Passaggio 2: prenotare lo slot

curl -X POST "https://www.timum.de/rest/1/resources/immobilie-123@is24/reserve_appointment" \
  -H "Content-Type: application/json" \
  -d '{
    "timeslot_uuid": "6cb6df60-48d8-11e8-a5e5-263fa1a58213",
    "product_uuid": "7fc85970-a2d0-11e2-9cd0-1231430706c1",
    "from": "2025-01-15T14:00:00Z",
    "to": "2025-01-15T14:30:00Z"
  }'

# La response contiene participation.customer_uuid -> da ricordare!

Passaggio 3: completare la prenotazione

curl -X POST "https://www.timum.de/resources/immobilie-123@is24/create_appointment_with_consumer" \
  -H "Content-Type: application/json" \
  -d '{
    "start": "2025-01-15T14:00:00Z",
    "end": "2025-01-15T14:30:00Z",
    "timeslot_uuid": "6cb6df60-48d8-11e8-a5e5-263fa1a58213",
    "product_uuid": "7fc85970-a2d0-11e2-9cd0-1231430706c1",
    "placeholder_id": "a48df610-483c-11f0-b6e3-72fe2304273f",
    "email": "interessent@example.com",
    "firstname": "Max",
    "lastname": "Interessent",
    "mobile": "0173 9876543",
    "locale": "de"
  }'

Argomenti correlati