Configuration Reference
All environment variables, tenant settings, privacy controls, and webhook configuration options.
Environment Variables
FeedbackLoop AI is configured primarily through environment variables defined in api/.env. The table below lists all available options.
Core Settings
| Variable | Default | Description |
|---|---|---|
PORT |
3500 |
API server port. The Fastify server listens on this port. |
HOST |
0.0.0.0 |
API bind address. Use 127.0.0.1 if behind a reverse proxy on the same machine. |
DATABASE_URL |
postgresql://... |
PostgreSQL connection string. Format: postgresql://user:pass@host:port/dbname. Required |
REDIS_URL |
redis://localhost:6379 |
Redis connection URL. Used for the render job queue. |
JWT_SECRET |
— | Secret key for signing JWT tokens. Must be a strong random string. Required |
PUBLIC_URL |
http://localhost |
Public-facing URL of your FeedbackLoop AI instance. Used for generating embed snippets and webhook URLs. |
PM2 ecosystem config environment variables override .env values. If you set PORT=3500 in .env but ecosystem.config.cjs defines a different PORT, the ecosystem config wins. Always check both files when debugging port issues.
AI Configuration
| Variable | Default | Description |
|---|---|---|
OPENROUTER_API_KEY |
empty | API key for OpenRouter. Required for AI qualification, deep analysis, and chat. Get one at openrouter.ai. |
OPENROUTER_MODEL |
gpt-4o-mini |
Default AI model for qualification and chat. Any OpenRouter-supported model works. |
AI_TEMPERATURE |
0.3 |
Temperature for AI responses. Lower values (0.1-0.3) produce more deterministic, focused outputs. Higher values (0.7-1.0) increase creativity. |
The default temperature of 0.3 is intentionally low. Higher temperatures cause the AI to add filler phrases like "Great!" and "That sounds interesting!" — which degrades the professional tone of qualification conversations.
Email Notifications
| Variable | Default | Description |
|---|---|---|
SENDGRID_API_KEY |
empty | SendGrid API key for email notifications. If not set, email notifications are disabled. |
SENDGRID_FROM_EMAIL |
noreply@example.com |
Sender email address for notifications. Must be verified in your SendGrid account. |
MinIO (Object Storage)
| Variable | Default | Description |
|---|---|---|
MINIO_ENDPOINT |
localhost |
MinIO server hostname. |
MINIO_PORT |
9000 |
MinIO API port. |
MINIO_ACCESS_KEY |
minioadmin |
MinIO access key (username). |
MINIO_SECRET_KEY |
minioadmin |
MinIO secret key (password). |
Change the default MinIO credentials before deploying to production. The minioadmin/minioadmin defaults are well-known and provide full access to all stored session replays.
Tenant Configuration
Each tenant (tracked website) has its own configuration stored in the database. These settings are managed via the admin dashboard or API.
| Setting | Default | Description |
|---|---|---|
name |
— | Human-readable tenant name (e.g., "My SaaS App"). |
apiKey |
auto-generated | Public API key used in the embed snippet. Safe to expose in client-side code. |
apiSecret |
auto-generated | Secret key for authenticated API calls and webhook verification. |
language |
en |
Language for AI qualification. The AI asks follow-ups and generates analysis in this language. Supports any language code. |
allowedOrigins |
* |
Comma-separated list of allowed CORS origins. Set to your domain(s) in production. |
docUrls |
empty | URLs of your documentation. The AI scrapes these and uses them as context for more accurate qualification. Supports HTML and Swagger/OpenAPI. |
API keys can be rotated at any time from the admin dashboard. After rotation, update the embed snippet on your site with the new key. Old keys are invalidated immediately.
Privacy Settings
FeedbackLoop AI provides granular, element-level privacy controls for session replay. These are configured as HTML data attributes on your page elements.
Data Attributes
| Attribute | Effect | Use Case |
|---|---|---|
data-hl-mask |
Text content is replaced with asterisks in the recording. The element structure is preserved. | Email addresses, phone numbers, personal names. |
data-hl-block |
Element is completely blocked from recording. Replaced with a grey placeholder in replay. | Credit card forms, sensitive data areas, third-party iframes. |
data-hl-ignore |
Element is excluded from the recording entirely. Not visible in replay. | Internal toolbars, debug panels, admin-only UI. |
Example Usage
<!-- Mask sensitive text -->
<span data-hl-mask>john.doe@example.com</span>
<!-- Block entire form from recording -->
<form data-hl-block>
<input type="text" name="card-number">
<input type="text" name="cvv">
</form>
<!-- Exclude debug toolbar -->
<div data-hl-ignore class="debug-toolbar">...</div>
Password inputs (<input type="password">) are always masked automatically, regardless of data attributes. You do not need to add data-hl-mask to password fields.
IP Anonymization
IP anonymization is enabled by default. The last octet of IPv4 addresses is zeroed (e.g., 192.168.1.123 becomes 192.168.1.0). Country-level geolocation is preserved for analytics using a local MaxMind database — no external API calls are made.
Bot Filtering
FeedbackLoop AI uses three-layer bot detection to prevent bots from inflating session counts:
- User-Agent matching — 20+ known bot patterns (Googlebot, Bingbot, etc.)
- Reverse DNS lookup — 50+ datacenter hostnames (AWS, GCP, Azure)
- ASN checks — Known cloud provider autonomous system numbers
Webhook Configuration
Webhooks enable the autonomous CI/CD pipeline. When feedback progresses through the pipeline stages, FeedbackLoop AI dispatches HTTP POST requests to your configured endpoint.
Settings
| Setting | Description |
|---|---|
ciWebhookUrl |
URL to receive webhook POST requests. This is your CI/CD pipeline trigger endpoint (e.g., a GitHub Actions webhook, GitLab trigger, or custom endpoint). |
ciWebhookSecret |
Shared secret for webhook signature verification. FeedbackLoop AI signs payloads with HMAC-SHA256 using this secret. Verify the X-Webhook-Signature header on your end. |
Payload Format
Webhook payloads are JSON objects sent as HTTP POST with Content-Type: application/json:
{
"event": "feedback.stage_changed",
"feedbackId": "clx1234...",
"stage": "ci_build",
"previousStage": "linear_issue",
"tenant": "your-tenant-id",
"data": {
"title": "Checkout button unresponsive on Safari",
"category": "bug",
"priority": "P1",
"rootCause": "Race condition in payment handler",
"suggestedFix": "Add mutex lock on cart state",
"sessionReplayUrl": "https://your-domain.com/replay/..."
}
}
Verifying Signatures
import crypto from 'crypto';
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
Always use crypto.timingSafeEqual for signature comparison to prevent timing attacks. Never compare signatures with ===.
Linear Integration
FeedbackLoop AI can automatically create issues in Linear when feedback reaches the appropriate pipeline stage. Configure your Linear API key and team in the admin dashboard.
Auto-created issues include:
- Feedback title and AI-generated summary
- Priority label (P0-P4) based on AI analysis
- Category label (bug, feature, improvement)
- Link to the session replay
- Root cause and suggested fix from deep analysis
- Full chat transcript