Skip to content
GetBelkiPublic

About

Open Source AI Search Intelligence. Measure what AI means for your business. Track how your brand is mentioned, cited, and recommended across ChatGPT, Gemini, Google AI Mode, and Google AI Overviews. Understand the signals beyond visibility that are relevant to your business.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

244 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Belki logo

Belki

Open-source AI search intelligence platform.

Self-hosted or managed on Cloudflare. Track how your brand and competitors appear across AI-generated answers, citations, recommendations, ads, and shopping results.

Deploy Belki to Cloudflare

Know when AI recommends you, and when it doesn't.

Belki schedules prompts across ChatGPT, Gemini, Google AI Mode, and Google AI Overviews, captures the returned answers and source evidence, and turns those captures into project-level visibility analytics. It supports multiple isolated workspaces, multiple brands per workspace, and source-specific reporting while retaining the evidence behind every metric.

The default Cloudflare topology is designed for at least one million runs per month on larger self-hosted installations.

Contents

Supported AI platforms

Belki supports six AI platforms through five capture providers, including Perplexity and Microsoft Copilot through Olostep. Each enabled platform runs every active prompt independently. The overview can combine enabled platforms, while prompts, responses, citations, related queries, entities, ads, and shopping data remain separated by their originating source.

Platform Data captured
ChatGPT Search Answers, citations, retrieved sources, fan-out queries, entities, ads, shopping blocks, and retained page evidence
Gemini Answers, citations, retrieved sources, fan-out queries, and entities
Google AI Mode Answers, cited and retrieved sources, fan-out queries, and entities
Google AI Overviews Whether an AI Overview appeared, its answer text, cited sources, and entities
Perplexity Answers, citations, search queries, and entities
Microsoft Copilot Answers, citations, and entities

ChatGPT is enabled by default. Additional sources must be available in the deployment and allowed by the workspace plan. Claude is not part of the current release.

Capture providers

Belki keeps AI-answer collection behind an internal provider interface. The rest of the product works with one normalized capture contract, so analytics, evidence, alerts, and exports do not need provider-specific code.

The current provider order is DataForSEO, Bright Data, Cloro, Oxylabs, then Olostep. An installation operator connects the first account during onboarding, can add or rotate accounts later under Operator → Providers, and chooses:

  • one installation-wide default provider;
  • an optional provider override for each AI platform; and
  • whether each AI platform is available for new collection.

If a platform has no override, Belki starts with the installation default. If a selected override or default cannot serve that platform at dispatch time, routing advances through active, configured, compatible accounts by provider priority. Disabled or unconfigured accounts are never selected.

Provider ChatGPT Gemini Google AI Mode Google AI Overviews Perplexity Copilot
DataForSEO Yes Yes Yes Yes — —
Bright Data Yes — — — — —
Cloro Yes Yes Yes Yes — —
Oxylabs Yes — Yes Yes — —
Olostep Yes Yes Yes Yes Yes Yes

Olostep setup

Apply control migration 0039_olostep.sql and snapshot migration 0009_olostep.sql to all shards before deploying this version (the normal migration command does this). Connect Olostep with an API key under Operator → Providers, then choose it as the default or as a platform override. Enable Perplexity and Copilot there and select them in project settings. Self-hosted workspaces can use all six platforms; managed installations must add the new platforms to their billing plans as needed. Existing managed plan choices and limits are preserved.

The Olostep GEO API runs asynchronously: Belki submits one item per run, polls every 30 seconds, and retrieves the matching parsed result after completion. Typical collection takes 5–8 minutes; Belki stops polling after 30 minutes. Queue recovery resumes stalled polls without submitting another batch. Both standard and live delivery use this asynchronous flow.

Country targeting uses the selected location's ISO country code. Country coverage is parser-specific and enforced by Olostep; unknown countries fail explicitly. This API does not expose city targeting, language overrides, forced web search, or model selection. Answers, citations, retrieved sources, available search-query telemetry, and documented ChatGPT ads/products are normalized. Other commercial modules remain in retained JSON evidence. Reported USD batch cost is recorded when available; credits are not treated as dollars. No API key is needed to run the mocked integration tests.

Provider accounts belong to the installation, not to customer workspaces. Credentials are verified before storage, encrypted with APP_CRYPTO_KEY, and versioned when rotated. The API exposes configuration and health metadata but never returns stored secrets.

Every collection attempt records its provider account, provider, adapter and credential versions, external task ID, state transitions, timestamps, and errors. Operator → Providers summarizes the last 30 days by account and AI platform: submitted, completed, failed or uncertain, in progress, success rate, average latency, and last activity.

Provider plans, credits, balances, spend, and invoices remain in the provider's own dashboard. Belki links to those dashboards but does not reproduce provider billing or attempt to normalize monetary costs across vendors. Belki's Billing page remains responsible only for Belki subscriptions and workspace limits.

