Preskoči na sadržaj

JSON API

Javni API je samo za čitanje. Ne traži ključ ni kolačiće, a ključ se nikad ne stavlja na stranicu. Sve adrese su pod https://app.tempact.app/public/v1/.

Objavljeni sadržaj

Odeljak: Objavljeni sadržaj
GET https://app.tempact.app/public/v1/companies/{slug}/content?location=all&lang=sr-Latn
Parametar Podrazumevano Značenje
location all ID lokacije ili sve lokacije
lang osnovni jezik firme Bilo koji kod jezika, na primer en, de ili de-AT. Odgovor nikad nije 404 zbog jezika. Vidite ispod.
  • Odgovor ima ETag. Uz If-None-Match dobijate 304 kad se ništa nije promenilo.
  • Cache-Control: public, max-age=60, must-revalidate.
  • X-Source-Validated-At kaže kad je izvor poslednji put proveren.

Odgovor (šema 1.0)

Odeljak: Odgovor (šema 1.0)
schemaVersion "1.0"
revision string
publicationVersion ceo broj, raste sa svakom objavom
publishedAt ISO vreme
company id, slug, name, currency ("RSD"), description, logo, logoAlt, email, phone, website
locations[] id, name, city, address, contact, zone (IANA vremenska zona),
publicOpeningHours.days["1".."7"] = {open, close} ili {closed: true},
publicExceptions[] = {date, open, close, closed, note},
hoursMismatch, hoursWarning, arrivalInstructions
services[] id, location, name, priceMinor (ceo broj, u parama), currency, minorUnit (2),
duration i buffer (minuti), kind ("main" | "addon"), category, variant,
instructions, compatibleMainServiceIds[]
staff[] id, name, location, serviceIds[], photo, photoAlt, description
theme id, version, rendererKey ("minimal" | "barber" | "package"), package
meta selectionRequired, availabilityIncluded (false), locale

Cena je u najmanjoj jedinici valute: priceMinor: 220000 uz minorUnit: 2 znači 2.200,00 RSD.

Logo i fotografije ekipe su na adresi https://app.tempact.app/public/v1/media/{uuid}.webp.

Ako traženi jezik ne postoji, server bira prvi koji postoji: isti jezik u opštem obliku (de-AT → de), zatim za bs, hr i cnr srpski, zatim engleski, i na kraju osnovni jezik firme. Isto važi za works?lang= i booking/catalog?lang=.

Polje u meta Značenje
locale Jezik koji je stvarno isporučen
locales Svi jezici koje firma nudi
fallbackLocale Osnovni jezik firme
GET https://app.tempact.app/public/v1/companies/{slug}/works?location=&worker=&category=

Opis odgovora je na strani Radovi.

Slobodni termini i samo zakazivanje idu preko obrasca, a ne preko vašeg koda.

Ako firma koristi dodatne mogućnosti, obrazac ih podržava sam: broj osoba (people, a spotsLeft u slobodnim terminima), seanse (series: { index, total }) i depozit (deposit: { amountMinor, status, ipsQr }, gde je status pending, paid ili waived). Trajanje usluge u ponudi termina je trajanje kod izabranog radnika. Za zakazivanje koristite link, prozor ili obrazac. Vaš dizajn može da otvori link sa unapred izabranom lokacijom, radnikom i uslugom iz podataka.

Osvežavanje sajta posle objave

Odeljak: Osvežavanje sajta posle objave

Panel pokazuje da li povezani sajt prikazuje poslednju objavu. Postoje tri načina.

1. Sekcije javljaju same. Uz reportSeen: true sekcije šalju verziju koju prikazuju.

2. Statički sajt potvrđuje build. Posle svakog build-a sajt šalje:

POST https://app.tempact.app/public/v1/companies/{slug}/site-confirm
Content-Type: application/json
{ "integrationId": "...", "publicationVersion": 12, "timestamp": 1793800000, "signature": "..." }

signature je HMAC-SHA256 tajne integracije nad tekstom timestamp.integrationId.publicationVersion, zapisan kao hex. Vreme mora biti u okviru ±300 sekundi.

3. Webhook ka sajtu. Posle svake objave sistem šalje POST na adresu vašeg sajta:

{ "event": "publication", "company": "vas-biznis", "integrationId": "...", "publicationVersion": 12 }

Zaglavlje X-Booking-Signature: t=TIMESTAMP,v1=POTPIS sadrži HMAC-SHA256 tajne nad tekstom TIMESTAMP.TELO_ZAHTEVA. Proverite potpis pre nego što pokrenete novi build.

import { createHmac, timingSafeEqual } from 'node:crypto';
function proveriPotpis(zaglavlje, telo, tajna) {
const { t, v1 } = Object.fromEntries(zaglavlje.split(',').map(d => d.split('=')));
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const ocekivano = createHmac('sha256', tajna).update(`${t}.${telo}`).digest('hex');
return timingSafeEqual(Buffer.from(ocekivano), Buffer.from(v1));
}

Tajnu integracije vidite u panelu, u odeljku Povezivanje sajta. Držite je samo na serveru, nikad u kodu stranice.