API reference
Every public endpoint lives under https://accessiflowfiji.com/v1. All endpoints require authentication except /v1/manifest and /v1/heartbeat, which are public by design (the widget calls them from end users’ browsers).
Authentication
Create a token from Settings → API tokens. The token is shown once on creation, prefixed af_, and hashed server-side.
curl https://accessiflowfiji.com/v1/sites \
-H "Authorization: Bearer af_xxxx…"Tokens can be revoked anytime; requests fail immediately once revoked.
Public endpoints
GET /v1/manifest?site=SITE_KEY
Returns a signed JSON payload describing the site’s widget configuration and domain allowlist. Called by the widget on every page load (cached per visitor for 1 hour). Signature is HMAC-SHA256 over the JSON body.
Cache-Control defaults to public, max-age=3600, stale-while-revalidate=300 in production and no-store in development, so local config changes are visible on the next reload.
POST /v1/heartbeat
One fire-and-forget beacon per widget session (plus one per feature toggle). Used to populate the analytics dashboard. Body:
{
"siteKey": "string",
"eventType": "load" | "feature",
"featureName": "string | null",
"session": "string",
"ts": number
}Session ID is hashed (SHA-256) before storage. IP is never stored — country is read from Vercel / Cloudflare edge headers.
Authenticated endpoints
The v1 authenticated API is scoped to the token owner’s org. Sites, domains, and analytics all operate within that scope.
Sites
GET /v1/sites— list sitesPOST /v1/sites— create sitePATCH /v1/sites/:id— update configDELETE /v1/sites/:id— soft-deleteGET /v1/sites/:id/analytics?range=7|30|90— daily loads + top features
Phase 5 note: the authenticated endpoints ship with the Phase 6 admin work; the widget-side public endpoints are already live. The dashboard UI already calls the same underlying code.
Webhooks
POST /v1/webhooks/paddle
Receives billing events from Paddle. Signature-verified using PADDLE_WEBHOOK_SECRET, idempotent via the paddle_webhook_events table (insert-or-skip on event id). Handles subscription.*, transaction.completed/paid, and transaction.payment_failed. Returns 200 after signature passes so Paddle never retries — processing errors are recorded on the event row for manual replay.
Rate limits
- Writes: 60/min per user, 600/min per IP global
- Manifest reads: no hard cap, CDN-cached for 1h
- Heartbeat: no hard cap, validated per-site-key
OpenAPI spec
A machine-readable OpenAPI 3.1 document ships with the Phase 6 admin work at /v1/openapi.json.