flowchart LR
  Onboarding[Installation onboarding] --> First[Connect first provider]
  Operator[Operator: Providers] --> Accounts[Provider accounts]
  Operator --> DefaultChoice[Installation default]
  Operator --> Routes[AI platform choices]

  First --> Accounts
  Accounts --> Vault[Encrypted, versioned credentials]
  DefaultChoice --> Resolver[Provider resolver]
  Routes --> Resolver
  Vault --> Resolver

  Prompt[Prompt + AI platform] --> Resolver
  Resolver --> Compatible{Active, configured, compatible?}
  Compatible -->|Yes| Adapter[Selected provider adapter]
  Compatible -->|No| Stop[Do not dispatch]
  Adapter --> Attempt[Tracked provider attempt]
  Attempt --> Normalize[Normalized capture contract]
  Normalize --> Product[Evidence, analytics, alerts, exports]

  Operator -. credits and invoices .-> Vendor[Provider dashboard]
Loading

Features

Belki has two deployment modes:

  • Self-hosted: the repository default. The installation owner supplies the Cloudflare resources and connects at least one supported capture provider during onboarding. Manual prompt runs are available, and subscription billing is disabled.
  • Managed cloud: a hosted subscription service using platform credentials, modular Stripe or Dodo Payments billing, plan limits, signup codes, and protected operator tools.

Unless labeled otherwise, the features below are available in both modes.

AI Analytics

Install belki-analytics.js to measure sessions originating from recognized AI utm_source values, subsequent page views, approximate visible time, country, device and conversions by page or JavaScript event. Collection is opt-in, with per-project domains, visible built-in mappings, custom aliases and sources, goals and 12 months of history.

AI Analytics → Installation generates the complete tag and provides a temporary test session excluded from real reports. Conversion delivery includes a bounded per-tab retry queue and server deduplication. Conversions and Sources have their own configuration sections. Each section has a direct route: /ai-traffic for Overview, /ai-traffic/installation, /ai-traffic/conversions, and /ai-traffic/sources.

Open-source installs work with the application origin by default. Run pnpm configure:analytics to choose an independent analytics subdomain or an optional CDN script URL. The deployment commands support both modes, sharing the same SDK and collection logic. Operator → Analytics service shows the resolved configuration and can check availability. No Belki-hosted service is required.

See AI Analytics installation, hosting and metric definitions.

Workspaces, projects, and onboarding

  • Users can belong to multiple isolated workspaces and switch between them without mixing projects, memberships, billing, or analytics.
  • Installation onboarding connects the first capture provider before project setup. Guided workspace onboarding then creates the first project and its initial prompts.
  • Every project defines an owned brand and optional primary domain for mention, citation, seller, and competitor comparisons.
  • Projects select one or more available AI platforms, subject to the active plan.
  • Projects can be paused without releasing their plan slot. Scheduled captures, recurring enrichment, and queued analytical work stop until the project is resumed; history and configuration remain available.
  • Workspace owners and administrators can create and edit projects. Archived projects retain their history and can be restored when the plan has room.
  • Project and source selectors preserve the relevant report context and safely return from detail pages when the selected scope changes.

Visibility overview

The 30-day overview provides an All platforms rollup and an individual tab for every enabled source. It includes:

  • owned-brand visibility, Share of Voice, visibility gap, and completed capture counts;
  • AI Overview appearance counts when Google AI Overviews is selected;
  • daily owned-brand and competitor visibility, Share of Voice, or average first-mention position trends;
  • pause intervals rendered as missing-data gaps rather than zero-value results;
  • prompt-set change annotations so changes in the monitored sample are visible;
  • leading citation-source trends, with the project domain identified separately;
  • leading competitors, top products, and recently detected products when the underlying data exists.

The competitor chart displays the owned brand and the four most visible competitors. Share of Voice includes every competitor tracked for that capture. Adding, editing, or removing a tracked brand takes effect for new captures and does not invalidate or hide completed historical position metrics.

Prompt tracking and prompt library

  • Create prompts individually or in bulk, assign tags, search and filter them, and enable, pause, edit, or permanently delete them.
  • Schedule prompts daily or weekly at a local time with a selected language, location, and IANA time zone. Scheduling remains DST-aware.
  • Run an enabled prompt immediately in self-hosted mode; managed plans rely on scheduled runs.
  • Review the latest status, capture count, mentions, mention rate, citations, and change signals for each prompt.
  • Open per-prompt response history and navigate to the exact captured response.
  • Browse a searchable library of proven brand-reputation prompt templates, inspect a template, customize it, and add it with the same locale, schedule, source, and tag controls as a new prompt.
  • Deleting a prompt starts an asynchronous purge across control D1, its snapshot shard, and R2. Aggregate usage history remains for operational integrity.

Responses and evidence

