API i webhookovi
Phonio ima REST API za integracije i webhookove za događaje. Sve ide preko istog dashboard servera.
Kompletna referenca javnog API-ja sa svim rutama, parametrima i primjerima živi na api.phonio.co/razvoj. Generiše se iz stvarnog sistema, pa je uvijek usklađena s onim što API zaista radi. Ova stranica je kraći vodič kroz autentikaciju i webhookove.
Autentikacija
Napravi API ključ u Postavke → Za programere (API) (ključ se prikazuje jednom — sačuvaj ga). Svaki zahtjev nosi zaglavlje:
Authorization: Bearer <tvoj-API-ključ>Osnovni URL API-ja vidiš u Postavke → Povezani programi → Make · Zapier · n8n.
Primjeri (čitanje)
# Pregled (KPI, ishodi, potrošnja)
curl -H "Authorization: Bearer $KEY" $API/api/pregled
# Pozivi
curl -H "Authorization: Bearer $KEY" $API/api/pozivi
# Poruke i leadovi (inbox)
curl -H "Authorization: Bearer $KEY" $API/api/porukeWebhookovi (događaji)
Phonio šalje POST na tvoj URL kad se desi događaj: kraj poziva, novi lead, nova poruka, zakazan termin. Podešavaš ih u Postavke → Povezani programi → Webhooks, birajući događaje po webhooku. Format tijela i primjer su na stranici Make · Zapier · n8n.
Webhookovi su najlakši put za povezivanje s vanjskim alatima — ne treba ti kod, samo URL.
Potpis — kako znaš da poruka dolazi od nas
Svaki POST nosi dva zaglavlja:
| Zaglavlje | Šta je |
|---|---|
X-Phonio-Signature | sha256=<hex> — HMAC-SHA256 tijela, potpisan tajnom tvoje firme |
X-Phonio-Event-Id | jedinstven broj događaja, isti kroz sve ponovne pokušaje |
Tajnu vidiš u Postavke → Povezani programi → Webhooks — kao i API ključ, puna se prikazuje samo prvi put, poslije samo početak. Ako je izgubiš, napravi novu.
Potpis se računa nad sirovim tijelom zahtjeva (bajtovima kako su stigli), nikad nad ponovo složenim JSON-om — razmak viška u JSON-u daje drugi potpis.
ocekivano = "sha256=" + hmac.new(tajna.encode(), sirovo_tijelo, hashlib.sha256).hexdigest()
hmac.compare_digest(ocekivano, request.headers["X-Phonio-Signature"])const o = "sha256=" + crypto.createHmac("sha256", tajna).update(sirovoTijelo).digest("hex");Uporedi poređenjem otpornim na mjerenje vremena (compare_digest, timingSafeEqual), ne običnim ==.
Ponovni pokušaji — poruka se ne gubi
Ako tvoj server ne odgovori s 2xx (pad, timeout, greška), ne odustajemo. Događaj čeka u redu na disku i pokušavamo ponovo po rastućim razmacima (oko 1, 5, 15 i 60 minuta). Red preživi i restart našeg sistema.
Poslije zadnjeg pokušaja događaj se označi kao neisporučen i vlasnik dobije obavijest na telefon. Nikad tiho ne odustajemo — ako je nešto propalo, to se vidi.
Zato tvoj server mora podnijeti isti događaj dvaput. Zapamti
X-Phonio-Event-Idi drugi put ga samo potvrdi s 200 bez ponovne obrade — inače ćeš od jednog poziva dobiti dvije narudžbe.
Praktično pravilo: prvo odgovori 200, pa onda obradi. Ako obradu radiš prije odgovora i ona traje dugo, mi ćemo poziv smatrati neuspjelim i poslati ga ponovo.
Šta kad nešto ne stigne
U Postavke → Povezani programi → Webhooks vidiš zadnje isporuke: šta čeka u redu, šta je
uspjelo i šta je odustalo — s razlogom (HTTP 500, timeout, pogrešan URL). To je prvo mjesto
gdje gledaš prije nego što nas zoveš.