Loopnote API Documentation

This document provides a comprehensive overview of all backend API endpoints available in the Loopnote platform, grouped logically by resource.


1. Widget & Public Endpoints

These endpoints power the public-facing feedback widget embedded on customer websites.

GET /api/widget-settings

Description: Serves configuration settings and statically assigns A/B test variants to anonymous visitors based on their session token.

  • Authentication: None
  • Query Parameters:
    • site_id (String, Required): The unique ID of the site.
    • token (String, Optional): An anonymous user token used to provide deterministic (sticky) A/B test assignments.
  • Success Response (200):
    {
      "plan": "agency",
      "settings": {
        "position": "bottom-right",
        "accent_color": "#18181b",
        "question_text": "How was your experience?",
        "_ab_test_id": "test_123",
        "_ab_variant": "A"
      }
    }
    
  • Error Responses:
    • 400: {"error": "site_id required"}
    • 404: {"error": "Invalid site_id"}
    • 500: {"error": "Internal server error"}

POST /api/feedback

Description: Collects user feedback submitted via the widget and asynchronously dispatches payloads to active external integrations (Zapier, Slack, WhatsApp).

  • Authentication: None
  • Rate Limiting: Free tier sites are securely capped at 100 responses per calendar month. Further requests return a 429.
  • Request Body:
    {
      "site_id": "uuid",
      "rating": 5,
      "message": "Great website!",
      "page_url": "/pricing",
      "trigger_fired": "exit_intent",
      "time_on_page_at_trigger": 45,
      "device_type": "desktop",
      "visit_count": 2,
      "is_returning_visitor": true,
      "anon_user_token": "token_abc",
      "ab_test_id": "test_123",
      "variant_seen": "A"
    }
    
  • Success Response (201):
    { "success": true }
    
  • Error Responses:
    • 400: {"error": "site_id is required"} or {"error": "rating must be 1–5"}
    • 404: {"error": "Invalid site_id"}
    • 429: {"error": "Monthly response limit reached. Upgrade to Pro Builder."}

GET /api/has-reply

Description: Checks if an anonymous user has received any replies to their previous feedback in order to show notification badges in the widget.

  • Authentication: None
  • Query Parameters:
    • site_id (String, Required)
    • token (String, Required): The visitor's anonymous tracking token.
  • Success Response (200):
    {
      "hasReply": true,
      "threads": [
        {
          "feedback_id": "fb_123",
          "original_rating": 3,
          "original_message": "Needs dark mode",
          "original_date": "2026-04-14T...Z",
          "thread_locked": false,
          "messages": [
            { "id": "rep_1", "sender": "owner", "text": "We just added it!", "created_at": "..." }
          ]
        }
      ]
    }
    

POST /api/contact

Description: Submits a contact or support form request from the public website via integration to FormSubmit.

  • Authentication: None
  • Request Body:
    {
      "name": "John Doe",
      "email": "john@example.com",
      "message": "I have a question about pricing."
    }
    
  • Success Response (200): {"success": true}
  • Error Responses: 400 (Missing fields), 500 (Failed to send).

2. Developer API (v1)

These endpoints are exposed externally for customer access via programmatic API Keys.

GET /api/v1/feedback

Description: Retrieves paginated and date-filtered feedback submissions for a specific site.

  • Authentication: API Key (Bearer {key_prefix}_{key})
  • Query Parameters:
    • site_id (String, Required)
    • limit (Number, Optional): Max 100, default 50.
    • page (Number, Optional): Default 1.
    • from (Date String, Optional): Filter start date.
    • to (Date String, Optional): Filter end date.
  • Success Response (200):
    {
      "data": [{ "id": "...", "trigger_type": "...", "response_text": "...", "rating": 5, "created_at": "..." }],
      "pagination": { "page": 1, "limit": 50, "total": 120, "has_more": true }
    }
    
  • Error Responses:
    • 400: {"error": "site_id query parameter is required"}
    • 401: {"error": "Invalid API Key"}
    • 403: {"error": "Site not found or access denied"}

GET /api/v1/sites

Description: Fetches a list of all sites belonging to the authenticated account's user.

  • Authentication: API Key (Bearer {key})
  • Success Response (200):
    {
      "data": [{ "id": "...", "name": "My Site", "domain": "example.com", "plan": "pro" }]
    }
    

GET /api/v1/summary

Description: Fetches the most recently generated AI qualitative summary for a given site.

  • Authentication: API Key (Bearer {key})
  • Query Parameters: site_id (String, Required)
  • Success Response (200):
    {
      "data": { "id": "...", "summary": { "overall_sentiment": "positive", "top_issues": [...] }, "created_at": "..." }
    }
    

3. Dashboard Analytics & Management

Used by the Dashboard to generate intelligence, manage feedback, and handle replies.

POST /api/ai-summary

Description: Analyzes up to 30 days of recent feedback using Google Gemini to generate a structured JSON qualitative insights report.

  • Authentication: Supabase Bearer Token
  • Request Body: {"site_id": "uuid"}
  • Success Response (200):
    {
      "success": true,
      "summary": {
        "overall_sentiment": "positive",
        "satisfaction_score": 8,
        "top_positives": ["UI", "Speed"],
        "action_items": ["Fix mobile menu"],
        "critical_insights": [...]
      }
    }
    
  • Error Responses: 401 (Unauthorized), 403 (Forbidden), 429 (AI API quota exceeded).

POST /api/page-ai-summary

Description: Generates a highly specific UX analysis report based entirely on feedback targeted at a specific URL route.

  • Authentication: Supabase Bearer Token
  • Request Body: {"site_id": "uuid", "url_path": "/pricing"}
  • Success Response (200): {"success": true, "summary": { "page_sentiment": "negative", "core_problem": "..." }}