Belki retains a global response explorer as well as history for each prompt. Response detail can show:

  • the captured answer rendered as readable Markdown, including tables;
  • cited sources separately from sources retrieved or considered by the model;
  • shopping results and fan-out queries returned with the answer;
  • tracked-brand and competitor mentions, extracted entities, and entities supplied by the provider;
  • changes from the previous capture and links to recent captures;
  • authorized downloads of normalized raw evidence and, when enabled, the original response-page HTML.

Provider callbacks are authenticated, normalized asynchronously, and recoverable when a postback is missed. Failed or incomplete runs retain enough status data for diagnostics without being counted as completed answers.

Related queries

  • Aggregate recurring fan-out queries generated while an AI platform expands an answer.
  • Search and compare 7-, 30-, 90-, or 365-day periods.
  • See frequency, tracking status, parent prompts, and every matching response.
  • Inspect cited URLs separately from retrieved-but-not-cited URLs in the context of the related query.
  • Turn a useful untracked query into a new monitored prompt in one step.
  • Lists and evidence tables use cursor pagination instead of loading unbounded result sets.

Citation sources

  • Measure citation rate, source share, leading domains, and daily source trends.
  • Separate explicit citations from retrieved search results throughout the UI.
  • Open a source to see its trend, prompts citing it, cited pages, occurrence counts, and links to the exact response evidence.
  • Source and URL tables use bounded cursor pagination for large projects.

Entities and competitors

  • Tracked entities contain the owned brand and competitors included in visibility and Share of Voice reporting.
  • Discovered entities contain brands, companies, people, places, and other names extracted asynchronously from captured answers.
  • Candidate relationship labels and evidence strength distinguish likely competitors from unrelated mentions and provider entities.
  • Expand an entity to review answer evidence and corroboration before tracking, ignoring, or restoring it.
  • Search and filter tracked and discovered entities independently by type, relationship, or review status.
  • Both entity tabs use debounced server-side search and 25-item cursor pages, so thousands of discoveries are never fetched into the browser at once.
  • Versioned v2 extraction validates exact spans from the answer, tolerates malformed model output, classifies competitive context separately, and combines answer, provider, domain, and tracked-brand evidence.
  • Existing retained responses can be backfilled into a new extractor version. Automatic competitor tracking is opt-in and requires repeated strong evidence.

Advertising intelligence

Ads appears after the selected project has captured a sponsored result. Reports are available for sources that actually returned ad data and include:

  • ad appearance rate and daily rendered-versus-served-but-hidden activity;
  • advertisers, destination domains and URLs, observed positions, and prompts;
  • creative copy, images, and favicons mirrored into private R2 storage;
  • 7-, 30-, 90-, and 365-day advertiser detail and links to source snapshots.

Advertisements remain visible in their originating response even when the Ads navigation item is hidden for a project with no current ad data.

Shopping intelligence

Shopping appears for sources that returned product blocks. The catalog and product detail reports include:

  • product and merchant search, period filters, and bounded cursor pagination;
  • visibility, appearances, win rate, average and median position, and position distribution;
  • co-featured products, price history, rating and review-count trends;
  • prompts, merchant observations, and links to the captured response history;
  • owned-seller identification based on workspace domains.

Optional DataForSEO Google Product Info enrichment adds catalog specifications, seller offers, delivery and availability, market price ranges and history, and review data for compatible Google Shopping product identifiers. Automatic enrichment runs at most weekly for each product and locale; administrators can also request an eligible refresh. It does not bulk-backfill historical products.

Alerts, webhooks, and exports

  • Configure change-detection rules and review read or unread alert events in the app.
  • Add workspace-wide public HTTPS webhook destinations for external delivery.
  • Webhook secrets are displayed once. Payloads include an event ID and timestamp and are signed with HMAC-SHA256 in x-ai-tracker-signature.
  • Generate compressed analytics and captured-response indexes asynchronously as CSV or NDJSON, monitor their status, and download completed exports.

Users, roles, and authentication

  • Role-based access uses owner, admin, editor, and viewer permissions.
  • Owners and administrators can invite members, select their role, inspect pending invitations, and revoke an invitation immediately.
  • Invitation links are always displayed once for copying and can optionally be sent with Cloudflare Email Sending. Links are validated before the acceptance form is shown and expire after 7 days.
  • Local password authentication supports one-use password-reset links that expire after 1 hour.
  • Sessions last up to 14 days and are backed by secure cookies and CSRF tokens.

Settings and diagnostics

Settings are divided by ownership boundary:

  • Project: project identity, enabled AI platforms, original HTML retention, Shopping enrichment, entity extraction, automatic competitor tracking, and workload-specific cost warnings.
  • Workspace: workspace identity, active and archived projects, and signed webhook destinations.
  • Diagnostics: administrator-only checks for the control database, all 32 snapshot shards, capture-provider readiness, payment-provider mode, and required runtime bindings.

