API & Webhooks
API & Webhooks
Bygg in Floowlies recensionsdata var som helst. 14 REST-endpoints plus HMAC-signerade realtids-webhooks. Allt över HTTPS, JSON in/ut, scopes per nyckel.
Översikt
REST + JSON
Standardiserade endpoints över HTTPS.
Scopes
Begränsa varje nyckel till exakt vad den behöver.
Webhooks
HMAC-signerade events i realtid.
Rate limit
Standard: 60 anrop/minut per nyckel, burst 20. Högre gräns kan avtalas per plan/kund.
Quickstart
- Logga in på Floowlie och gå till Konto → API & Webhooks.
- Skapa en nyckel, välj scopes och kopiera värdet (den visas bara en gång – nycklar börjar med
flw_live_). - Anropa
/healthför att verifiera nyckeln och se vilka scopes den har. - Bygg din integration – Zapier, Make, n8n, en intern dashboard eller en widget.
https://api.floowlie.se/v1. Direkta anrop till backend-värden blockeras med 403.curl https://api.floowlie.se/v1/health \
-H "Authorization: Bearer flw_live_xxx"Autentisering & scopes
Alla anrop kräver headern Authorization: Bearer flw_live_.... Skapa nycklar från Konto → API & Webhooks.
| Scope | Ger åtkomst till |
|---|---|
| reviews:read | Läs recensioner, AI-utkast och publicerade svar. |
| analytics:read | Läs stats, sentiment, ratings, timeseries och scans. |
| employees:read | Läs medarbetare, deras scans och topplistor. |
| webhooks:read | Läs era registrerade webhooks och leveranshistorik. |
| * | Full läsåtkomst till alla nuvarande och framtida read-endpoints. |
Tips: skapa en separat nyckel per integration. Roterar du en nyckel? Skapa en ny, byt i din integration, återkalla sedan den gamla från Konto-vyn.
Base URL & versionering
https://api.floowlie.se/v1Versionen är inbyggd i pathen (/v1/...). Breaking changes släpps som/v2; nya endpoints och fält i existerande svar räknas inte som breaking. Alla tidsstämplar är ISO 8601 i UTC. Alla request- och response-bodies är JSON.
Endpoint-referens
Alla endpoints är scopade till företaget som äger API-nyckeln. Ingen cross-tenant data lämnar någonsin servern.
Core
GET/health–
Verifierar din API-nyckel och returnerar dina scopes.
Exempelsvar
{
"ok": true,
"company_id": "8c2…",
"scopes": ["reviews:read", "analytics:read", "employees:read"],
"server_time": "2026-06-25T10:00:00Z"
}Analytics
GET/statsanalytics:read
Personal och Floowlies egna skanningar senaste 7/30 dagar; Google-sammanställningar ingår inte.
Exempelsvar
{
"employees": 14,
"scans_last_7_days": 84,
"scans_last_30_days": 421
}GET/analytics/sentimentanalytics:read
Avvecklad: HTTP 410. Google-recensioner sammanställs inte för sentiment.
Exempelsvar
{
"total": 312,
"positive": 268,
"neutral": 28,
"negative": 16,
"positive_pct": 86,
"by_language": { "sv": 240, "en": 60, "ar": 12 }
}GET/analytics/ratingsanalytics:read
Distribution över 1–5 stjärnor med total och snitt.
Exempelsvar
{
"total": 312,
"average": 4.78,
"distribution": { "1": 4, "2": 6, "3": 18, "4": 52, "5": 232 }
}GET/analytics/timeseries?metric=scans&days=30analytics:read
Dagliga counts. metric=scans|reviews, days=1–365 för skanningar, högst 30 för recensioner (default 30).
Exempelsvar
{
"metric": "scans",
"days": 30,
"series": [
{ "date": "2026-05-27", "count": 12 },
{ "date": "2026-05-28", "count": 18 }
]
}GET/analytics/top-employees?period=30d&limit=10analytics:read
Intern medarbetarstatistik i namnordning, utan ranking. Äldre adress behålls. period=all|7d|30d|90d.
Exempelsvar
{
"period": "30d",
"top": [
{ "id": "…", "name": "Sara", "avatar_url": null, "scan_count": 84 }
]
}GET/scans?since=2026-06-01&limit=200analytics:read
Alla scans för företaget. Filtrera med since (ISO-datum), limit 1–500.
Exempelsvar
{
"scans": [
{ "id": "…", "employee_id": "…", "scanned_at": "…", "clicked_through_at": "…" }
]
}Employees & Scans
GET/employeesemployees:read
Lista alla medarbetare med totalt antal QR-scans.
Exempelsvar
{
"employees": [
{ "id": "…", "name": "Sara", "avatar_url": null, "scan_count": 132 }
]
}GET/employees/{id}employees:read
Detaljer för en medarbetare med scan-totaler och senaste scan-tid.
Exempelsvar
{
"employee": {
"id": "…",
"name": "Sara",
"avatar_url": null,
"scan_count": 132,
"last_scan_at": "2026-06-24T19:11:00Z"
}
}GET/employees/{id}/scans?limit=50employees:read
Senaste QR-scans för en specifik medarbetare (max 500).
Exempelsvar
{
"employee_id": "…",
"scans": [
{ "id": "…", "scanned_at": "2026-06-25T08:12:00Z", "clicked_through_at": "2026-06-25T08:12:14Z" }
]
}GET/leaderboardemployees:read
Avslutad. Returnerar HTTP 410; använd intern medarbetarstatistik utan ranking.
Exempelsvar
{ "error": "Den publika topplistan har avslutats." }Reviews
GET/reviews?min_rating=4&language=sv&limit=20reviews:read
Lista recensioner. Filtrera med min_rating, max_rating, since (ISO), language (sv/en/ar/de), limit 1–100.
Exempelsvar
{
"reviews": [
{
"id": "…",
"rating": 5,
"text": "Bästa kaffet i stan!",
"reviewer_name": "Anna",
"created_at": "2026-06-20T13:02:00Z",
"language": "sv",
"status": "published",
"reply": "Tack Anna! …",
"reply_published_at": "2026-06-20T13:30:00Z"
}
]
}GET/reviews/{id}reviews:read
Hämta en specifik recension med AI-utkast och slutligt svar.
Exempelsvar
{
"review": {
"id": "…",
"rating": 5,
"review_text": "…",
"reviewer_name": "Anna",
"review_created_at": "…",
"ai_draft": "…",
"final_reply": "…",
"published_at": "…",
"detected_language": "sv",
"status": "published"
}
}Webhooks
GET/webhookswebhooks:read
Lista era registrerade webhooks och senaste leveransstatus.
Exempelsvar
{
"webhooks": [
{
"id": "…",
"url": "https://example.com/floowlie",
"events": ["review.created", "review.reply_published"],
"is_active": true,
"last_delivery_at": "…",
"last_status": 200
}
]
}SDK-exempel
Hämta senaste 5 svenska 5-stjärniga recensionerna:
curl "https://api.floowlie.se/v1/reviews?min_rating=5&language=sv&limit=5" \
-H "Authorization: Bearer flw_live_xxx"Node / TypeScript:
const res = await fetch("https://api.floowlie.se/v1/analytics/sentiment", {
headers: { Authorization: `Bearer ${process.env.FLOOWLIE_KEY}` },
});
const data = await res.json();
console.log(data.positive_pct, data.by_language);Python:
import requests
r = requests.get(
"https://api.floowlie.se/v1/employees",
headers={"Authorization": f"Bearer {KEY}"},
)
print(r.json())PHP:
$ch = curl_init("https://api.floowlie.se/v1/stats");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer " . getenv("FLOOWLIE_KEY")
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = json_decode(curl_exec($ch), true);
print_r($data);Zapier / Make / n8n: använd en HTTP-modul med GET, lägg headern Authorization: Bearer flw_live_… och peka mot Base URL ovan.
Webhooks
Floowlie POSTar event-payloaden till din URL. Headers vi alltid skickar:
Content-Type: application/jsonX-Floowlie-Event– eventnamnet (t.ex.review.created)X-Floowlie-Delivery– unikt leverans-id (idempotens-nyckel)X-Floowlie-Signature– HMAC-SHA256 avtimestamp.bodymed er webhook-secret, formatsha256=<hex>X-Floowlie-Signature-Legacy– tidigare signatur av enbart råa bodyn, för övergång till tidsstämplad verifieringX-Floowlie-Timestamp– Unix-tid när eventet skickades (avvisa > 5 min skew)
Events
review.createdNy recension synkad från Google.
{
"event": "review.created",
"id": "evt_01HZ…",
"created_at": "2026-06-25T10:00:00Z",
"company_id": "…",
"data": {
"review_id": "…",
"rating": 5,
"text": "Bästa kaffet i stan!",
"reviewer_name": "Anna",
"language": "sv",
"google_review_id": "ChdD…"
}
}review.reply_draftedAI har skapat ett utkast som väntar på godkännande.
{
"event": "review.reply_drafted",
"id": "evt_…",
"company_id": "…",
"data": {
"review_id": "…",
"rating": 4,
"ai_draft": "Tack för din feedback! …",
"requires_approval": true
}
}review.reply_publishedSvar publicerades till Google.
{
"event": "review.reply_published",
"id": "evt_…",
"company_id": "…",
"data": {
"review_id": "…",
"rating": 5,
"final_reply": "Tack Anna! …",
"published_at": "2026-06-25T10:01:00Z"
}
}scan.createdQR-kod skannades av en kund (kopplad till en medarbetare om sådan finns).
{
"event": "scan.created",
"company_id": "…",
"data": {
"scan_id": "…",
"employee_id": "…",
"location_id": "…",
"scanned_at": "2026-06-25T10:00:00Z"
}
}employee.createdNy medarbetare lades till i ert konto.
{
"event": "employee.created",
"company_id": "…",
"data": { "employee_id": "…", "name": "Anna Andersson", "location_id": "…" }
}support.message.createdNytt meddelande i ett av era supportärenden.
{
"event": "support.message.created",
"company_id": "…",
"data": { "thread_id": "…", "message_id": "…", "sender": "admin", "preview": "Hej, …" }
}subscription.changedAbonnemangsplan eller status ändrades.
{
"event": "subscription.changed",
"company_id": "…",
"data": { "tier": "business", "status": "active", "changed_at": "2026-06-25T10:00:00Z" }
}Verifiera signaturen (Node):
import crypto from "crypto";
export function verifyFloowlie(rawBody: string, header: string, timestamp: string, secret: string) {
if (!/^\d+$/.test(timestamp) || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
if (!/^sha256=[a-f0-9]{64}$/.test(header)) return false;
const expected = crypto.createHmac("sha256", secret).update(timestamp + "." + rawBody).digest("hex");
const a = Buffer.from(expected, "hex");
const b = Buffer.from(header.slice(7), "hex");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}Leverans & retries:
- Svara
2xxinom 10 sekunder. Annat räknas som fail. - Misslyckade leveranser försöker vi igen med exponentiell backoff i upp till 24 timmar.
- Använd
X-Floowlie-Deliverysom idempotens-nyckel – samma event kan komma flera gånger.
Fel & rate limits
Standardiserade felkoder över alla endpoints.
| Status | Innebörd | Fältet error |
|---|---|---|
| 400 | Ogiltiga query-parametrar | invalid_parameter |
| 401 | Saknad / ogiltig / återkallad nyckel | Invalid or revoked API key |
| 403 | Nyckeln saknar rätt scope | insufficient_scope |
| 404 | Okänd endpoint eller resurs ej i ert konto | not_found / employee_not_found |
| 429 | Rate limit (standard 60 anrop/min · burst 20) | rate_limit_exceeded |
| 5xx | Serverfel – försök igen med backoff | internal_error |
Alla fel returneras som JSON: { "error": "..." }.
Rate limit i detalj
Standardgränsen är 60 anrop per minut och nyckel, plus en burst på 20, alltså upp till 80 anrop inom samma minutfönster. Gränsen är konfigurerbar per nyckel: vissa planer och kunder kan efter överenskommelse ha ett högre värde.
Varje svar innehåller X-RateLimit-Limit, X-RateLimit-Burst, X-RateLimit-Remaining och X-RateLimit-Reset. När gränsen överskrids svarar API:t med 429, kroppen { "error": "rate_limit_exceeded", "limit": 60, "burst": 20, "retry_after_seconds": 12 } och headern Retry-After i sekunder. Värdet är alltid den tid som återstår av just er nyckels aktuella minutfönster, läs headern och vänta den tiden istället för att anta 60 sekunder.
Changelog
2026-10-17 Google API-innehåll och samtycken. Sparat recensionsinnehåll gallras inom 30 dagar. Recensionstidsserier, betygsfördelning, sentiment och Google-embeds returnerar 410; stats och MCP-översikt innehåller inte Google-sammanställningar. Automatisk publicering kräver ägarens separata samtycke efter övergångstiden.
2026-10-17 Versionsbundet FloowStar-godkännande. Personal, QR-skanningar och skanningsstatistik kräver enhetens godkännande av aktuell regelversion. Annars returneras 403 med floowstar_rules_required. Befintliga gästers QR-länkar påverkas inte.
2026-10-17 Google-recensionsregler. Publika topplistor avslutas. Medarbetarstatistik visas i namnordning utan ranking; godkända recensionssvar köas för utspridd publicering.
2026-10-13 Betrodd klient-IP. IP-baserade gränser och tillåtelselistor använder plattformens betrodda IP, aldrig klientens första X-Forwarded-For-värde.
- 2026-10-13 Säkrare webhooks. Signaturen omfattar nu
timestamp.body; tidigare bodysignatur finns iX-Floowlie-Signature-Legacy. DNS-adresser kontrolleras före leverans och privata adresser blockeras. Oväntade klientfel får neutrala meddelanden och referens-id. - 2026-09-22 Fakturamejl blir underlag automatiskt. Den interna e-posthämtningen (
POST /api/public/email-poll) registrerar nu mejl som klassats som faktura som fakturaunderlag i FloowStock för bolagskonton där tillvaletinvoice_inboxär påslaget. Svaret innehåller ett nytt fältinvoicesmedscanned,imported,skippedochresults. Samma mejl läses aldrig in två gånger, och ingenting tolkas, attesteras eller bokförs automatiskt. Befintliga fält i svaret är oförändrade. - 2026-09-20 Rate limit: 60 anrop/minut + burst 20 är standard. En tidigare changelogpost angav felaktigt 600 anrop/minut som standard. Det faktiska basvärdet är 60 anrop per minut och nyckel med en burst på 20 (upp till 80 anrop inom samma minutfönster). Gränsen är nu konfigurerbar per nyckel och kan höjas för enskilda planer eller kunder efter överenskommelse, ändringen börjar gälla omedelbart. Svaren innehåller även
X-RateLimit-Burst, och429-svar harRetry-Afterberäknad på nyckelns faktiska gräns och fönster. - 2026-09-19 Personal på kedjenivå.
/v1/employees,/v1/employees/:id,/v1/employees/:id/scans,/v1/analytics/top-employeesoch/v1/statsomfattar nu hela kedjans personal, enhetens egna poster plus kedjekollegor som samlat skanningar på enheten. Allascan_counträknas enbart på skanningar som skedde på den enhet nyckeln gäller. Nytt fältpaused(boolean) på medarbetare; avbokad personal räknas inte istats.employees. - 2026-09-10 Samlad fakturering via Huvudföretag. Regeln “fakturering sker per enhet” gäller fortfarande som standard, men en kedja kan nu peka ut ett Huvudföretag som tar emot fakturan för kedjans enheter. Enheter som tillkommer senare läggs till med ett tilläggsavtal som Huvudföretaget signerar.
- 2026-09-04 MCP-servern kräver nu modulen API & Webhooks och har fått tre skrivande verktyg:
save_review_reply,publish_review_replyochupdate_inventory_product. - 2026-09-04 Ny MCP-server på
https://floowlie.se/mcpför AI-assistenter (ChatGPT, Claude m.fl.). OAuth-inloggning och samma behörigheter som i appen. Se AI-assistenter (MCP). - 2026-09-03 Autentiserade supportmeddelanden binder nu avsändaridentiteten till den inloggade användaren.
- 2026-08-27 Alla delar av Floowlie är moduler. FloowStar (QR-koder, personal och intern statistik) kan slås av eller på per företag, precis som FloowAgent, FloowStock och API. Konton utan FloowStar kan inte skapa nya medarbetare eller ta emot QR-skanningar.
- 2026-06-29 Endast den officiella URL:en
https://api.floowlie.se/v1är tillåten. Andra endpoints returnerar403. - 2026-06-25 Nya webhook-events:
scan.created,employee.created,support.message.createdochsubscription.changed. Ny leveranslogg per webhook (status, HTTP-kod, försök, felmeddelande) med manuell retry från översikten. Automatisk retry med exponentiell backoff (1m → 5m → 15m → 1h → 6h, max 5 försök, sedan markeraddead). - 2026-06-25 API-nycklar och webhooks kräver API-modulen. Anrop från konton utan aktiv API-modul returnerar
402. - 2026-06-25 Per-nyckel rate limiting, IP-allowlist per nyckel (IPv4 + CIDR) och visning av senast använd IP i översikten. Svar inkluderar
X-RateLimit-Limit/Remaining/Reset; vid överskridning returneras429medRetry-After. (Gränsvärdet i den ursprungliga texten var felaktigt, se posten 2026-09-20 för den faktiska gränsen.) - 2026-06-25 Webhook-URL:er måste använda
https://. API-nycklar inaktiveras automatiskt om kontot pausas. HMAC-secrets visas endast en gång vid skapande och returneras aldrig av/v1/webhooks. - 2026-06-25 Lade till
/analytics/ratings,/analytics/timeseries,/analytics/top-employees,/scans,/employees/{id}och/webhooks. Ny scopewebhooks:read. - 2026-06-10 Webhooks GA med HMAC-signering och retries.
- 2026-05-20 Initial v1: stats, sentiment, employees, reviews, leaderboard.
Redo att börja?
Skapa en nyckel på 10 sekunder och börja anropa.
Till API-nycklar