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

    60 req/min per nyckel. Burst 20.

    Quickstart

    1. Logga in på Floowlie och gå till Konto → API & Webhooks.
    2. Skapa en nyckel, välj scopes och kopiera värdet (den visas bara en gång – nycklar börjar med flw_live_).
    3. Anropa /health för att verifiera nyckeln och se vilka scopes den har.
    4. Bygg din integration – Zapier, Make, n8n, en intern dashboard eller en widget.
    Officiell bas-URL: https://api.floowlie.se/v1. Direkta anrop till backend-värden blockeras med 403.
    bash
    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.

    ScopeGer åtkomst till
    reviews:readLäs recensioner, AI-utkast och publicerade svar.
    analytics:readLäs stats, sentiment, ratings, timeseries och scans.
    employees:readLäs anställda, deras scans och topplistor.
    webhooks:readLä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

    url
    https://api.floowlie.se/v1

    Versionen ä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

    json
    {
      "ok": true,
      "company_id": "8c2…",
      "scopes": ["reviews:read", "analytics:read", "employees:read"],
      "server_time": "2026-06-25T10:00:00Z"
    }

    Analytics

    GET/stats

    Totalt antal recensioner, snittbetyg och senaste 7/30 dagar.

    Exempelsvar

    json
    {
      "employees": 14,
      "reviews_total": 312,
      "average_rating": 4.78,
      "scans_last_7_days": 84,
      "scans_last_30_days": 421
    }
    GET/analytics/sentiment

    Fördelning positiv/neutral/negativ och per språk.

    Exempelsvar

    json
    {
      "total": 312,
      "positive": 268,
      "neutral": 28,
      "negative": 16,
      "positive_pct": 86,
      "by_language": { "sv": 240, "en": 60, "ar": 12 }
    }
    GET/analytics/ratings

    Distribution över 1–5 stjärnor med total och snitt.

    Exempelsvar

    json
    {
      "total": 312,
      "average": 4.78,
      "distribution": { "1": 4, "2": 6, "3": 18, "4": 52, "5": 232 }
    }
    GET/analytics/timeseries?metric=scans&days=30

    Dagliga counts. metric=scans|reviews, days=1–365 (default 30).

    Exempelsvar

    json
    {
      "metric": "scans",
      "days": 30,
      "series": [
        { "date": "2026-05-27", "count": 12 },
        { "date": "2026-05-28", "count": 18 }
      ]
    }
    GET/analytics/top-employees?period=30d&limit=10

    Topplista efter scans. period=all|7d|30d|90d.

    Exempelsvar

    json
    {
      "period": "30d",
      "top": [
        { "id": "…", "name": "Sara", "avatar_url": null, "scan_count": 84 }
      ]
    }
    GET/scans?since=2026-06-01&limit=200

    Alla scans för företaget. Filtrera med since (ISO-datum), limit 1–500.

    Exempelsvar

    json
    {
      "scans": [
        { "id": "…", "employee_id": "…", "scanned_at": "…", "clicked_through_at": "…" }
      ]
    }

    Employees & Scans

    GET/employees

    Lista alla anställda med totalt antal QR-scans.

    Exempelsvar

    json
    {
      "employees": [
        { "id": "…", "name": "Sara", "avatar_url": null, "scan_count": 132 }
      ]
    }
    GET/employees/{id}

    Detaljer för en anställd med scan-totaler och senaste scan-tid.

    Exempelsvar

    json
    {
      "employee": {
        "id": "…",
        "name": "Sara",
        "avatar_url": null,
        "scan_count": 132,
        "last_scan_at": "2026-06-24T19:11:00Z"
      }
    }
    GET/employees/{id}/scans?limit=50

    Senaste QR-scans för en specifik anställd (max 500).

    Exempelsvar

    json
    {
      "employee_id": "…",
      "scans": [
        { "id": "…", "scanned_at": "2026-06-25T08:12:00Z", "clicked_through_at": "2026-06-25T08:12:14Z" }
      ]
    }
    GET/leaderboard

    Publik topplista över anställda för företaget.

    Exempelsvar

    json
    {
      "leaderboard": [
        { "employee_id": "…", "name": "Sara", "scan_count": 132, "last_scan_at": "…" }
      ]
    }

    Reviews

    GET/reviews?min_rating=4&language=sv&limit=20

    Lista recensioner. Filtrera med min_rating, max_rating, since (ISO), language (sv/en/ar/de), limit 1–100.

    Exempelsvar

    json
    {
      "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}

    Hämta en specifik recension med AI-utkast och slutligt svar.

    Exempelsvar

    json
    {
      "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/webhooks

    Lista era registrerade webhooks och senaste leveransstatus.

    Exempelsvar

    json
    {
      "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:

    bash
    curl "https://api.floowlie.se/v1/reviews?min_rating=5&language=sv&limit=5" \
      -H "Authorization: Bearer flw_live_xxx"

    Node / TypeScript:

    ts
    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:

    python
    import requests
    r = requests.get(
      "https://api.floowlie.se/v1/employees",
      headers={"Authorization": f"Bearer {KEY}"},
    )
    print(r.json())

    PHP:

    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/json
    • X-Floowlie-Event – eventnamnet (t.ex. review.created)
    • X-Floowlie-Delivery – unikt leverans-id (idempotens-nyckel)
    • X-Floowlie-Signaturesha256=<hex> av råa bodyn med er webhook-secret
    • X-Floowlie-Timestamp – Unix-tid när eventet skickades (avvisa > 5 min skew)

    Events

    review.createdNy recension synkad från Google.
    json
    {
      "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.
    json
    {
      "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.
    json
    {
      "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 scannades av en kund (kopplad till en anställd om sådan finns).
    json
    {
      "event": "scan.created",
      "company_id": "…",
      "data": {
        "scan_id": "…",
        "employee_id": "…",
        "location_id": "…",
        "scanned_at": "2026-06-25T10:00:00Z"
      }
    }
    employee.createdNy anställd lades till i ert konto.
    json
    {
      "event": "employee.created",
      "company_id": "…",
      "data": { "employee_id": "…", "name": "Anna Andersson", "location_id": "…" }
    }
    support.message.createdNytt meddelande i ett av era supportärenden.
    json
    {
      "event": "support.message.created",
      "company_id": "…",
      "data": { "thread_id": "…", "message_id": "…", "sender": "admin", "preview": "Hej, …" }
    }
    subscription.changedAbonnemangsplan eller status ändrades.
    json
    {
      "event": "subscription.changed",
      "company_id": "…",
      "data": { "tier": "business", "status": "active", "changed_at": "2026-06-25T10:00:00Z" }
    }

    Verifiera signaturen (Node):

    ts
    import crypto from "crypto";
    
    export function verifyFloowlie(rawBody: string, header: string, secret: string) {
      // header format: "sha256=<hex>"
      const sig = header.startsWith("sha256=") ? header.slice(7) : header;
      const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
      const a = Buffer.from(expected);
      const b = Buffer.from(sig);
      return a.length === b.length && crypto.timingSafeEqual(a, b);
    }

    Leverans & retries:

    • Svara 2xx inom 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-Delivery som idempotens-nyckel – samma event kan komma flera gånger.

    Fel & rate limits

    Standardiserade felkoder över alla endpoints.

    StatusInnebördFältet error
    400Ogiltiga query-parametrarinvalid_parameter
    401Saknad / ogiltig / återkallad nyckelInvalid or revoked API key
    403Nyckeln saknar rätt scopeinsufficient_scope
    404Okänd endpoint eller resurs ej i ert kontonot_found / employee_not_found
    429Rate limit (60 req/min · burst 20)rate_limited
    5xxServerfel – försök igen med backoffinternal_error

    Alla fel returneras som JSON: { "error": "..." }. Klientbibliotek bör läsa Retry-After på 429-svar och respektera den.

    Changelog

    • 2026-09-04 MCP-servern kräver nu modulen API & Webhooks och har fått tre skrivande verktyg: save_review_reply, publish_review_reply och update_inventory_product.
    • 2026-09-04 Ny MCP-serverhttps://floowlie.se/mcp fö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, statistik och topplista) kan slås av eller på per företag, precis som FloowAgent, FloowStock och API. Konton utan FloowStar kan inte skapa nya anställda eller ta emot QR-skanningar.
    • 2026-06-29 Endast den officiella URL:en https://api.floowlie.se/v1 är tillåten. Andra endpoints returnerar 403.
    • 2026-06-25 Nya webhook-events: scan.created, employee.created, support.message.created och subscription.changed. Ny leveranslogg per webhook (status, HTTP-kod, försök, felmeddelande) med manuell retry från dashboarden. Automatisk retry med exponentiell backoff (1m → 5m → 15m → 1h → 6h, max 5 försök, sedan markerad dead).
    • 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 (standard 600 req/min, justerbar 1–60 000), IP-allowlist per nyckel (IPv4 + CIDR) och visning av senast använd IPi dashboarden. Svar inkluderar X-RateLimit-Limit/Remaining/Reset; vid överskridning returneras 429 med Retry-After.
    • 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 scope webhooks: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