Capture-provider plans, credits, invoices, and monetary spend remain in each provider's dashboard. The operator provider page reports comparable activity instead: submitted, completed, failed or uncertain, and in-progress attempts, plus success rate, latency, and last activity by provider and AI platform.

Billing and subscriptions

Self-hosted installations show their configured Belki limits without enforcing a subscription plan. Provider billing is not duplicated inside Belki.

Managed cloud adds:

  • an installation-defined subscription catalogue with arbitrary plan names, ordering, limits, allowed sources, currency, and prices;
  • current subscription, monthly limits, and usage reporting;
  • provider-hosted Checkout and customer management through Stripe or Dodo;
  • immediate, prorated upgrades confirmed by the selected payment provider;
  • downgrades scheduled for renewal with an exact transition preview;
  • replacement or cancellation of a pending downgrade;
  • non-destructive allowance enforcement that archives excess projects, pauses excess prompts, and disables excess sources without deleting history;
  • read-only state for cancelled or unpaid workspaces.

Managed operator tools

These capabilities are available only in a managed deployment and must be protected with Cloudflare Access.

  • Create email-bound, one-use signup URLs; list recent codes; and revoke unused codes.
  • Inspect managed workspaces, subscription state, allowances, and operator interventions.
  • Suspend or restore a workspace for support and abuse handling, and reconcile state that normally follows verified payment-provider webhooks.
  • Analyze aggregate citation trends across retained managed projects with source, domain, period, and project filters.
  • Analyze aggregate fan-out telemetry, model activity, query signals, year terms, response coverage, and fan-outs per response without unbounded D1 reads.

Metrics

Metric Definition
Visibility Completed responses mentioning the tracked brand ÷ all completed responses
Share of Voice Tracked-brand appearances ÷ appearances across the owned brand and every competitor tracked for that capture
Average position Mean first-mention rank among brands tracked for that capture; lower is better
Visibility gap Owned-brand visibility minus the visibility of the leading tracked competitor, in percentage points
Citation rate Completed responses containing at least one citation ÷ all completed responses
Ad appearance rate Completed responses containing at least one sponsored result ÷ all completed responses
Product win rate Product appearances at position 1 ÷ all responses in which the product appeared

Share of Voice and visibility gap become available after at least one competitor is tracked. Google AI Overview metrics distinguish a completed search with no AI Overview from a capture in which the surface appeared.

Architecture

Belki runs a React single-page application and Hono API in one Cloudflare Worker. A control D1 database stores tenancy, orchestration, configuration, and aggregate state. Thirty-two snapshot D1 shards distribute detailed captures. R2 stores raw evidence, optional HTML, generated exports, and mirrored advertising assets.

One SQLite-backed Durable Object per workspace serializes usage reservations and project-limit claims so concurrent requests and queues cannot overspend an allowance.

flowchart LR
  Browser[Belki React SPA] --> API[Hono Worker API]
  Operator[Installation operator] --> API
  Cron[Cloudflare Cron Triggers] --> StandardQ[Scheduled task queue]
  API --> LiveQ[Manual task queue]

  API --> Control[(Control D1)]
  Control --> ProviderConfig[Accounts / defaults / AI platform choices]
  Crypto[[APP_CRYPTO_KEY]] -. credential decryption .-> Resolver[Provider resolver]
  ProviderConfig --> Resolver
  StandardQ --> Resolver
  LiveQ --> Resolver

  Resolver --> Registry[Provider registry]
  Registry --> DFSAdapter[DataForSEO adapter]
  Registry --> BrightAdapter[Bright Data adapter]
  Registry --> CloroAdapter[Cloro adapter]
  Registry --> OxyAdapter[Oxylabs adapter]
  Registry --> OlostepAdapter[Olostep adapter]
  DFSAdapter --> Providers[External AI capture providers]
  BrightAdapter --> Providers
  CloroAdapter --> Providers
  OxyAdapter --> Providers
  OlostepAdapter --> Providers
  Resolver --> Attempts[Provider attempt provenance]
  Providers --> Result[Callback / polled / synchronous result]
  Result --> Attempts
  Result --> R2[(Private R2 evidence)]
  Result --> NormalizeQ[Normalization queue]

  NormalizeQ --> Shards[(32 snapshot D1 shards)]
  NormalizeQ --> Control[(Control D1)]
  NormalizeQ --> EntityQ[Entity extraction queue]
  NormalizeQ --> AssetQ[Ad asset queue]
  EntityQ --> WorkersAI[Workers AI]
  AssetQ --> R2

  Shards --> RollupQ[Analytics rollup queue]
  RollupQ --> Control

  Control --> ProductQ[Product enrichment queue]
  ProductQ --> Merchant[DataForSEO Google Product Info]
  Merchant --> ProductPostback[Authenticated product result]
  ProductPostback --> R2
  ProductPostback --> ProductQ

  Control --> Automation[Alerts / exports / webhooks / purges]
  API --> Control
  API --> Shards
  API --> R2