GET /api/revenue-report

Description: Computes an estimated revenue leak report across the account by analyzing drop-off triggers against average order value and traffic data.

  • Authentication: None strictly enforced by token (Relies on data availability), but inherently restricted to Agency tier plans.
  • Query Parameters: site_id (String, Required)
  • Success Response (200):
    {
      "site_id": "uuid",
      "total_estimated_monthly_loss": 1250.00,
      "trend": "worsening",
      "top_issues": [
        {
          "trigger_type": "pricing_exit",
          "estimated_monthly_loss": 500,
          "recommendation": "Add comparison FAQ..."
        }
      ]
    }
    

DELETE /api/delete-feedback

Description: Hard-deletes a specific feedback entry.

  • Authentication: Supabase Bearer Token (Verifies site ownership)
  • Request Body: {"feedback_id": "uuid"}
  • Success Response (200): {"success": true}

POST /api/replies

Description: Sends a reply to an existing feedback thread. Differentiates between 'owner' (dashboard) and 'user' (widget).

  • Authentication: Supabase Bearer Token (if sender = 'owner'); Widget anonymous token (if sender = 'user').
  • Request Body:
    {
      "feedback_id": "uuid",
      "reply_text": "Thanks! We will look into it.",
      "sender": "owner",
      "token": "optional_if_user"
    }
    
  • Success Response (201): {"success": true, "reply": { ... }}
  • Error Responses: 401, 403, 409 (User already sent follow-up).

GET /api/replies

Description: Fetches all replies corresponding to a specific feedback ID.

  • Authentication: Supabase Bearer Token (Owner side only)
  • Query Parameters: feedback_id (String, Required)

4. A/B Testing Management

Endpoints for configuring, reading, and interacting with A/B Tests.

GET /api/ab-tests

Description: Retrieves all A/B tests associated with a site.

  • Query Parameters: site_id

POST /api/ab-tests

Description: Initiates a new A/B Test definition ensuring no overlapping tests are running for the same dimension.

  • Request Body: {"site_id": "uuid", "dimension": "question_text", "variants": [{ "id": "A", "value": "Test 1" }]}

POST /api/ab-tests/track-view

Description: Increments the view count for a designated A/B test variant when a widget physically renders it.

  • Request Body: {"ab_test_id": "uuid", "variant_id": "A"}

GET /api/ab-tests/[id]

Description: Calculates the live statistical performance (conversion rate) of a test by comparing views mathematically against feedback received.

  • Path Parameter: id (A/B test ID)

PATCH /api/ab-tests/[id]

Description: Manipulates the lifecycle of a test (pause, resume, or finish and permanently apply winner to widget settings).

  • Request Body: {"action": "apply_winner", "winner_variant_id": "A"}

DELETE /api/ab-tests/[id]

Description: Permanently deletes an A/B test.


5. Account, Security & Agency Features

Endpoints meant strictly for tier upgrades, Developer API limits, and Sub-accounts.

GET / POST /api/api-keys

Description: Lists or provisions programmatic API keys (SHA-256 hashed on storage). Returns raw key only once on creation.

  • Authentication: Supabase Bearer Token + Agency Tier Validation.
  • POST Body: {"key_name": "Zapier Integration"}

DELETE /api/api-keys/[id]

Description: Securely revokes an API key (Soft delete flag is_active = false).

GET / POST /api/client-accounts

Description: Lists or provisions white-labeled client sub-accounts managed under an Agency user.

  • Authentication: Supabase Token + Agency Tier Validation.

PATCH /api/client-accounts/[id]

Description: Updates client account profiles or links/unlinks a specific Site to the designated sub-account.

  • Request Body: {"action": "assign_site", "site_id": "uuid"}

DELETE /api/client-accounts/[id]

Description: Deletes a client sub-account from the Agency's control.

POST /api/integrations

Description: Upserts integrations (Slack webhook, Zapier webhook, WhatsApp Meta Credentials) into the site settings JSON payload.

  • Authentication: Supabase Token + Agency Tier Validation.

POST /api/integrations/whatsapp/test

Description: Validates WhatsApp Meta Cloud API configuration by sending a hardcoded test template message to the recipient's phone number.


6. Payments (Razorpay)

POST /api/razorpay/create-order

Description: Safely maps a requested pricing tier into secure billing values and proxies an Order creation call to Razorpay.

  • Authentication: None (Internal user_id passed)
  • Request Body: {"plan": "pro", "billing_cycle": "annual", "currency": "INR", "user_id": "uuid"}
  • Success Response: {"order_id": "order_abc", "amount": 2199900, "currency": "INR"}

POST /api/razorpay/verify-payment

Description: The strict verification loop that ensures Razorpay HMAC SHA256 signatures match prior to finalizing database Upserts into the subscriptions table.

  • Authentication: Signature Validation
  • Request Body: {"razorpay_order_id": "...", "razorpay_signature": "...", "plan": "...", "amount": ...}

7. Admin Operations

Secured routes executing system-wide operations on behalf of Loopnote Founders.

POST /api/admin/action

Description: Enables execution of overriding manual actions (e.g. bypassing payment gateway to grant a manual upgrade).

  • Body Options: {"action": "manual_upgrade", "payload": { "user_id": "...", "plan": "agency" }}

POST /api/admin/alert

Description: Triggers an alert entry to the DB and fires an immediate email notification via Resend notifying founders of critical tier drops/errors.

  • Request Body: {"alert_type": "Payment_Failure", "user_id": "...", "message": "..."}

PATCH /api/admin/alert

Description: Resolves an admin alert.

POST /api/support

Description: Relays logged-in user feedback securely to founder tracking emails via Resend.

  • Authentication: Supabase Bearer Token