Lokly API

REST API for accessing reviews and business data programmatically. Currently in scaffold — read endpoints only.

Base URL

https://lokly.ai/api/v1

Authentication

Bearer token in the Authorization header. Get a key from your account manager.

curl https://lokly.ai/api/v1/business \
  -H "Authorization: Bearer lk_live_XXXXXXXXXXXX"

Scopes

  • reviews:read — list reviews across all your businesses
  • business:read — list and retrieve business profiles

GET /api/v1/business

Returns every active business the key owner is associated with.

{
  "data": [
    {
      "id": "cluxxxxx",
      "name": "Acme Cafe",
      "category": "restaurant",
      "city": "Bengaluru",
      "countryCode": "IN",
      "googleRating": 4.6,
      "googleReviewCount": 312,
      "googlePlaceId": "ChIJxxx",
      "createdAt": "2025-04-15T10:30:00.000Z"
    }
  ]
}

GET /api/v1/reviews

Paginated review feed. Newest first.

Query params: limit (default 50, max 200), cursor (for pagination).

{
  "data": [
    {
      "id": "clrxxxxx",
      "businessId": "cluxxxxx",
      "platform": "GOOGLE",
      "rating": 5,
      "authorName": "Alia",
      "content": "Best coffee in town.",
      "aiResponse": "Thanks Alia — see you again soon!",
      "sentiment": "positive",
      "publishedAt": "2025-06-01T08:12:00.000Z",
      "createdAt": "2025-06-01T08:14:00.000Z"
    }
  ],
  "pagination": {
    "nextCursor": "clrxxxxx",
    "hasMore": true
  }
}

Errors

  • 401 — missing/invalid Bearer token (header sets WWW-Authenticate: Bearer)
  • 403 — key valid but missing required scope
  • 429 — coming soon (rate limiting per plan)

Webhooks

Subscribe to events with signed HTTP POST callbacks. Retries with exponential backoff (1m, 5m, 15m, 1h, 4h, 12h) up to 6 attempts.

Supported events:

  • REVIEW_CREATED
  • REVIEW_REPLIED
  • CAMPAIGN_SENT
  • NEGATIVE_FEEDBACK_RECEIVED

Headers Lokly sends:

  • X-Lokly-Event: REVIEW_CREATED
  • X-Lokly-Delivery: clxxxxx
  • X-Lokly-Signature: t=1719000000000,v1=abc123…

Verifying the signature (Node example):

import { createHmac } from 'crypto'

function verify(secret: string, payload: string, header: string): boolean {
  const parts = Object.fromEntries(header.split(',').map(s => s.split('=', 2)))
  const ts = parseInt(parts.t, 10)
  if (Math.abs(Date.now() - ts) > 5 * 60 * 1000) return false  // reject > 5 min old
  const expected = createHmac('sha256', secret).update(`${ts}.${payload}`).digest('hex')
  return parts.v1 === expected
}

To register a webhook, request a key from sales. Self-serve registration ships in v1.1.