Loading

The control database owns workspaces, users, projects, prompts, schedules, job state, compact snapshot indexes, rollups, ads, entities, enrichment state, alerts, Belki billing, provider configuration and attempt provenance, and exports. Each prompt is assigned to one snapshot shard for its lifetime, avoiding cross-database joins on detail reads. Provider credentials are stored as encrypted, versioned records in the control database; APP_CRYPTO_KEY remains a Worker secret and is never stored beside them.

Capture and analysis flow

flowchart TD
  Prompt[Scheduled or manually requested prompt] --> Source[Enabled AI platform]
  Source --> Resolve[Resolve platform override or installation default]
  Resolve --> Compatible{Compatible provider account available?}
  Compatible -->|No| Blocked[Keep failure state; do not dispatch]
  Compatible -->|Yes| Attempt[Create versioned provider attempt]
  Attempt --> Adapter[Dispatch through selected adapter]
  Adapter --> Mode{Provider execution mode}
  Mode -->|Asynchronous| Async[Submit task with signed callback]
  Mode -->|Synchronous| Direct[Wait for provider response]
  Async --> Callback[Authenticated provider callback]
  Async -. missed callback recovery .-> Recover[Adapter-specific reconciliation]
  Callback --> Capture[Provider result]
  Recover --> Capture
  Direct --> Capture
  Capture --> AttemptState[Update attempt state and provenance]

  Capture --> Evidence[Store raw evidence in R2]
  Evidence --> Normalize[Normalize provider payload into Belki contract]
  Normalize --> Snapshot[Persist answer / sources / products / ads]
  Snapshot --> Rollup[Update analytics and internal usage]
  Snapshot --> Entities{Entity extraction enabled?}
  Snapshot --> Ads{Ad assets present?}
  Snapshot --> Shopping{Eligible product enrichment?}

  Entities -->|Yes| NER[Extract / validate / corroborate entities]
  Ads -->|Yes| Assets[Mirror creative assets to R2]
  Shopping -->|Yes| ProductInfo[Capture Shopping market snapshot]

  Rollup --> Reports[Overview and source-separated reports]
  NER --> Reports
  Assets --> Reports
  ProductInfo --> Reports
Loading

Requirements

  • Node.js 24 or newer
  • pnpm 11
  • A Cloudflare account with Workers Paid
  • Credentials for at least one supported capture provider
  • DataForSEO Merchant Google Product Info access for optional Shopping enrichment
  • A Cloudflare Email Sending domain only when invitation emails are required
  • A Stripe or Dodo Payments account only when managed subscriptions are enabled (configured in the operator UI)

Workers Paid is required by the default topology because it declares one control database and 32 snapshot databases. Workers Free permits fewer D1 databases than this architecture requires.

Email is disabled in the checked-in self-hosted configuration. Invitations still return a copyable link, and the sign-in page hides email password recovery. To enable delivery, onboard a sending domain in Cloudflare Email, set EMAIL_FROM_ADDRESS in wrangler.jsonc, and optionally restrict the EMAIL binding with allowed_sender_addresses. The managed deployment supplies its sender through its managed deployment profile; no Belki sender is inherited by a fork.

Quick start: self-host on Cloudflare

Install Belki in your own Cloudflare account using the steps below. The Deploy button requires this source repository to be publicly accessible.

The software is Apache-2.0 licensed. You pay Cloudflare and your chosen capture provider directly for their services; a Belki subscription is not required. The default installation uses 33 D1 databases and requires Workers Paid. Provider usage and optional enrichment can incur additional charges. Start with one manual prompt before enabling scheduled collection.

  1. Create a Cloudflare Workers Paid account and choose an initial capture provider: DataForSEO, Bright Data, Cloro, Oxylabs, or Olostep.

  2. Generate two different secrets locally. Keep the outputs out of Git, screenshots, issue reports, and shell history shared with other people.

    openssl rand -base64 32
    openssl rand -base64 32
  3. Click Deploy to Cloudflare. Cloudflare creates a fork, provisions the declared Worker, D1, R2, Queue, Durable Object, Workers AI, and asset bindings, then runs the repository's deploy command.

    Deploy to Cloudflare

  4. Enter only these two required application secrets when Cloudflare asks for bindings:

    Secret Value
    APP_CRYPTO_KEY First generated value; encrypts provider credentials and authenticates provider callbacks
    BOOTSTRAP_TOKEN Second generated value; save it for step 6
  5. Wait for the deployment and migrations to finish, then open the generated workers.dev URL. Leaving PUBLIC_APP_ORIGIN empty is intentional for this first deployment: setup records the origin you opened.

  6. The first-run screen appears automatically. Enter the exact BOOTSTRAP_TOKEN, owner details, and workspace details to create the first account. Then select the initial capture provider and enter its credentials. Finally choose managed subscriptions—defining the installation's plans and configuring either Stripe or Dodo—or self-hosted/in-house mode without payments. Belki verifies and encrypts all configured credentials before use. The token cannot create a second owner after setup is complete.

  7. Create a project and a test prompt, enable only the sources you intend to use, and run it once before scheduling recurring collection.

  8. Clone your new fork, authenticate Wrangler, and apply the checked-in R2 lifecycle policy with pnpm r2:lifecycle before enabling original HTML capture.

Self-hosted mode does not use a payment provider. Invitation email is also optional: with the default empty sender, owners can copy invitation links directly from the application.

Use a custom domain

First confirm the workers.dev deployment works. Then edit your fork's wrangler.jsonc so the final HTTPS origin and custom-domain route are deployed together:

"workers_dev": false,
"routes": [
  { "pattern": "tracker.example.com", "custom_domain": true }
],
"vars": {
  // Keep the other checked-in variables unchanged.
  "PUBLIC_APP_ORIGIN": "https://tracker.example.com",
  "EMAIL_FROM_ADDRESS": ""
}

The hostname must belong to a Cloudflare zone in the same account and the origin must not contain a path or trailing slash. Deploy the change, open the custom domain, and update any workspace URL that was saved during the initial workers.dev setup under Settings → Workspace. The configured origin is authoritative for future provider callbacks and generated links. For an existing installation that has already changed domains, use the repair steps in the deployment runbook.

Local development

pnpm install
cp .dev.vars.example .dev.vars
pnpm db:migrate:local
pnpm dev

Configure these secrets in .dev.vars:

Secret Purpose
APP_CRYPTO_KEY Encrypts operator-owned capture and payment-provider credentials and authenticates provider jobs and callbacks; changing it makes stored credentials unreadable and invalidates outstanding jobs
BOOTSTRAP_TOKEN One-time token entered during first-run owner setup

Use independent, high-entropy values for the two application secrets. Add the first provider through the setup screen, then manage provider accounts, the default, and the provider for each AI platform under Operator → Providers. Managed installations also configure the payment account, environment, encrypted API/webhook secrets, installation-defined plan catalogue, and provider-specific webhook URL during installation or under Operator → Payments. The initial GetBelki catalogue is only an editable template: an installer can rename, reorder, add, or remove plans and set each plan's limits, allowed tracking sources, price, and currency before saving the first payment account. Payment secrets are never returned to the browser or stored as Worker bindings. For locally submitted asynchronous tasks, the provider must be able to reach the Worker. Use a deployed staging Worker or secure public tunnel and set the workspace public application URL accordingly. Self-hosted live runs do not need an inbound postback.

Production deployment

For resource provisioning, secret placement, payment-provider configuration, Cloudflare Access, existing-install migration, verification, and rollback, read docs/deployment-and-migration.md. Adapter ownership and the Stripe/Dodo integration contract are documented in docs/payment-provider-adapters.md.

Self-hosted deployment

The Cloudflare Deploy button provisions the declared D1, R2, Queue, Workers AI, and secret bindings and can connect the fork to Workers Builds:

Deploy to Cloudflare

For a manual deployment, first provision the resources declared in wrangler.jsonc in your own account and configure their bindings. Authenticate Wrangler, configure the two required production secrets, and run:

pnpm build
pnpm deploy
pnpm r2:lifecycle

Before first-run setup, set PUBLIC_APP_ORIGIN in wrangler.jsonc to the final HTTPS origin, such as https://tracker.example.com. It is the canonical base for provider postbacks, invitations, password resets, and billing return URLs. Leave it empty only for local development or when you want each workspace owner to manage the URL under Settings → Workspace. A configured value overrides the stored workspace value and prevents a legacy workers.dev hostname from reappearing after a custom-domain migration.

pnpm deploy applies control migrations and the same snapshot migrations to all 32 shards before publishing with Wrangler. pnpm r2:lifecycle replaces the ai-tracker-evidence bucket lifecycle configuration with the checked-in prefix-specific retention rules.

For an interactive release that validates the checkout, verifies required Worker secret names, previews and applies every D1 migration, inspects the migrated provider/payment/plan state, deploys the Worker, and runs a public smoke check, use:

pnpm deploy:guided

The assistant asks whether this is a GetBelki or self-hosted deployment. For a repeatable non-interactive invocation, pass the target explicitly:

pnpm deploy:guided -- --target self-hosted --url https://tracker.example.com --yes
pnpm deploy:guided -- --target getbelki --yes

A pre-launch installation whose only billing state is disposable sandbox data can explicitly reset payments while keeping projects, captures, users, provider configuration, and logical plan definitions:

pnpm deploy:guided -- --target getbelki --reset-test-payments

The reset runs after the additive migrations and before Worker publication. It prints the affected accounts/workspaces and refuses to continue if any live or ambiguous payment marker exists. It then records a CONTROL_DB Time Travel bookmark and requires the exact phrase DISCARD-TEST-PAYMENTS; --yes does not bypass that phrase. For a non-interactive run, the destructive confirmation must also be explicit:

pnpm deploy:guided -- --target getbelki --reset-test-payments \
  --confirm-reset-test-payments DISCARD-TEST-PAYMENTS --yes

This resets Belki's database only. Cancel the discarded subscription and remove its legacy webhook in the provider's sandbox dashboard; the deployment helper does not mutate external Stripe or Dodo objects.

Provider credentials and commercial choices are deliberately completed in the authenticated Belki UI after deployment. This prevents secrets from appearing in shell history and ensures each account is remotely verified before Belki encrypts it in D1. The script prints direct links and the remaining checklist.

Self-hosted mode is the repository default: DEPLOYMENT_MODE=self_hosted and PAYMENT_MODE=disabled. During installation onboarding, the operator connects the first capture provider and then explicitly chooses Self-hosted / in-house or Managed subscriptions. The self-hosted path requires no payment account and disables Checkout. It can later be changed to managed under Operator → Payments by adding or activating a verified payment account. Belki encrypts provider credentials with APP_CRYPTO_KEY before storing them in the control database; credentials can be replaced but are never returned to the browser.

Managed production deployment

Belki's managed profile lives in deployment/getbelki.json, while wrangler.jsonc remains the self-hosting default.

# Publish application code without changing the database schema
pnpm deploy:getbelki

# Apply pending D1 migrations before publishing
pnpm deploy:getbelki:with-migrations

Production changes should pass CI on a feature branch, be reviewed through a pull request, and merge through the protected main branch. The deployment system can then publish the managed profile. Code-only deployments deliberately remain separate from migration-bearing deployments.

flowchart LR
  Branch[Feature branch] --> PR[Pull request]
  PR --> CI[pnpm check / types check / deploy dry run]
  CI --> Merge[Protected main branch]
  Merge --> Publish{Schema migration?}
  Publish -->|No| Code[deploy:getbelki]
  Publish -->|Yes| Migrate[deploy:getbelki:with-migrations]
Loading

Managed cloud

Managed mode uses operator-owned capture-provider accounts and sells prompt tracking, not provider credentials or API credits. The installation operator can choose a default provider and override it for each AI platform.

The table below is GetBelki's current commercial catalogue, not a repository-wide requirement. A fresh Belki installation starts with this editable template and can define 1–8 plans of its own while connecting its first payment account. For each plan the operator sets a stable internal ID, customer-facing name and description, display order, featured state, monthly usage allowance, project and prompt limits, allowed tracking sources, source limit, ISO 4217 currency, and monthly price.

Plan Price Active prompts Projects Tracking sources per project Seats
Starter €10/month 25 1 ChatGPT Unlimited
Studio €29/month 75 5 Up to 2 enabled sources Unlimited
Agency €149/month 250 30 Up to 4 enabled sources Unlimited

The six supported platforms are available according to each plan's allowed sources and the installation's enabled provider routes. Managed operators must enable Perplexity and Microsoft Copilot and add them to the appropriate plans. Each additional source runs the project's active prompts independently.

Set DEPLOYMENT_MODE=managed and enable the PAYMENT_MODE runtime kill switch. After the operator creates the installation owner and capture-provider account, Belki asks for an installation mode. Managed setup requires exactly one verified payment account and lets the operator choose either Stripe or Dodo Payments. Rebill and Polar appear as disabled Coming soon entries so the roadmap is visible without implying that an unimplemented adapter can accept payments. Every provider account maps the installation's logical plans to that provider's external objects, so a later provider can use different IDs and amounts without changing customer entitlements:

  • Stripe uses a test/live secret key, webhook signing secret, one monthly Price ID and amount per active installation plan, and an action Customer Portal configuration ID.
  • Dodo Payments uses a test/live API key, Standard Webhooks signing secret, and one monthly Product ID and amount per active installation plan. Its customer portal is created through Dodo's API.

Plan definitions become the shared installation catalogue when the first payment account is saved. Additional accounts reuse those definitions and only map them to their own Price/Product IDs and amounts. This prevents Stripe and Dodo from silently describing different entitlements.

Copy the unique webhook URL shown for that account into the selected provider. Additional Stripe or Dodo accounts can be added later under Operator → Payments. Changing the installation default affects only new Checkout sessions; each existing workspace remains pinned to the account that created its subscription.

Signup is email-bound and one-use. A platform operator creates a URL through the Platform operations page or POST /api/v1/operator/signup-codes. A workspace remains pending until a verified payment-provider webhook activates it. Protect both /operator* and /api/v1/operator/* with the same Cloudflare Access policy. Operator navigation intentionally performs a full document request so Access can issue or renew its authorization cookie before protected API data is requested. The Worker also verifies that the Access-authenticated email belongs to platform_operators. Disable workers.dev and attach a custom production route before launch.

Belki maintains internal workload budgets for cost and abuse protection. Those weights are implementation details, not a customer-facing credit balance. Reservations occur before paid work: accepted provider work is committed, while pre-submit failures and explicit provider rejections release the reservation.

Operations

Schedule Responsibility
Every 5 minutes Enqueue due prompts, recover stale jobs, enqueue eligible product enrichments, and reconcile product work
Every minute Reconcile billing changes, recover missed source and product postbacks, reconcile purges, entity extraction and ad assets, and advance analytics backfills
Daily at 03:00 UTC Expire sessions, tokens, ingest events, jobs, indexes, hot snapshots, and completed exports
Sunday at 04:00 UTC Refresh the DataForSEO locale catalog and reconcile metric outboxes

The scheduler uses separate standard and live queues, signed provider job tags, idempotent callbacks, retryable normalization, and adapter-specific recovery. Cloudflare observability is enabled and scheduled handlers emit structured metrics. Brand-only migration work uses a separate bulk path of up to 250 snapshots per minute; ordinary tracked-brand changes are forward-effective and do not start a historical project-wide rebuild.

Security and retention

  • Workspace membership and every project read are tenant-scoped.
  • Local password authentication uses secure cookies, CSRF protection, role checks, hashed one-use tokens, and bounded session lifetime.
  • Invitation links expire after 7 days; password-reset links expire after 1 hour; sessions expire after 14 days.
  • Stored provider credentials use AES-256-GCM with key material derived from APP_CRYPTO_KEY; rotation creates a new credential version without exposing prior values.
  • Provider callbacks require a valid signed job tag and are matched to the provider account and external task recorded for the attempt.
  • Stripe webhook signatures are verified before subscription state changes.
  • Managed operator endpoints combine Cloudflare Access identity with an internal operator allowlist.
  • Webhook delivery accepts only public HTTPS destinations and signs each payload.
  • R2 is private; evidence and export downloads are authorized by the Worker.
  • Raw prompts should not contain personal or sensitive information.
Data Default retention
Normalized raw provider results 730 days
Original response-page HTML 90 days when project capture is enabled
Hot snapshot detail 12 months
Completed exports 7 days

Original HTML capture is opt-in per project. Permanent prompt deletion removes its detailed D1 and R2 evidence asynchronously while preserving aggregate usage history needed for operational integrity.

Verification

Run the same aggregate application checks used by CI:

pnpm check
pnpm types:check
pnpm deploy:dry

Maintainers changing Belki's managed deployment must additionally run pnpm deploy:getbelki:dry. Self-hosters do not need the managed deployment profile or payment-provider credentials.

pnpm check runs application and Worker type checking, strict linting, unit tests, Workers integration tests, and the production build. CI also checks both self-hosted and managed deployment packages without publishing them. GitHub Actions uses Node.js 24 and pnpm 11.0.8 and runs on every pull request and push to main.

Entity-extraction releases also have an offline gold-set gate. Keep private or sanitized JSONL fixtures out of Git. pnpm evaluate:entities creates the local stratified sample, v1/v2 predictions, and review page. After review, run:

pnpm benchmark:entities -- --gold <gold.jsonl> --prediction v2=<predictions.jsonl>

Fixture shape, metrics, and acceptance thresholds are documented in evaluation/entity-extraction.

Repository map

  • src/app: React dashboard, onboarding, authentication, and product experience
  • src/worker: Hono API, provider adapters, routing, ingestion, analytics, automation, and scheduled work
  • src/shared: request schemas, provider and source definitions, plan access, activity summaries, and queue contracts
  • migrations/control: tenancy, provider accounts and attempts, orchestration, analytics, entities, ads, enrichment, billing, and project settings
  • migrations/snapshot: detailed response, citation, product, and ad evidence
  • deployment: environment-specific deployment profiles
  • infrastructure: R2 lifecycle configuration
  • scripts/migrate.mjs: control and 32-shard migration runner
  • docs/deployment-and-migration.md: production provisioning and migration runbook
  • docs/public-release-checklist.md: maintainer checklist for approving public release
  • evaluation/entity-extraction: offline entity quality workflow
  • ai-tracker-prd.md: original product and architecture requirements

Contributing and security

Read CONTRIBUTING.md before opening a pull request. Report suspected vulnerabilities privately using the process in SECURITY.md; do not put exploit details or secrets in an issue.

License

Apache-2.0

About

Open Source AI Search Intelligence. Measure what AI means for your business. Track how your brand is mentioned, cited, and recommended across ChatGPT, Gemini, Google AI Mode, and Google AI Overviews. Understand the signals beyond visibility that are relevant to your business.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages