Documentation

TruIntel Platform Documentation

All the necessary documentation for the TruIntel services is found here.

Getting Started

What is TruIntel?

TruIntel is an AI Engine Optimization (AEO) platform for the era of AI-assisted search. As buyers shift from typing keywords into Google to asking ChatGPT, Claude, Gemini, Perplexity, and Google AI Overview, TruIntel measures and improves how those AI engines perceive, rank, and cite your brand. It pairs that AEO core with a full SEO toolkit, an AI-optimized CMS, traffic and lead intelligence, and automated weekly reporting.

Where traditional SEO optimizes for one ranking algorithm, AEO optimizes for the way large language models recommend brands inside conversational answers. TruIntel runs your real customer questions through all five AI engines on a schedule, parses every answer for whether you are recognized, where you rank, the sentiment around you, and whether a source links back to you, then turns that into a single Visibility Score and a queue of fixes.

AI Visibility Monitoring

Track how ChatGPT, Claude, Gemini, Perplexity, and Google AI Overview mention, rank, and cite your brand against competitors.

SEO Toolkit

Site Health, PageSpeed, on-page audits, crawler, keyword and backlink research, GSC sync, indexation, rank tracking, and CTR analysis.

AI Insights & Tasks

Weekly AI-generated insights and an actionable task queue, powered by a Gemini-driven analysis pipeline.

AI-Optimized CMS

Generate, score, optimize, schedule, and publish content engineered to be cited by AI engines.

Traffic Classification

Classify visitors as human, good agent, bad bot, or synthetic in real time using a four-factor model.

Lead Verification

Score and verify form submissions to filter fake leads and route only real prospects to sales.

ChatGPT

ChatGPT

OpenAI gpt-5.4-mini via the Responses API with the web_search tool.

Claude

Claude

Anthropic claude-haiku-4-5 with server-side web search enabled.

Gemini

Gemini

Google gemini-3.1-flash-lite with Google Search grounding.

Perplexity

Perplexity

Perplexity sonar, routed as perplexity/sonar through OpenRouter.

Google AI Overview

Google AI Overview

Google's own AI Overview, captured via SearchAPI.io (not a model TruIntel runs).

Where the product lives

The TruIntel app runs at app.truintel.ai. These docs live at truintel.ai/docs. Sign up, onboarding, and every feature described here happen inside the app.

Quick Start Guide

You can get your first AI visibility check running in a single sitting. The flow moves from account creation, through choosing a plan, into a guided brand-setup wizard that ends by firing your first full check across all five AI engines.

1

Create your account

Sign up at app.truintel.ai with email and password (verified by a 6-digit OTP) or with Google. Google accounts are auto-verified.

2

Name your organization

Create a workspace that holds your brands, team members, and billing. Each user can own exactly one organization.

3

Choose a plan

Pick a paid plan via Razorpay checkout, or activate the permanent Free plan. Plan selection sits between organization creation and brand setup.

4

Add your brand

Enter brand name, domain, and a 50-500 character description, pick a country, and optionally capture a Brand Voice profile.

5

Pick topics and prompts

Accept or edit AI-suggested topics, then expand each to load suggested prompts (the real questions customers ask AI engines about your space).

6

Confirm competitors

Review AI-discovered competitors (auto-selected up to your plan limit) and add your own. Their visibility is benchmarked against yours.

7

Connect Google Search Console (paid plans, optional)

Link GSC for real keyword, click, and position data. Free users see this step locked; everyone can skip it.

8

Launch

Hit Start Visibility Check on the Review step. TruIntel fires your first full AEO check plus a full SEO refresh and on-page audit in the background.

Not sure what to track?

TruIntel suggests topics, prompts, and competitors for you using an AI suggestion engine tuned to your brand and industry. You only need to review and confirm.

How long the first check takes

The first full visibility check runs across all five AI engines and takes roughly 5 minutes to populate. PageSpeed is not run automatically at launch — trigger it manually from the SEO section when you want it.

Authentication & Account Security

TruIntel uses JWT-based authentication with a short-lived access token and a rotating refresh token. You can sign up with email and password or with Google, and invited teammates join automatically when they verify or sign in for the first time.

MethodHow it worksNotes
Email & PasswordRegister, then verify a 6-digit OTP emailed to you. Login is blocked until your email is verified.OTP valid 10 minutes, max 5 attempts; an unverified login re-sends a fresh code.
Google OAuthFull-page redirect to Google consent, then back to the app with tokens. Not a popup.Scope is openid email profile; Google accounts are auto-verified and linked to a matching email account.
Team invitationAn invited email auto-joins the organization on first verify or Google signup.The first organization joined becomes the active workspace.
Password recoveryForgot-password emails an OTP; reset-password takes the email, OTP, and new password.Reset also marks the email verified. Google-only accounts cannot change a password.

Password requirements

  • 8 to 100 characters long.
  • At least one uppercase letter, one lowercase letter, and one digit (no symbol is required).
  • Stored hashed with bcrypt; passwords are never persisted in plain text.

OTP lifecycle

  • Six numeric digits, delivered by email via Resend.
  • Valid for 10 minutes; a new request resets the attempt counter.
  • Up to 5 wrong attempts — on the fifth the code is invalidated and you must request a new one.
  • Used for both email verification at signup and password reset.

Token security

The access token (JWT, HS256) expires after 30 minutes and is held in an in-memory variable mirrored to localStorage so a refresh restores your session. The refresh token lasts 7 days, is SHA-256 hashed in the database, and rotates on every use. A single in-flight refresh is shared to avoid races, refresh fires about 2 minutes before expiry, and the refresh token is also set as an HttpOnly SSO cookie on .truintel.ai for cross-subdomain login.

reCAPTCHA never locks you out

Auth forms are protected by reCAPTCHA in fail-open mode: a missing token or an unreachable verification service is soft-passed and logged, so a broken widget will not block a real login. Only a supplied-but-forged token is rejected.

Login

/login

Email/password or Google sign-in.

Register

/register

Create a new account.

Verify Email

/verify-email

Enter the 6-digit OTP.

OAuth Callback

/auth/callback

Lands here after Google consent with tokens.

Forgot Password

/forgot-password

Request a reset OTP.

Reset Password

/reset-password

Set a new password with email + OTP.

Account Ready

/account-ready

Post-setup confirmation screen.

Organizations & Multi-Workspace

An organization is the top-level workspace that owns your brands, team members, plan, and billing. Understanding how organizations resolve and switch is key for anyone who belongs to more than one.

  • Each user can OWN exactly one organization — creating a second returns an error. The creator becomes the OWNER.
  • A user can BELONG to many organizations through invitations, even though they can only own one.
  • A newly created organization starts with no plan, so plan selection is the immediate next step.
  • Switching organizations clears the selected-brand and query caches so you always see the right workspace data.

How your current organization is resolved

When you load the app, TruIntel picks your active workspace using a single deterministic rule (never an arbitrary first-membership pick), which prevents the intermittent plan-bounce issues common to multi-org accounts.

1

Explicit active choice

The membership matching your saved active organization is used first.

2

An organization you own

If no active choice is set, an organization you own is selected next.

3

Oldest membership

Otherwise the oldest membership (by creation date) wins, keeping resolution stable across sessions.

Switching workspaces

If you belong to multiple organizations, use the workspace switcher to set a new active organization. The switch updates your account preference and reloads brands and data for the chosen workspace.

Onboarding Walkthrough

Onboarding is a guided wizard that takes you from a brand-new account to a live, monitored brand. The organization step is skipped automatically if you already have a workspace, and progress is saved so you can resume where you left off.

1

Organization

Name your workspace. This creates (or updates) the organization and routes you to plan selection. Skipped if an organization already exists.

2

Choose Plan

Pick a paid plan via Razorpay or activate the one-time Free plan. The Start Free button is disabled once the Free plan has been used by the organization.

3

Brand

Enter brand name, domain (required and validated), a 50-500 character description, and country. Optionally capture a Brand Voice profile. Saving loads AI topic suggestions.

4

Topics & Prompts

Accept AI-suggested topics (capped by plan), expand each to lazily load suggested prompts, and select your set. Paid plans also see an AI search-volume column per prompt.

5

Competitors

AI-discovered competitors are auto-selected up to your plan limit; add or remove as needed before saving.

6

Google Search Console

Optional, paid-plans only. A popup OAuth lets you pick a GSC property. Free users see a locked card; anyone can skip.

7

Review & Launch

Start Visibility Check bulk-creates your queries, completes onboarding, and navigates to the Overview while the first full check runs in the background.

What launch actually triggers

Submitting the Review step fires the first full AEO visibility check across all five AI engines, bulk-creates your competitors, and kicks off a full SEO refresh plus an on-page check. This takes about 5 minutes to populate. PageSpeed is not part of launch and is run manually later.

Brand Voice (optional)

Capturing a Brand Voice — tone (educational, conversational, or authoritative), audience, and preferences like em-dash and CTA usage — tunes AI content generation in the CMS. You can set or edit it later under Settings, Brand Voice.

Description length is enforced

The onboarding form requires a brand description between 50 and 500 characters and a valid domain, even though the backend itself only requires a name. This richer context improves AI mention detection.

Brands & Limits

A brand is the unit TruIntel monitors: it carries the queries, competitors, sources, SEO data, content, and reports tracked for one website. Your plan determines how many brands an organization can run at once.

  • Brand fields include name, domain, description, industry, country, a default country code (used to localize AI prompts), logo, and the optional Brand Voice profile.
  • The active-brand count is checked against your plan limit on every create — exceeding it returns a brand-limit error prompting an upgrade.
  • A brand stays in onboarding until you complete it; until then the app routes you back into the wizard so setup is never left half-done.
  • Completing onboarding on a paid plan also generates a one-time onboarding brand report.
PlanBrandsTracking queries / brandTotal tracked queriesCompetitors
Free1551
Starter110101
Lite225503
Pro3401205
Enterprise4502005

All five engines on every plan

ChatGPT, Claude, Gemini, Perplexity, and Google AI Overview are available on every plan, including Free. Plans differ on how many brands, queries, and competitors you can track — not on which AI engines you can monitor.

Plans & Billing Basics

TruIntel offers a permanent Free tier plus four paid plans. Pricing is monthly and billed in USD through Razorpay. The Free plan is a real, hard-limited tier — not a time-limited trial.

Free

$0/mo

  • 1 brand
  • 5 queries / brand
  • 1 competitor
  • 1 team member
  • All 5 AI engines
  • 0 AI credits

Starter

$59/mo

  • 1 brand
  • 10 queries / brand
  • 1 competitor
  • 1 team member
  • 50 AI credits / mo
  • Insights, CMS, Reports

Lite

$139/mo

  • 2 brands
  • 25 queries / brand
  • 3 competitors
  • 2 team members
  • 150 AI credits / mo
  • All Starter features

Pro

$479/mo

  • 3 brands
  • 40 queries / brand
  • 5 competitors
  • 3 team members
  • 500 AI credits / mo
  • Rank Tracking, daily checks

Enterprise is a custom plan (contact sales) with 4 brands, 50 queries per brand, 5 competitors, up to 10 team members, 1000 AI credits per month, and the highest daily-priority check allowance.

PlanTeam membersAI credits / moDaily-priority AEO queries
Free100
Starter1500
Lite21500
Pro35005 / brand
Enterprise10100010 / brand

No time-based free trial

The Free plan is permanent and can be activated once per organization. There is no 7-day trial system — any "free trial" marketing copy is misleading. Marketing also shows struck-through regular prices ($79 / $189 / $599) and an annual "Save 20%" toggle, but both are display-only: billing is monthly. In India, 18% GST is added on top of the listed USD price.

AI credits and top-ups

Paid plans include a monthly AI-credit allowance that resets on the 1st, plus any one-time top-up credits that never expire. Top-up packs: Starter Pack (50 credits, $10), Growth Pack (150 credits, $25), Pro Pack (400 credits, $50). Credits power CMS/content generation (1 credit standard, 3 premium), content repurposing (1 credit), and Prompt-Volumes page lookups (5 credits each, after the daily/monthly cap). Brief generation is free.

Teams & Roles

Organizations support multiple users with three roles: owner, admin, and member. Role checks gate only organization-management actions — they do not restrict which brand features a teammate can use. Feature access is gated by your plan, not by role.

ActionOwnerAdminMember
Update organization settingsYesYesNo
Invite membersYesYesNo
View / cancel pending invitationsYesYesNo
Change a member’s roleYesNoNo
Remove a memberYes (anyone)Yes (members only)No
Use brand features (AEO/SEO/CMS/reports)YesYesYes

Role nuances to know

Only owners can change roles — admins cannot. Admins can remove only members, never owners or other admins. The last remaining owner cannot be removed or demoted, so an organization always has at least one owner. There is no per-brand RBAC: a member is not read-only and has the same feature access as everyone else on the plan.

Inviting teammates

1

Send the invite

An owner or admin invites by email. If the person already has a TruIntel account they are added immediately as a member with an email notification.

2

Pending invitation

If they have no account, a pending invitation is created with a secure token that expires after 7 days, and an invite email is sent.

3

Acceptance

New users auto-join when they verify their OTP or sign up with Google. Existing users accept via the invitation token, which must match the invited email.

Member limits per plan

Team size is capped by plan: Free 1, Starter 1, Lite 2, Pro 3, Enterprise 10. Manage your team from Settings, where you can invite, view pending invitations, change roles, and remove members.

AI Visibility Monitoring

Overview & Visibility Score

AI Visibility Monitoring is TruIntel's core feature. For every brand it runs your tracking queries (prompts) against 5 AI answer engines — ChatGPT, Claude, Gemini, Perplexity, and Google AI Overview — and measures whether, where, and how each engine surfaces your brand. Results are stored as time-series so you can watch trends, get alerts, and prove progress.

Each check produces a composite AI Visibility Score (0–100), a query x platform performance matrix, per-platform scores, brand perception (attributes + sentiment), Share of Voice vs competitors, and cited-source tracking. The score is computed by deterministic Python text-parsing — there is no LLM at scoring time, so the same responses always produce the same number.

AI Visibility Score

40%
30%
20%
10%
Recognition Rate (40%)
Position Strength (30%)
Sentiment (20%)
Citation Rate (10%)
ComponentWeightWhat it measuresExact behavior
Recognition Rate40%Share of query x platform pairs where AI mentions your brandmentions / total pairs x 100; denominator excludes pairs where Google AI Overview was unavailable
Position Strength30%How high your brand ranks within the responsepos 1 = 100, then -15 per rank (pos 7+ = 0); mentioned but not in a ranked list defaults to 50; averaged over mentions
Sentiment20%Whether AI describes your brand positively or negativelyraw sentiment [-1,1] mapped to [0,100] via (s+1)x50, averaged; defaults to 50 when there are no mentions
Citation Rate10%Whether AI links to a source for the mentionmentions carrying a citation URL / total mentions x 100

Score interpretation (3-band gauge)

The Visibility gauge uses three bands: 75–100 Excellent (emerald), 50–74 Good (amber), and below 50 Poor (red). There is no separate "Fair" band on the gauge. A different 60/40 threshold colours the Recognition Rate and Citation Rate metric cells (60+ green, 40+ amber) — do not confuse the two.

Zero-state defaults

On a brand's very first check (or when no mentions exist yet), overall / recognition / position / citation read 0, but Sentiment defaults to 50. The first check is also flagged as a "Baseline" so trend deltas only appear from the second check onward.

The 5 AI Platforms

TruIntel queries 5 AI answer engines concurrently on every check. The exact production models are listed below and are visible in each mention's "Run details" panel. The first three (ChatGPT / Claude / Gemini) are environment-overridable; Perplexity and Google AI Overview routing are fixed. The same models run on every plan, including Free — models are global, not plan-tiered.

ChatGPT

ChatGPT

gpt-5.4-mini via the OpenAI Responses API with the web_search tool (default search context "low"). The most widely used AI assistant.

Claude

Claude

claude-haiku-4-5 (Haiku 4.5) via the Anthropic Messages API with the web_search_20250305 server tool (max 5 searches per query).

Gemini

Gemini

gemini-3.1-flash-lite via the google-genai SDK with Google Search grounding; falls back to non-grounded mode on a billing or quota error.

Perplexity

Perplexity

perplexity/sonar routed through OpenRouter (not Perplexity's own API), returning built-in source citations from real-time web access.

Google AI Overview

Google AI Overview

Google's own AI-generated search summary, scraped via SearchAPI.io in a two-step google -> AI-Overview flow. Many queries simply have no AI Overview — a normal, non-failing result.

How each platform is queried

PlatformModel / sourceWeb accessNotes
ChatGPTgpt-5.4-miniweb_search tool, depth "low"OpenAI Responses API; single attempt, country + date localized
Claudeclaude-haiku-4-5web_search_20250305, max 5 usesAnthropic Messages API; fails fast if credits are too low
Geminigemini-3.1-flash-liteGoogle Search groundingNon-grounded fallback on quota/billing error; 1-hour quota cooldown circuit-breaker
Perplexityperplexity/sonar (via OpenRouter)Built-in real-time searchReturns citations; no recency filter
Google AI OverviewGoogle AIO (SearchAPI.io)Google's live AIOTwo-step fetch; aio_available flag marks "no AIO for this query"

Response intelligence is a separate, non-blocking pass

After parsing, a Kimi K2.5 model (moonshotai/kimi-k2.5 via OpenRouter) enriches each mention with an LLM-derived rank_position, an optional mention-type override (recommended/discouraged), and up to 3 brand attributes. It never blocks the check and never changes the numeric Visibility Score — that is computed entirely by deterministic text-parsing.

What Each Check Extracts

For every query x platform pair, the pipeline parses the AI response with pure text/regex analysis (no LLM, under ~50 ms) and stores a structured mention record. Competitors are parsed first, so they are captured even when your brand is not mentioned.

Mentioned (y/n)

Word-boundary match against brand-name variants: lowercase name, CamelCase split, hyphenated, no-space, full domain, and domain without TLD.

List position

Rank within a numbered or bulleted list (1. / - / #1). 0 (stored null) if mentioned but not in a list. Drives matrix colour and the Position Score.

Rank position (LLM)

A second, Kimi-K2.5-derived rank stored separately for display only. Non-blocking; never affects the score.

Mention type

recommended / alternative / compared / mentioned / not_mentioned, from keyword scanning; Kimi may override to recommended or discouraged.

Sentiment

positive / neutral / negative plus a -1…1 score, from keyword counting in a +/-100-char window around the first mention.

Snippet & full response

A ~200-char sentence-trimmed snippet around the mention, plus the complete AI response text for review.

Citations & sources

A single best citation URL (brand-domain preferred) plus every unique URL in the response, each stored as a classified CitedSource.

Competitor mentions

Each tracked competitor found, with its own list position and sentiment, stored as CompetitorMention rows.

Run telemetry

Model used, tokens, latency, web-search call count, Live/Cached state, and per-check cost breakdown in response_metadata.

Query intent taxonomy

Every query is auto-classified into one of 5 intents at creation time (via Kimi K2.5, defaulting to informational if unavailable). The intent automatically sets the query's business value (1–5) — this is derived, not manually assigned.

Query intentAuto business valueExample
transactional5"best CRM to buy for a small agency"
comparison4"TruIntel vs competitor X"
recommendation4"recommend an AEO tool"
brand3"is TruIntel any good"
informational2"what is answer engine optimization"

Brand-name alias gap

Matching only covers name/domain morphologies — there are no custom aliases and no bare-first-word matching. A brand whose AI-surfaced name is a short or product name (e.g. "River Mobility" surfaced as "River Indie") can be recorded as not-mentioned even when it is explicitly recommended. This is a known limitation.

Query Performance Matrix

The Query Performance Matrix shows how each tracking query performs across all 5 platforms. Rows are queries, columns are the 5 platforms plus an "Avg #" column, and each cell is a status pill (not just a shaded square). The AI Visibility page shows the first 15 active queries (newest first) with a "View all N queries" link to Prompt Tracking.

Cell stateAppearanceMeaning
Mentioned, position 1–3Green #N pillBrand ranked in the top 3 of a list
Mentioned, position 4–6Amber #N pillBrand ranked mid-list
Mentioned, position 7+Red #N pillBrand ranked low in the list
Mentioned, no list positionGreen check pillBrand named but not inside a ranked list
Retryable failureAmber, clickable retry iconCredits / rate-limit / timeout / no-response — click to re-run that one cell
Non-retryable failureRed warning iconConfiguration / invalid request — a retry cannot fix it
Auto-retry in flightAmber spinner ("still loading")Queued in a bulk sweep or an in-flight retry — not a failure
AI Overview unavailable / not mentionedGrey dashNo Google AI Overview for that query, or brand simply absent

Hovering a mentioned cell shows position, mention type, sentiment, and Share of Voice. Clicking a row opens the Query Detail view — platform tabs, the full AI response with your brand highlighted, the citation list, competitors found on that platform, and run telemetry (model, latency, tokens, Live/Cached).

Where filters live

The matrix on the AI Visibility page does not expose sort or intent filters. Full filtering — topic, status (all/active/suggested/inactive), country, priority-only, search, and sort — lives on the Prompt Tracking page at /queries. There is no UI filter by "business value" or "query intent".

Brand Perception & Sentiment

TruIntel surfaces the attributes and sentiment that AI engines associate with your brand — effectively the keywords AI uses to describe you. The Brand Perception table is built from BrandAttribute rows from the latest full visibility check only, grouped by attribute + sentiment.

  • Brand attributes — up to 3 per response (from Kimi K2.5), each with its sentiment, an occurrence count, and which platforms produced it.
  • A per-platform dropdown (All / ChatGPT / Claude / Gemini / Perplexity / Google AIO) filters the table client-side.
  • Sentiment distribution — positive / neutral / negative mention counts, available both overall and per platform.
  • Mention types — recommended / alternative / compared / mentioned / not_mentioned, refined by the Kimi enrichment pass.

Use perception to steer content

If AI consistently associates the wrong attributes with your brand — or attaches negative sentiment — that is a direct signal to adjust the content and sources AI reads. Negative attributes also drive the negative-mention alert.

Share of Voice

Share of Voice (SoV) measures your brand's slice of total brand attention within a single AI response, relative to all tracked competitors. It is computed deterministically (no LLM): for each response, SoV% = your brand-sentences / total brand-sentences (yours + competitors) x 100, using sentence-level whole-word matching.

  • SoV is computed per mention at store time and saved on each QueryMention.
  • The Share of Voice card shows the average SoV per platform across the visible queries (a per-platform bar).
  • Per-mention SoV also appears in the query-detail tooltip and sidebar.
  • Competitor mention counts and head-to-head detail live on the Competitors page.

SoV is per-response, not a global heatmap

SoV reflects how much of a given answer is about you versus competitors. A high recognition rate with low SoV means AI mentions you but devotes more of the answer to rivals — a packaging/authority gap to close.

Citation & Source Tracking

Every URL in every response is extracted as a CitedSource and aggregated into a SourceDomain with citation count, usage %, and first/last-seen dates. This shows which websites AI relies on in your industry and whether your own site is among them.

Source domain types

Each cited domain is classified into one of 8 types. Classification runs in order: your own domain -> corporate; a tracked competitor -> competitor; hardcoded lists and institutional suffixes (.gov/.edu) for editorial / reference / ugc / marketplace / institutional; otherwise "other", which a background Kimi K2.5 pass later reclassifies. Domain types are cached for 7 days.

TypeMeaning
corporateYour own / owned brand domain
competitorA tracked competitor's domain
editorialNews, magazines, and editorial publications
referenceReference and knowledge sites
ugcUser-generated content (forums, Reddit, Q&A)
institutionalGovernment, education, and other institutions (.gov/.edu)
marketplaceRetail and marketplace listings
otherUnclassified domains (reclassified in the background by Kimi K2.5)

Gap analysis

Source Gap Analysis finds domains cited in responses where your brand was NOT mentioned but a competitor WAS — high-value outreach targets. If none are found, it falls back to your own low-citation domains. These results feed Off-Page Outreach.

Earn citations to lift visibility

Being cited by high-authority sources directly improves AI visibility. Use the gap analysis to find sources that cite competitors but not you, then create content or run PR outreach toward those domains.

Check Frequency, Types & Plan Limits

How many queries, brands, and competitors you can track — and how often checks run automatically — depends on your plan. All 5 platforms are available on every plan, including Free. Free runs exactly one onboarding visibility check and has no recurring schedule.

PlanBrandsQueries / brandTotal queriesCompetitorsDaily priority / brand
Free ($0)15510
Starter ($59)1101010
Lite ($139)2255030
Pro ($479)34012055
Enterprise (custom)450200510
Check typeWhen (Asia/Kolkata IST)What runsPlans
Weekly full checkMonday 02:00 ISTALL active queries x ALL 5 platformsAll paid plans
Daily priority checkTue–Sun 02:00 ISTPriority queries onlyPro (5/brand) & Enterprise (10/brand)
Manual full checkOn-demand (button)All queries x 5 platforms, bypasses the 24h cacheAll paid; Free = one check total
Single-cell / single-query recheckOn-demand (matrix retry, Query Detail)1 query x 1 or all platformsAll paid plans
Auto on prompt-addImmediately after adding a promptThat query x 5 platformsCapped at 10 immediate runs / org / day

Free tier: one check only

On the Free plan you get 5 queries, 1 brand, and exactly one visibility check (the onboarding run). The page shows "No recurring checks on free plan" and further check requests return a 403. Recurring scheduled checks require a paid plan.

24-hour response cache

AI responses are cached for 24 hours (keyed on the original query text + country). Scheduled checks reuse the cache; manual checks set skip_cache to force fresh provider calls (then write the fresh result back). This is why a manual re-run can differ from the weekly snapshot. Retries always run fresh.

Localized to your country

Every check is anchored to the brand's country and the current local date, with a "prefer local brands, retailers, and sources" directive injected into the system prompt and query. This mirrors what a real in-country user would see (20 countries supported). It is why you may see local rather than global brands in results.

Post-Check Processing & Alerts

Each visibility check runs a fixed processing pipeline. The score itself is pure deterministic text-parsing; the Kimi K2.5 enrichment and domain reclassification are non-blocking add-ons that never change the number.

1

Fan-out

Every active query x 5 platforms runs concurrently (semaphore-limited), using the 24h cache for scheduled checks or fresh calls for manual checks.

2

Text parse

Pure text/regex extraction of mentioned, list position, mention type, sentiment, snippet, citation URL, and all citations — no LLM.

3

Score

Recognition / Position / Sentiment / Citation rolled into the overall and per-platform scores; AI-Overview-unavailable pairs are excluded from the denominators.

4

Persist

VisibilityCheck, QueryMention, PlatformScore, CitedSource, and CompetitorMention rows are written, with a per-check cost breakdown.

5

Response intelligence

Kimi K2.5 (non-blocking) updates rank_position, may override mention type, and extracts up to 3 brand attributes.

6

Domain classification

Cited domains are typed by rules now, with a background Kimi reclassification for "other" domains; SourceDomain usage % is recomputed.

7

Trends & alerts

Score / recognition deltas vs the previous full check are computed, then alerts are generated and HIGH/CRITICAL ones emailed.

Alert types

Five alert types are generated after a check. Only HIGH/CRITICAL alerts trigger an email to members.

AlertTriggerSeverity
visibility_dropScore dropped >= 5.0 points vs the previous checkHIGH if >= 10, else MEDIUM
score_milestoneScore crossed 50 / 75 / 90 upwardLOW
competitor_overtakeA competitor's mentions exceeded your brand'sMEDIUM
negative_mentionNew negative-sentiment mentions vs the previous checkHIGH if >= 3, else MEDIUM
integration_errorTransient/retryable platform failures (points to Retry)MEDIUM

Weekly Insights are separate

The 4-step AI Insights pipeline (Trend -> Competitor -> Strategy -> Tasks, powered by gemini-3.1-flash-lite) is a separate weekly scheduled task, not part of every visibility check. See the Insights section.

Failure Detection & Retry

Platform clients make a single attempt; all persistent retry is owned by a dedicated retry service so that "failed" means the same thing everywhere — in the matrix pills, query detail, and retry counts. Silent empty-200 responses are caught and surfaced honestly instead of showing an infinite spinner.

Failure bucketRetryable?Example
rate_limit / timeout / temporaryAuto-retry429, 503, overloaded, connection reset
no_response (empty 200)Manual retry onlyProvider returned an empty response
creditsNon-retryableCredit balance too low, insufficient quota, 402
configurationNon-retryableMissing API key / unsupported country
invalid_requestNon-retryableInvalid value / unsupported parameter

Auto-retry fires immediately after a check for transient failures, then backs off across 30s / 2m / 5m / 15m / 1h for up to 6 attempts before marking the cell "exhausted". A 60-second beat sweeper re-runs any brand whose next retry is due. Each retry inserts a new mention row, so history is preserved and the original aggregate score is not mutated.

  • Per-cell retry — click the amber retry pill on a matrix cell to re-run that one (query, platform) inline; a manual single-cell retry resets the chain so 6 fresh auto-retries can follow.
  • "Retry all failed" button — sweeps every manually-recoverable failure (exhausted, in-backoff, credits-depleted, silent-empty); only configuration and invalid_request are excluded because a retry cannot fix them.
  • The "Retry N failed" count equals exactly what the button re-runs (pending + stuck), so it never lies.
  • An in-flight Redis lock collapses double-clicks and overlapping sweeps into a single provider call, and the matrix spinner is server-derived so it survives page navigation and device switches.

Credit-exhaustion is intentionally non-retryable

Errors that mean "out of money" (insufficient quota, credit balance too low, payment required, 402) are classified non-retryable so doomed retries do not burn the backoff window or show an endless spinner. Top up the relevant provider, then use "Retry all failed".

AI Crawlability & Site Audit

The AI Crawlability / Site Audit view (at /visibility/site-audit) checks how well AI crawlers can reach and read your site — a prerequisite for being cited at all. It combines site-health signals with per-vendor LLM-bot access derived from your robots.txt.

Site health gauge

Composite health signal alongside Domain Authority, backlinks, and referring domains.

LLM bot access

Per-vendor allow/block status (e.g. GPTBot, ClaudeBot, Google-Extended) parsed from robots.txt.

Top cited URLs

The brand URLs most frequently cited by AI engines, so you know which pages are working.

Spam score

Domain spam-risk signal (Pro+ only) to flag toxicity that can suppress citations.

Blocked bots = invisible brand

If your robots.txt blocks AI crawlers, those engines cannot read your pages and will struggle to cite you. The audit makes per-vendor access explicit so you can open the right bots.

Pages & API Reference

AI Visibility spans several pages in the AI Visibility navigation section. Free can reach AI Visibility, AI Crawlability/Site Audit, Prompt Tracking, Prompt Research, Sources, and Competitors; richer surfaces such as Prompt Volumes are paid-only.

AI Visibility

/visibility

Score gauge, query performance matrix, brand perception, Share of Voice, topics performance, and trends.

Prompt Tracking

/queries

Manage tracking queries with full filters (topic, status, country, priority, search) and sort.

Query Detail

/queries/:queryId

Per-query deep dive: platform tabs, full responses, citations, competitors, and run telemetry.

AI Crawlability / Site Audit

/visibility/site-audit

Site health, LLM-bot access from robots.txt, and top brand URLs cited by AI.

Sources

/sources

Cited domains, source-type breakdown, URL-level tracking, and source gap analysis.

Competitors

/competitors

Competitor mention counts, positions, and head-to-head Share of Voice.

Prompt Research

/prompt-research

Discover and add new high-value tracking queries.

Key API endpoints

Visibility & Dashboard endpoints
# Run and watch a check
POST /api/v1/visibility/check
GET  /api/v1/visibility/check/{task_id}/status
GET  /api/v1/visibility/check/{task_id}/stream   # SSE live progress

# Scores, history, mentions
GET  /api/v1/visibility/score/{brand_id}
GET  /api/v1/visibility/history/{brand_id}
GET  /api/v1/visibility/checks/{brand_id}
GET  /api/v1/visibility/checks/{check_id}/details
GET  /api/v1/visibility/mentions/{brand_id}
GET  /api/v1/visibility/mentions/{brand_id}/{query_id}
GET  /api/v1/visibility/response/{mention_id}
GET  /api/v1/visibility/{brand_id}/site-audit

# Matrix, retries, sources (dashboard + sources routers)
GET  /api/v1/dashboard/{brand_id}/queries          # performance matrix
POST /api/v1/dashboard/{brand_id}/queries/{query_id}/regenerate  # single cell
POST /api/v1/dashboard/{brand_id}/queries/retry-failed           # manual sweep
GET  /api/v1/dashboard/{brand_id}/retry-status                   # badge polling
GET  /api/v1/sources/{brand_id}/type-stats
GET  /api/v1/sources/{brand_id}/gap

Live progress stream

A running check exposes a Server-Sent Events stream (/visibility/check/{task_id}/stream) so the UI can show "checking query X of N" in real time rather than a blank loading state.

Prompts & Queries

What a Tracking Query Is

A tracking query (also called a "prompt") is a buyer-style question that TruIntel runs across the five AI platforms on a schedule to measure your brand visibility. Each query represents something a potential customer might genuinely ask an AI assistant about your category — for example "What is the best CRM for small teams?" rather than a keyword.

Every query stores its text, country/locale (default India), tags, status, intent, an auto-derived business value, and an optional topic. Queries are managed on the Prompt Tracking page at /queries; each query has a detail view at /queries/:id showing its visibility trend over time.

Buyer-Intent Phrasing

Queries are written as natural questions a customer would ask an AI assistant — never as raw keywords.

Localized

Each query carries a country/locale (default India). The country and current date are injected into the AEO system prompt so results reflect the right market.

Tagged & Grouped

Queries carry free-form tags and belong to one topic, so you can slice visibility by theme across the whole dashboard.

Trend-Tracked

Each query keeps a history of scores. The detail page charts how its visibility moves week over week.

Status & Check Cadence

Every query has one of three statuses, and the status plus the priority flag together decide when (and whether) the query is checked across the AI platforms.

StatusMeaningCounts toward plan limit?Checked?
activeBeing tracked on scheduleYesYes
suggestedAn AI recommendation not yet acceptedNoNo (until accepted)
inactivePaused by youNoNo

Your plan limit counts only non-inactive queries (active + suggested), so pausing a query frees a slot. The check cadence then depends on whether the query is flagged as priority:

CadenceApplies toWhen it runs (Asia/Kolkata IST)UI label
Weekly full checkEvery active queryMonday 02:00 ISTMon
Daily priority checkPriority queries onlyTue-Sun 02:00 IST (plus Monday's full check)Daily
Not checkedInactive queriesNever

Priority is a Pro+ feature

Daily priority slots are 0 on Free, Starter, and Lite. Pro gives 5 priority queries per brand and Enterprise gives 10. On the lower plans the priority toggle hard-fails with "Priority query limit reached" — every query is simply checked in the Monday full pass.

Intent & Business Value

When a query is created, TruIntel classifies its intent exactly once and caches the result on the row. Business value is then auto-derived from that intent — it is never a number you set yourself. The classifier runs on Kimi K2.5 (moonshotai/kimi-k2.5) via OpenRouter and falls back to informational / value 2 if classification ever fails.

IntentWhat it capturesBusiness value
transactionalReady-to-buy / "near me" / pricing questions5
comparison"X vs Y" head-to-head questions4
recommendation"Best / top / recommended" questions4
brandQuestions that name your brand directly3
informationalGeneral "how / what / why" research questions2

The effective business-value range is therefore 2-5 (never a user-assigned 1-5). In the UI, a QueryIntentBadge shows the intent and a "$" / "$$" badge marks high-value queries (value >= 4 shows $, value 5 shows $$).

High-value queries can auto-promote to priority

If a new query classifies at business value >= 4 and your plan still has a free priority slot, TruIntel auto-flags it as priority at creation so the most commercially valuable questions get the daily cadence first.

Bulk-created queries (from onboarding) are classified in the background a few seconds after they are saved, so their intent badges fill in shortly after the queries appear.

Adding & Editing Queries

The "Add Prompt" modal has two tabs: Manual (type a query yourself) and AI (generate suggestions). There is no CSV upload — bulk creation happens through the AI-generation and onboarding flows.

1

Open Add Prompt

From the Prompt Tracking page, choose the Manual or AI tab. Manual takes one query at a time; AI proposes a batch you can accept.

2

Plan limit + duplicate checks run first

Creation is blocked at your per-brand query cap (PLAN_LIMIT_EXCEEDED). Case-insensitive duplicate detection returns the existing query instead of creating a second copy.

3

Intent is classified

The new query is sent to the intent classifier, which sets its intent, business value, and possibly an auto-priority flag.

4

An immediate check may kick off

So you don't have to wait for the next cycle, TruIntel can run a single instant AEO check on the new query and show a "Running now…" state while it processes.

Instant-check quota

Immediate single-query checks are capped at 10 per organization per IST day. It is a soft limit: once exhausted the prompt is still created, the instant check is just skipped and the query waits for its next scheduled run.

Editing the text resets the trend

If you materially change a query's wording, TruIntel clears the cached intent/business value (re-derived on the next run) and returns a history-reset warning. Existing history rows are kept, not deleted, but the change only takes effect on the next scheduled check — edits never trigger an immediate run.

Topics & Organization

Topics group related queries so you can slice visibility by theme across the dashboard. Each query belongs to exactly one topic, and topics carry a denormalized query count.

  • Topics are unlimited on every plan — there is no per-plan topic cap.
  • Create, rename, and delete topics from the Topics Management modal; duplicate names are blocked case-insensitively.
  • Deleting a topic does not delete its queries — their topic is simply set to none (they keep all history, they just lose the grouping).
  • Filter visibility data by topic anywhere the topic filter appears to focus on one area of your business.
  • Topics also help the AI Insights engine group related findings.

AI Query Suggestions

TruIntel can generate topics and prompts for you using its provider-agnostic utility-LLM chain (Anthropic-first, falling back to Gemini then OpenAI). These are an on-demand onboarding flow — every "suggest" call is preview-only and saves nothing until you accept selections through the bulk endpoints. They are not a continuously refreshed feed.

  • Topics-with-prompts: one shot that returns N topics each pre-filled with K prompts (the current onboarding step).
  • Topics only, then prompts-per-topic: the legacy two-step flow for expanding one topic at a time.
  • Generate: produces queries for topics you have already saved, distributed across your plan's per-brand query budget.
  • Generated prompts are deliberately brand-agnostic (your brand name is forbidden inside the query text) and localized to your brand's country.

How many topics and prompts you can generate depends on your plan:

PlanTopics generatedSelectablePrompts / topicRegenerations
Free4321
Starter5331
Lite6432
Pro8532
Enterprise10653

Best practice

Start with 10-20 high-intent queries that map directly to your product, then expand into broader category questions. Queries where you have a realistic chance of being mentioned move your score; very generic questions tend to have low brand recognition.

Prompt Research

Prompt Research (/prompt-research) is an ideation tool that turns keywords into ready-to-track prompt ideas. You enter a list of keywords and TruIntel returns up to 15 natural-language prompt ideas, each with suggested tags and an intent label, that you can add straight into tracking with one click.

What it does NOT do

Prompt Research does not query any AI platform and does not analyze responses. It generates prompt ideas only — it computes no mentions, sources, or sentiment. To actually measure visibility, add an idea to tracking and let the scheduled AEO checks run it.

  • Input is a set of keywords (not a single seed topic).
  • Output is 15 flat prompt ideas — there are no topic clusters.
  • Each idea carries up to 3 tags and an intent of transactional, comparison, recommendation, or informational.
  • Generation runs on the utility-LLM chain (Anthropic-first fallback) and is stateless apart from saving a history row.
  • Past runs are saved: browse the research history and open any past run to see its full prompt list.

Costs 1 credit per run — paid plans only

Each Prompt Research generation deducts 1 AI credit up front (insufficient credits return HTTP 402). Because Free includes 0 monthly credits, Prompt Research is effectively a paid-plan feature, metered by credits rather than unlimited.

Plan Limits & Routes

Query capacity scales with your plan. Limits below are per brand — both the per-brand query cap and the daily priority slots are counted per brand.

PlanQueries / brandTotal tracked queriesDaily priority queries
Free550
Starter ($59)10100
Lite ($139)25500
Pro ($479)401205
Enterprise5020010

Prompt Tracking

/queries

List, add, filter, and prioritize tracking queries; manage topics.

Query Detail

/queries/:id

Per-query visibility trend, platform breakdown, and history.

Prompt Research

/prompt-research

Generate prompt ideas from keywords and add them to tracking.

Sources & Citations

What Source Tracking Captures

When an AI platform answers one of your tracked queries, it often cites source domains and URLs. Source Tracking (/sources) records every one of those citations so you can see exactly which sites AI engines lean on when they describe your category — and which ones mention you versus your competitors.

Per-Citation Records

Each individual citation is stored with its domain, URL, title, and type, tied back to the exact AI mention it came from.

Aggregated Domain Stats

Per domain, TruIntel rolls up total citations, usage percentage, average citations, and first/last seen timestamps.

Typed & Filterable

Every domain is classified into one of eight source types, so you can filter earned media from owned, competitor, or marketplace sources.

Sources are a byproduct of visibility checks

There is no separate "scan sources" action. Citation data accumulates automatically as your scheduled AEO checks run, so coverage deepens with your query count and check cadence. The page is viewable on every plan, including Free.

Source Types

TruIntel classifies every cited domain into one of eight stored source types. A domain is typed once and the result is cached, so each domain is classified only a single time.

Source TypeDescriptionExamples
corporateCompany / brand official sites (including your own)yoursite.com, vendor homepages, about pages
editorialNews outlets and publicationsForbes, TechCrunch, Reuters
ugcUser-generated content platformsReddit, Quora, Stack Overflow
institutionalGovernment, academic, and non-profit sites.gov, .edu, standards bodies
referenceReference and knowledge basesWikipedia, documentation hubs
competitorA tracked competitor's domain (matched, not LLM-guessed)rival.com
marketplaceE-commerce and listing platformsAmazon, Product Hunt, app stores
otherAnything that does not fit the aboveMisc. blogs and aggregators

Classification follows a fixed order: (1) if the domain matches your brand it becomes corporate, and if it matches a tracked competitor it becomes competitor; (2) hardcoded lists / first-seen typing handle well-known hosts; (3) anything still "other" is sent to a Kimi K2.5 (via OpenRouter) classifier, whose output is cached. The LLM can return any type except competitor (that one is reserved for domain matching).

Earned vs Owned are filter aggregates, not stored types

The Sources page lets you filter by "Earned Media" and "Owned-Corporate". These are frontend roll-ups, not database types: Owned = corporate, and Earned = editorial + ugc + reference + institutional + marketplace + other. Use them for a quick split, and the eight underlying types for precision.

Sources Page

The Sources page opens with a five-cell stat strip, then a distribution donut, a gap-opportunity table, and the full citation table.

  • Stat strip: Total sources, Earned Media, Corporate-Owned, Competitor, and Gap Opportunities.
  • Source Type Distribution donut: citations broken down by type (interactive donut).
  • "Sources You Should Target": the gap table, with a per-row "Draft outreach" button that hands the domain to the Outreach workflow.
  • "All Citation Sources": the full table with domain search, a type dropdown (All / Earned Media / Owned-Corporate / Editorial / UGC / Reference / Institutional / Marketplace / Competitor), a platform filter, and sorting by Most cited, Last seen, First seen, or Highest usage %.

Click any row to open the Source Detail modal, which lists that domain's top cited URLs, which AI platforms cite each one, and the first/last seen dates.

Source Gap Analysis

Gap Analysis surfaces high-authority domains that AI cites in responses where your competitors appear but your brand does not. These are your highest-leverage outreach targets — places AI already trusts in your category that have not yet picked you up.

1

Find your blind spots

TruIntel collects the AI responses where your brand was not mentioned for a tracked query.

2

Check who got cited instead

It identifies which active competitors were mentioned in those same responses and aggregates the domains cited there (top 30).

3

Score the opportunity

Each domain gets an opportunity score from 0-100, weighted by how often competitors are cited there, the size of the gap versus your own citations, and how many distinct competitors it favors. The top 20 are returned.

4

Act

Each gap row shows the domain, its type, competitor vs brand citations, which competitors cite it, the platforms involved, a representative query, and a plain-language opportunity note — and a "Draft outreach" button to start a pitch.

Fallback when there's no competitor data yet

If TruIntel doesn't yet have competitor-cited responses to compare against, it instead surfaces your own low-citation domains (3 or fewer cites) as "room for growth", excluding your own host and a blocklist of non-targetable mega-platforms (Google, Bing, YouTube, Facebook, X, LinkedIn, Reddit, Quora, Medium, Wikipedia, Amazon, CDNs, and AI-infra hosts).

Actionable insight

If a domain is frequently cited by AI in your industry but never references your brand, getting featured there (through PR, guest posts, or partnerships) can meaningfully lift your visibility score.

Routes

Sources

/sources

Citation tracking: stat strip, type donut, gap targets, and the full citation table with per-source detail modals.

Competitor Tracking

How Competitor Tracking Works

Competitor Tracking (/competitors) measures how your rivals show up in AI answers alongside you. You add competitors (manually or from AI discovery) and TruIntel records every time one of them is mentioned in a response to your tracked queries — position, sentiment, snippet, and platform.

Competitor data appears only after the next full check

Competitor mentions are generated solely as a byproduct of your brand's weekly full visibility check. There is no competitor-only refresh, and adding or removing a competitor dispatches no task — it is just a database row. A newly added competitor shows "tracking starts at next check" and has no metrics until that Monday 02:00 IST full pass runs.

Discovery & Lifecycle

Competitors move through a suggested → active → rejected lifecycle. AI discovery proposes candidates; you decide which to track.

1

Discover

AI discovery (run at onboarding and on demand) uses the utility-LLM chain to propose competitors from your brand profile, returning name, domain, description, and a confidence score, then dedupes against what you already have. Discovered entries get an "Auto-discovered" badge.

2

Triage

Suggested competitors can be tracked (promoted to active, subject to your plan limit) or rejected. You can also manually add competitors directly as active.

3

Maintain

Edit a competitor's name, domain, or description at any time — edits are free and never count against your limit. Delete removes it entirely.

The limit applies to active competitors only

Your plan cap is enforced at add / track / bulk time and counts only competitors with status active. Suggested and rejected entries are free, and edits are always exempt.

Comparison Metrics

The Visibility Comparison table shows you side by side with each tracked competitor across the latest full check window. A status PillTabs filter lets you view suggested, active, or rejected competitors.

MetricWhat it shows
Visibility ScoreAI visibility (0-100) for the brand and each competitor
Recognition RateHow often each brand is mentioned in AI responses
Average PositionWhere each brand appears in AI answers (1st, 2nd, 3rd, …)
SentimentDominant tone (positive / neutral / negative) per competitor
Citation CountHow often each brand's own domain is cited as a source
Top TopicsThe top 3 topics each brand shows up in
Platform BreakdownWhich platforms favor which competitors

The competitor score uses a different formula

Your brand's visibility score weighs Recognition 0.40 + Position 0.30 + Sentiment 0.20 + Citation 0.10. The per-competitor score uses Recognition 0.40 + Position 0.30 + Presence 0.30, with no sentiment or citation term. The two are broadly comparable but not computed identically — read competitor scores as a directional benchmark, not a like-for-like number.

Analysis Surfaces

Beyond the comparison table, the Competitors page offers four deeper analysis surfaces.

AEO Competitor Matrix

A grid of your brand versus each competitor, showing per-platform mention presence at a glance.

Top Opportunities

"Missing" prompts where a competitor is mentioned but you are not, and "Weak" prompts where you are mentioned but a competitor outranks you — each with the query, topic, competitor, and the mention/position deltas.

Prompt Overlap (Venn)

Per competitor, how your tracked prompts split into brand-only, competitor-only, both, and neither across every query.

Mentions History

A time series of mention counts for your brand and each active competitor, in day or month buckets over 1-365 days, with an optional platform filter.

Plan Limits & Routes

How many competitors you can actively track depends on your plan. Unknown plans fall back to Starter limits.

PlanTracked competitors
Free1
Starter1
Lite3
Pro5
Enterprise5

Competitors

/competitors

Discovery, suggested/active/rejected workflow, comparison table, AEO matrix, opportunities, prompt overlap, and mentions history.

Prompt Research

Overview

Prompt Research is an AI prompt-idea generator. You type 1-20 seed keywords and an LLM returns up to 15 natural-language search prompts — the kinds of questions real people ask AI assistants like ChatGPT, Claude, Gemini and Perplexity in your industry. Each prompt comes with topic tags and an intent label, and any prompt can be promoted into a tracked AI Visibility query with one click.

What it is — and what it is NOT

Prompt Research only writes question ideas. It does NOT call ChatGPT/Claude/Gemini/Perplexity/Google AI Overview, and it does NOT analyze brand mentions, citations, or sentiment. The actual cross-platform analysis happens later in AI Visibility, after you add a prompt as a tracking query.

Idea generation

Turn a handful of seed keywords into up to 15 ready-to-use, natural-language AI search prompts tailored to your brand industry.

Tags + intent

Every prompt carries up to 3 topic tags and one of 4 intent categories so you can sort comparison, recommendation, transactional and informational questions.

Add to Queries

Promote any generated prompt into a tracked AI Visibility query — with an optional Topic, a Country, and the tags carried over.

Saved history

Every generation is saved per brand as a Recent Search you can reload — keywords and full prompt list included.

Best practice

Use Prompt Research to build your tracking query set. Generate prompt ideas for a topic, pick the questions that matter most to your audience, then "Add to Queries" so AI Visibility starts measuring whether your brand shows up in those answers across all five platforms.

How It Works

The flow is a single round-trip: you supply keywords, TruIntel injects your brand context, an LLM drafts the prompts, and the result is sanitized and saved. No AI platforms are queried at this stage.

1

Add seed keywords

Enter 1-20 keyword chips via Enter or the "Add" button. The Generate button stays disabled until at least one keyword is present.

2

Brand context is injected

The selected brand name, industry and description are silently added as context — but the brand name is deliberately kept OUT of every generated prompt so the questions read like neutral user queries.

3

Generate (costs 1 AI credit)

One AI credit is deducted up front before generation. If you have no credits the request returns a 402 "Insufficient credits" error and nothing is generated.

4

LLM drafts the prompts

The utility-LLM chain is asked for exactly 15 prompts — a mix of comparison, recommendation, how-to, informational and buying-intent questions, each with 1-3 tags and one intent category.

5

Sanitize + return

Empty prompts are dropped, tags are capped at 3, and any invalid intent is forced to "informational". You receive up to 15 clean prompts (not always a fixed 15).

6

Saved to history

The keywords and prompt list are stored as a Recent Search row scoped to the brand, returning a history_id you can reload later.

Up to 15 — not 20-30, and no clusters

The model is asked for exactly 15 prompts; after sanitization you get 15 or fewer. There are no topic clusters. Each prompt only carries tags and an intent label — nothing else.

Output & Intent Categories

Each generated prompt is a small object: the prompt text, up to 3 topic tags, and exactly one intent category. Intents render as colored pills so you can scan the mix of question types at a glance.

FieldTypeNotes
textstringThe natural-language search prompt. Never contains your brand name.
tagsstring[]Up to 3 topic tags. Carried over when you Add to Queries.
intentenumOne of 4 categories (see below); invalid values default to informational.

The 4 intent categories

Transactional

Buying-intent questions — pricing, where to buy, "best deal" style prompts close to a purchase decision.

Comparison

Head-to-head questions comparing products, vendors or approaches ("X vs Y", "alternatives to...").

Recommendation

Ask-for-a-pick questions ("best tools for...", "what should I use to...") where AI suggests options.

Informational

How-to and explainer questions. Also the fallback category for any prompt with an unrecognized intent.

Add to Queries

Add to Queries is the real payoff. It converts a generated prompt idea into a tracked AI Visibility query, so TruIntel begins measuring whether your brand appears in AI answers to that question on every platform.

1

Click "Add to Queries"

Each result row has an Add to Queries button that opens a short modal.

2

Pick or create a Topic (optional)

Group the query under an existing topic, or create a new topic on the spot. Topics organize your tracked queries.

3

Choose a Country

Set the market for the query. The default is India (IN); change it to localize AI answers to the right region.

4

Save the query

The prompt tags carry over automatically. Once added, the result row switches to an "Added" state so you do not double-add.

This is what feeds tracking

A prompt only starts producing visibility data once you Add to Queries. From there it is picked up by the normal AI Visibility cadence — the weekly full check (Mondays 02:00 IST) and, on Pro/Enterprise, the daily-priority checks.

History (Recent Searches)

Every generation is persisted per brand so you can revisit and reload past ideas without spending another credit. The idle screen surfaces recent searches as clickable pills.

  • Each Recent Search stores the keywords used, the full prompt list, and the prompt count.
  • Clicking a recent-search pill reloads its keywords and prompts instantly — no new generation, no credit spent.
  • History is scoped to the brand and organization and is paginated (default 20 per page, up to 100).
  • Reloading a past entry lets you Add to Queries from older ideas at any time.

Reloading is free

Only generating a fresh set of prompts costs 1 AI credit. Opening a saved Recent Search to re-read or promote those prompts to queries is free.

Credits, Plans & Availability

There is no route-level plan gate on Prompt Research — access is governed purely by your AI-credit balance. Each generation costs exactly 1 AI credit, drawn from your monthly plan_credits pool first, then any never-expiring extra_credits top-ups. Because the Free plan gets 0 credits, Prompt Research is effectively a paid-plan feature.

PlanMonthly AI creditsPrompt ResearchApprox. generations/month
Free0Blocked (every run 402s)0
Starter50Available~50 (shared)
Lite150Available~150 (shared)
Pro500Available~500 (shared)
Enterprise1000Available~1000 (shared)

Credits are shared

AI credits are a single shared pool. Prompt Research generations compete with CMS/Plus content drafts, repurposing, and Prompt-Volumes page lookups. There is no per-day or per-session cap beyond your credit balance — heavy generation will draw down credits you also need elsewhere.

  • plan_credits reset on the 1st of each month; extra_credits top-up packs never expire.
  • Top-up packs (one-time): Starter Pack 50 credits $10, Growth Pack 150 credits $25, Pro Pack 400 credits $50.
  • The page itself unlocks only after the brand's first AI Visibility check completes — until then it shows a loading gate.

How Prompts Are Generated (Model)

Prompt Research does not use a single fixed model. It runs through TruIntel's provider-agnostic utility-LLM chain: the first provider that returns valid JSON wins, and the chain falls through on any error, a non-JSON response, or a 60-second timeout. This keeps generation resilient when one provider is rate-limited or down.

OrderProviderModel
1Anthropicclaude-haiku-4-5
2Geminigemini-3.1-flash-lite
3OpenAIgpt-5.4-mini (JSON mode)
4OpenRouter (backstop)moonshotai/kimi-k2.5

No platform analysis here

This utility chain only drafts prompt text. It is separate from the AEO platforms that AI Visibility actually queries, and separate from the deterministic Python scoring used to compute your Visibility Score.

Routes & API Reference

Prompt Research lives under the AI Visibility section in the navigation, and is backed by three endpoints under the /api/v1/prompt-research prefix.

Prompt Research

/prompt-research

The generator page — keyword input, results with tags + intent, Add to Queries, and Recent Searches. Found under AI Visibility in the nav.

Backend endpoints

MethodEndpointPurpose
POST/api/v1/prompt-research/generateGenerate prompts (costs 1 AI credit); saves a history row and returns history_id.
GET/api/v1/prompt-research/{brand_id}/historyList past generations (paginated: limit 1-100, default 20; offset).
GET/api/v1/prompt-research/{brand_id}/history/{history_id}Fetch a single past generation with its full prompt list for reloading.

Prompt Volumes

New

What Prompt Volumes Is

Prompt Volumes is a single-keyword "AI search volume" research tool. You type one keyword or topic and it estimates how many times people are asking AI engines about it, broken down across five AI platforms, plus a 12-month trend, the kinds of prompts users actually ask, the top cited source domains, co-mentioned brands, and topic categories. Think of it as keyword research for the AI-answer era.

It lives under the AI Visibility group at the route /prompt-volumes and replaced the retired "AI Mentions" feature (the old /ai-mentions route permanently redirects here). The page is a single scrolling layout — there are no tabs.

Total AI Search Volume

A headline volume number summed across all five platforms, with a period-over-period delta so you can see whether interest is rising or falling.

12-Month Trend

A multi-line chart of monthly volume per platform, with client-side period re-slicing (1 / 3 / 6 / 12 months) that recomputes totals instantly without a new lookup.

Relevant Prompts

AI-generated, buyer-style example questions for the topic, each with its own search keyword and an asynchronously filled volume column.

Sources & Brands

The top 10 cited source domains, the top 10 brands co-mentioned for the topic, and the top 5 topic categories.

Intent Classification

A rule-based badge labelling the keyword as informational, commercial, transactional, or navigational, with a confidence score.

Watchlist

Star any keyword to save it (with its region and language) to the active brand's watchlist so you can re-run it later.

Brand context required

You must have a brand selected in the top-nav brand picker to use the page — lookups and watchlist saves are scoped to that brand. The keyword you research itself is brand-agnostic; the brand only provides scope for saving and history.

Powered by DataForSEO + Gemini

Real volume comes from the DataForSEO "LLM Mentions" dataset (for ChatGPT and Google AI Overview). The relevant-prompts list is generated by Gemini (gemini-3.1-flash-lite). The three remaining platforms are modelled from the ChatGPT number — see the next subsection for the honest breakdown.

The Five Platforms: Real vs Estimated

The page always shows five platforms, but they are not all measured the same way. This is the single most important nuance to understand: only ChatGPT and Google AI Overview carry real measured data. Gemini, Claude, and Perplexity volumes are statistically modelled from the ChatGPT number using fixed market-share multipliers.

ChatGPT

ChatGPT

REAL data. Volume is derived from Google "People Also Ask" — DataForSEO's official proxy for ChatGPT prompt volume, since no public ChatGPT-usage API exists.

Google AI Overview

Google AI Overview

REAL data. Sourced from DataForSEO Google AI Overview impressions and Google Search Volume data, using your actual selected region.

Gemini

Gemini

ESTIMATED. Modelled as ChatGPT volume x 0.171 market-share multiplier, with a confidence band.

Claude

Claude

ESTIMATED. Modelled as ChatGPT volume x 0.043 market-share multiplier, with a confidence band.

Perplexity

Perplexity

ESTIMATED. Modelled as ChatGPT volume x 0.071 market-share multiplier, with a confidence band.

PlatformSourceHow the number is producedConfidence band
ChatGPTRealDataForSEO PAA-proxy volume (Google People Also Ask)Measured
Google AI OverviewRealDataForSEO AI Overview impressions / Google Search VolumeMeasured
GeminiEstimatedChatGPT volume x 0.171-0.85 / +1.20
ClaudeEstimatedChatGPT volume x 0.043-0.80 / +1.30
PerplexityEstimatedChatGPT volume x 0.071-0.80 / +1.25

Each estimated platform row carries an "[Estimated]" badge with a tooltip explaining the methodology, and a confidence range (low / high) derived from the per-platform band multipliers above. The Total Volume in the hero is the sum of all five platform values (two real plus three estimated).

Estimates never fabricate volume

If ChatGPT volume is 0, all three estimated platforms are 0 too — the model never invents non-zero estimates. The market-share weights are a hardcoded set "as of 2026-04-01", refreshed quarterly from Statcounter / Similarweb / OpenAI-Anthropic disclosures.

ChatGPT is US-only at the source

DataForSEO's ChatGPT dataset is hard-pinned to the US (location code 2840, language English) regardless of the region you select. For non-US regions, TruIntel applies a silent regional multiplier to the US ChatGPT number so the displayed value reflects that region's relative scale. Google AI Overview, by contrast, uses your actual selected region directly with no weighting.

RegionChatGPT multiplierRegionChatGPT multiplier
United States1.00Germany0.14
India0.55France0.11
United Kingdom0.18Canada0.08
Japan0.18Spain0.07
Brazil0.20Australia0.05

Unlisted regions

Any region not in the table above uses a multiplier of 1.00, meaning ChatGPT volume is shown at its raw US value for that region.

How a Lookup Works

A standard page lookup fans out four parallel DataForSEO calls plus one Gemini call, then assembles the trend, deltas, intent, sources, brands, and categories from the merged results.

1

1. Real volume (2 aggregate calls)

Aggregated-metrics calls for Google AI Overview and for ChatGPT return the real headline volumes for the keyword.

2

2. Trend + hierarchy data (2 search calls)

Search/live calls for Google and ChatGPT return monthly search history (for the 12-month trend) and fan-out queries.

3

3. Relevant prompts (1 Gemini call)

Gemini (gemini-3.1-flash-lite) generates the buyer-style example prompts for the topic.

4

4. Model + assemble

The backend models the three estimated platform volumes, builds the 12-month trend, computes period-over-period deltas, classifies intent, and merges top sources, brand entities, and categories.

5

5. Async prompt volumes

The frontend then fires a follow-up call to fill the per-prompt volume column; until it returns, that column shows a skeleton.

Lookup typeCalls firedApprox. costWhat you get
Page (default)4 DataForSEO + 1 Gemini~$0.42 freshFull data: volume, trend, prompts, sources, brands, categories
Onboarding2 DataForSEO (aggregate only)~$0.20 freshTotal-volume number only; prompts/sources/brands/categories empty

The onboarding variant (used during brand onboarding) skips the two search/live calls, so it returns only the headline volume — relevant prompts, sources, brands, categories, and hierarchy come back empty by design.

24-hour caching

Every lookup is cached for 24 hours, keyed by a hash of the keyword, region, language, and purpose. An identical lookup within 24 hours is served free and marked as cached — it does not cost money and does not consume your lookup quota.

  • A "force refresh" action bypasses the cache and re-bills (exposed as a secondary action in the UI).
  • Page lookups and onboarding lookups never share a cache row (different purpose in the key).
  • Self-heal: if a cached row has volume but an empty prompts list (e.g. Gemini was down at capture time), only the cheap Gemini call re-runs — not the full ~$0.42 bundle.
  • Stale-cache fallback: if every upstream DataForSEO call fails but a past row exists for the exact keyword, the stale row is served rather than an error.

Lookup outcome statuses

StatusMeaningQuota / billing
okFull data returnedConsumes one lookup (if fresh)
partialSome upstream calls failed; partial data shownConsumes one lookup (if fresh)
insufficient_dataKeyword too obscure — both ChatGPT and Google volume are 0Persisted so the same keyword does not re-bill within 24h; shows "Not enough AI search activity" with broader-term suggestions
service_unavailableAll upstream calls failed (outage / out of credit)Refunded — does NOT consume quota; shows "Service temporarily unavailable, try again"

Reading the Results

The results page renders as a single scroll. Here is what each panel shows and how to read it.

Search Hero

Keyword input, the intent badge, the save-to-watchlist star, and your recent searches.

Prompt Volume Chart

"Across 5 platforms" total + delta hero, a filters bar (period, region, platform toggles), the 12-month multi-line chart, and a per-platform breakdown panel you can toggle on or off.

Relevant Prompts

A table of AI-generated example prompts with an asynchronously filled volume column.

Top Sources & Brands

The top 10 cited source domains and the top 10 brands co-mentioned for the topic, shown side by side.

Topic Categories

The top 5 topic categories associated with the keyword.

Trend and period filter

The 12-month trend is built from monthly search history summed across all returned items so the line matches the headline magnitude. The two real series (ChatGPT and Google AI Overview) are trimmed to a common end month because Google publishes AI Overview data on a slower cadence than ChatGPT. The estimated series are the ChatGPT spine scaled by each platform's weight.

The period selector is free

The API always returns the full 12 months. Switching between 1 / 3 / 6 / 12 months re-slices and recomputes totals and deltas entirely in your browser — no new lookup is fired and no quota is consumed. The default period is 12 months.

Intent badge

A rule-based classifier (no LLM) labels the keyword by matching keyword prefixes. Transactional terms are checked first, then commercial, then informational; anything unmatched defaults to informational at low confidence.

IntentTriggered by terms likeExample
Transactionalbuy, price, coupon, deal"buy crm software"
Commercialbest, vs, review, top"best crm for startups"
Informationalwhat is, how to, guide"what is a crm"
Navigationalbrand / product navigation terms"salesforce login"

Relevant Prompts (AI-generated, not captured)

These are example prompts, not real user prompts

The Relevant Prompts table shows buyer-style questions that Gemini invents for the topic — they are AI-generated examples, NOT captured real user prompts. Each carries a summary, a full question, an intent tag, and a short search keyword that Gemini extracts (2-4 word noun phrase).

A page lookup returns five relevant prompts by default. The volume column for each is filled in asynchronously: the frontend sends each prompt's search keyword to a follow-up endpoint that runs DataForSEO cross-aggregated calls (Google AI Overview + regionally weighted ChatGPT) and returns a per-keyword AI search volume, cached for 24 hours. Onboarding lookups produce no relevant prompts.

Plan Gating & Quotas

Prompt Volumes is a paid feature — the Free plan has no access and sees an upgrade gate. There are three separate, independently metered quotas related to Prompt Volumes, plus a hard monthly spend wall that sits above all of them.

Free plan: locked

The Free tier ($0, permanent) cannot run Prompt Volumes lookups at all. All quotas below are 0 for Free.

(a) Page lookups — daily vs monthly cadence by plan

The main page-lookup cap uses a monthly cadence on the lower tiers and a daily cadence on Pro and Enterprise. Monthly counters reset on the 1st of the next month; daily counters reset at midnight.

PlanPricePage lookup capCadence
Free$0Locked (no access)
Starter$59/mo2 lookupsper month
Lite$139/mo5 lookupsper month
Pro$479/mo25 lookupsper day
EnterpriseCustom200 lookupsper day

Cache hits and outages are refunded

The quota counter increments up front and is decremented again if the lookup did not fire a fresh charge — so a cached result and a service_unavailable result both cost you nothing against your cap.

(b) Onboarding AI Search Volume — separate daily budget

The lighter onboarding lookup (used in brand onboarding Step 3) has its own per-day budget so onboarding bursts never drain your page-lookup allowance.

PlanOnboarding lookups / day
Free0
Starter5
Lite6
Pro30
Enterprise60

(c) Topics Performance "AI Volume" column — Pro+ only

The AI Overview page's Topics Performance card has an "AI Volume" column that batches up to 10 keywords per call. It is locked below Pro and metered as batches per day. A batch only counts when at least one keyword in it is uncached.

PlanTopics Performance batches / day
Free / Starter / Lite0 (locked)
Pro20
Enterprise100

Spending credits past the cap

When a paid-plan user exhausts the page-lookup cap, they can spend AI credits to keep going at a rate of 5 credits = 1 lookup.

  • Available only on the page surface, never on onboarding.
  • Credits are checked up front but deducted only after a confirmed fresh DataForSEO charge — cache hits and upstream failures never burn credits.
  • Deducts from your monthly plan_credits first, then from never-expiring extra_credits; you need at least 5 available.
  • The Free plan can never redeem (no Prompt Volumes access at all).

The real ceiling is the monthly spend wall

Independent of the lookup caps, all Prompt Volumes spend is bounded by a per-plan monthly USD budget: Free $0 (disabled), Starter $20, Lite $40, Pro $75, Enterprise unlimited. When exceeded, a lookup is denied (and the quota is refunded). The lookup cap is the soft throttle; this budget is the hard wall.

Watchlist & History

Save the keywords you care about so you can re-run them later without retyping. The watchlist is a per-brand list of saved keywords, each remembering its region and language.

1

Save a keyword

Click the star on the search bar to save the current keyword (with its region and language) to the active brand's watchlist.

2

Re-run anytime

Re-running a saved keyword within 24 hours hits the cache, so it returns instantly and for free.

3

Remove

Delete a watchlist item when it is no longer relevant; the watchlist cascade-deletes with its brand.

No automatic refresh

The watchlist is a manual saved-keyword list — there is no background task that refreshes it. Uniqueness is enforced per brand + keyword + region + language, so saving the same combination twice is rejected as a duplicate.

A "recent searches" list also surfaces your most recent lookups (newest first) so you can jump back to a previous result. The page URL (carrying the keyword, region, and period) is the source of truth, which makes a result link shareable and refresh-safe.

Page states

StateWhen it appearsWhat you see
LoadingA fresh lookup is running"Crunching the numbers..."
Insufficient dataKeyword too obscure (no AI activity)"Not enough AI search activity" + suggested broader terms
Service unavailableAll upstream calls failed"Service temporarily unavailable, try again" (no quota consumed)
Select a brandNo brand chosen in the pickerA prompt to pick a brand first
Upgrade gateFree planAn upgrade prompt — Prompt Volumes requires a paid plan

Not currently shown

Earlier "Demographics" and "Keyword Hierarchy" tabs were removed (Demographics had no trusted data source; Hierarchy added little beyond Topic Categories). The backend still computes hierarchy data internally, but it is not surfaced in the UI.

Routes & API Reference

Prompt Volumes is reached from the AI Visibility group in the sidebar. Below is the page route and the backend endpoints that power it (all under /api/v1, all requiring an active subscription).

Prompt Volumes

/prompt-volumes

The main research page (AI Visibility group). The old /ai-mentions route redirects here.

API endpoints

MethodPathPurpose
POST/prompt-volumes/lookupRun or serve a keyword lookup (keyword, region, language, period, brand, purpose, force_refresh, use_credits)
GET/prompt-volumes/quotaLookup quota status (used / max / remaining, cadence, credits available) — no DataForSEO cost
POST/prompt-volumes/prompts-volumeAsync per-prompt volume fill (1-10 keywords per call)
GET/prompt-volumes/recentRecent lookups for the org, newest first
GET/brands/{brand_id}/prompt-volumes/watchlistList a brand's saved keywords
POST/brands/{brand_id}/prompt-volumes/watchlistSave a keyword to the brand watchlist
DELETE/prompt-volumes/watchlist/{item_id}Remove a watchlist item

Error codes

HTTPCodeMeaning
403PROMPT_VOLUMES_PLAN_REQUIREDPlan does not include page lookups (e.g. Free)
403ONBOARDING_PV_PLAN_REQUIREDPlan does not include onboarding lookups
403TOPICS_PERFORMANCE_PLAN_REQUIREDTopics Performance AI Volume requires Pro+
429PROMPT_VOLUMES_DAILY_LIMITDaily page-lookup cap reached (Pro / Enterprise)
429PROMPT_VOLUMES_MONTHLY_LIMITMonthly page-lookup cap reached (Starter / Lite)
429ONBOARDING_PV_DAILY_LIMITOnboarding lookup daily cap reached
429TOPICS_PERFORMANCE_DAILY_LIMITTopics Performance batch daily cap reached
402INSUFFICIENT_CREDITSFewer than 5 credits available to redeem a lookup
402PV_REDEMPTION_NOT_ALLOWEDCredit redemption not allowed on this surface (e.g. onboarding)

Default lookup parameters

Lookups default to region United States (location code 2840) and language English. The UI exposes region, language, and period (1 / 3 / 6 / 12 months) selectors; the trend periods are derived client-side from a single 12-month payload.

SEO Module

SEO Module Overview

TruIntel's SEO module pairs traditional search optimization with the AEO engine. It runs on two engines: free homepage-level checks powered entirely by free Google APIs and self-hosted parsing, and paid domain-level metrics from DataForSEO plus a self-hosted site crawler. Keyword data is Google Search Console first, with DataForSEO only enriching volume and difficulty.

Free Checks Engine

Homepage-level analysis using Google PageSpeed Insights, Chrome UX Report, SSL, meta, robots, structured data, readability and content quality. No paid vendor, runs for every brand starting at onboarding.

Paid Checks Engine

Domain Authority, backlink profile, referring domains and competitor DA from DataForSEO. Gated by a $5/brand/month SEO budget; degrades gracefully when funds run low.

Self-Hosted Crawler

A breadth-first httpx + BeautifulSoup site crawler that powers the on-page technical audit, crawl visualization and image audit on a dedicated queue.

GSC-First Keywords

Tracked keyword positions, clicks, impressions and CTR come from Google Search Console. DataForSEO Labs only enriches volume/difficulty and supplies optional top-organic keywords.

No single SEO score

There is no one composite backend SEO score. The Site Health gauge is computed client-side as a plain average of four components (see SEO Dashboard). Other distinct scores include the On-Page SEO Checker grade, per-page crawler penalty scores and content-quality buckets.

SEO Dashboard

/seo

Site Health gauge, search performance, backlinks, competitors and quick wins.

PageSpeed

/seo/pagespeed

Mobile + desktop Lighthouse scores, Core Web Vitals and per-page scans.

Backlinks

/seo/backlinks

Backlink profile, toxic detection and disavow file generation.

Keywords

/seo/keywords

GSC-first keyword rankings, position changes and alerts.

Site Audit

/seo/audit

Site-wide BFS crawler technical audit results.

Competitors

/seo/competitors

Competitor DA, trust, backlinks and keyword overlap.

Images

/seo/images

Image audit: alt text, file size, format and indexability.

Keyword Suggestions

/seo/keyword-suggestions

DataForSEO Labs suggestions from a seed keyword (1 credit each).

Keyword Gap

/seo/keyword-gap

Competitor keyword opportunity buckets (Pro+).

Backlink Gap

/seo/backlink-gap

Domains linking to competitors but not you (Pro+).

On-Page Checker

/seo/onpage-checker

On-demand single-URL audit, ~90 checks with A-F grade.

Crawl Visualization

/seo/visualization

Interactive React Flow graph of your internal link structure.

SEO Dashboard

The SEO Dashboard aggregates PageSpeed, keyword rankings, backlink analysis and on-page audit data into a single view headed by the Site Health gauge. It is the landing page for the SEO module and is route-accessible on every plan, though Free brands only ever see data from their single onboarding audit.

Site Health Score

A client-side average of PageSpeed mobile, PageSpeed desktop, Domain Authority and SSL status. Shows last-checked and next-update timestamps.

Domain Authority & Trust

DA (0-100) and Trust Score tracked over time with a competitor comparison bar chart.

Page Speed

Mobile and desktop Lighthouse scores side-by-side with a Core Web Vitals breakdown.

Backlinks & Referring Domains

Total backlinks and referring-domain counts with change indicators versus the previous report.

  • Site Health stats bar — pages crawled, issues found, average response time, average page score and broken links
  • Search Performance card — GSC clicks, impressions, CTR and average position over time on an interactive line chart
  • Top Pages by Inbound Links — pages with the most internal links pointing to them
  • Quick Wins section — dynamic alerts for PageSpeed under 50, SSL expiration, broken links and image issues
  • Images preview — table of images missing alt text with an inline fix button
  • Competitor SEO card — top competitors with DA, trust score, backlinks and referring domains
  • DA & Trust vs Competitors — horizontal bar chart comparing your domain against tracked competitors

Site Health Score Formula

The Site Health Score is computed entirely on the client as a simple average of whichever of four components are present. It is the single source of truth shared by the Overview "SEO Health Score" card and the SEO Dashboard "Site Health" gauge. There is no separate backend aggregate, and there is no "technical health" term.

Site Health Score (average of available components)

1/n
1/n
1/n
1/n
PageSpeed Mobile (0-100) (1/n)
PageSpeed Desktop (0-100) (1/n)
Domain Authority (0-100) (1/n)
SSL Status (1/n)
  • SSL is scored valid = 100, expiring = 60, any other status = 0
  • Only the components that are present are averaged, then rounded; the score is null when none are present
  • This matches the backend Site-Audit "Site Health" definition used by the visibility site-audit service

Why your score may show fewer components

On Free plans, or when DataForSEO funds are exhausted, Domain Authority may be missing and the average is taken over the remaining components. A degraded or estimated DA can shift the score, so always check the underlying tiles.

Free SEO Checks

Every brand gets a suite of free, homepage-level SEO checks that require no paid vendor. Nine checks run in parallel, with mobile-friendliness derived from the PageSpeed mobile score and an HTTP security-headers analysis added from already-captured response headers. Each check has its own timeout and fails gracefully without blocking the others.

  1. PageSpeed Insights (Google PSI v5) — mobile and desktop, with performance / SEO / accessibility / best-practices category scores (30s timeout, retries on 429/500/502/503)
  2. Core Web Vitals — LCP, INP and CLS field data from the Chrome UX Report (CrUX)
  3. SSL certificate — validity, issuer and expiry via an HTTPS HEAD request
  4. Structured data — JSON-LD schema detection with types and details
  5. Meta-tag audit — title, description, Open Graph, Twitter cards, hreflang and canonical
  6. Robots.txt & Sitemap — validity, sitemap URL count and blocking rules
  7. Readability — Flesch Reading Ease and Gunning Fog index
  8. Content quality — heading hierarchy, links, image alt text and paragraphs (0-100 buckets)
  9. Technology detection — CMS, frameworks, analytics and CDN identification
  10. Mobile-friendly (derived) — from the PSI mobile score: 90+ good, 50+ needs improvement, under 50 not friendly
  11. HTTP headers (derived) — security-header analysis from the captured response headers

Core Web Vitals measure INP, not FID

TruIntel reads LCP, INP (Interaction to Next Paint) and CLS from the Chrome UX Report. First Input Delay (FID) is deprecated and is not measured anywhere in the product.

Free plan: one audit total

On the Free plan the free checks run exactly once — the onboarding audit. A second refresh returns FREE_PLAN_SEO_LIMIT. Paid plans re-run them on a schedule and on demand.

PageSpeed & Core Web Vitals

PageSpeed combines lab data (Lighthouse via PSI v5, mobile and desktop) with field data (Chrome UX Report). Lab data yields detailed metrics and category scores plus prioritized performance opportunities; field data reflects real users at the 75th percentile.

MetricWhat It MeasuresGood TargetPoor Threshold
LCP (Largest Contentful Paint)Loading — time until the largest visible element renders<= 2.5 s> 4.0 s
INP (Interaction to Next Paint)Interactivity — responsiveness across all interactions<= 200 ms> 500 ms
CLS (Cumulative Layout Shift)Visual stability — how much the layout shifts while loading<= 0.1> 0.25
FCP (First Contentful Paint)Time until the first content appears< 1.8 s> 3.0 s
TTI (Interactive)Time until the page is fully interactive< 3.8 s> 7.3 s
TBT (Total Blocking Time)Total time the main thread was blocked< 200 ms> 600 ms
Speed IndexHow quickly content is visually displayed< 3.4 s> 5.8 s
TTFB (Server Response Time)Time to the first byte from the server< 800 ms> 1.8 s
  • Category scores — performance, SEO, accessibility and best-practices are captured for both mobile and desktop
  • Performance opportunities — estimated ms/byte savings for render-blocking resources, unused CSS/JS, modern image formats, responsive images, text compression, image encoding and long cache TTL
  • Diagnostics — server response time, DOM size, total byte weight, main-thread work breakdown, bootup time and third-party count
  • Per-page PageSpeed scanning — scan multiple pages, track progress and rescan individual pages from the PageSpeed page

PageSpeed quota per refresh

Each SEO refresh consumes one of your monthly PageSpeed checks: Free 1, Starter 5, Lite 5, Pro 15, Enterprise 30 per month. Color-coded statuses (green good, amber needs improvement, red poor) and trend lines track the impact of optimizations over time.

Keyword Rankings & Google Search Console

Keyword tracking is Google Search Console first. Connecting GSC gives you real positions, clicks, impressions, CTR and average position per query, with DataForSEO only enriching volume and difficulty. Without GSC, ranking coverage is limited to enriched and top-organic data.

  • Position distribution — breakdown of keywords in Top 3, Top 10, Page 2 and below
  • Position changes — which keywords improved or declined, with delta indicators
  • Search volume & difficulty — estimated monthly searches and competition level
  • Filter tabs — Improved, Declined, Top 10 and All keywords
  • Keyword history chart — position trends for individual keywords over time
  • Position alerts — notifications when important keywords move significantly
GSC PropertyDetail
OAuth scopeRead-only; tokens are Fernet-encrypted at rest
Initial syncLast 90 days of search performance
Daily syncRolling last 28 days, refreshed daily at 05:00 IST
Data lag3-day lag on the end date (Google publishes data with a delay)
Position change windowCompared against records at least 7 days old
Connect flowSettings -> Integrations -> Connect GSC (popup OAuth), then select a property

Connect GSC for the full picture

GSC provides real click-through rate, actual impressions and the search queries you rank for, including long-tail terms. Without it, TruIntel relies on third-party enrichment that will not include every query.

On-Page Technical Audit (Crawler)

TruIntel's self-hosted breadth-first crawler (httpx + BeautifulSoup, concurrency 3, with optional JS-link recovery) scans your whole site and stores a detailed record per page. It runs on a dedicated crawl queue with a 30-minute time limit, separate from the inline paid checks.

Stored per pageExamples
Meta & canonicalTitle, meta description, canonical URL, html lang, noindex/nofollow flags
StructureH1/H2/H3 counts, word count, image count, images without alt
LinksInternal, external and broken link counts
ResponseStatus code, response time (ms), page size (bytes), crawl depth, content hash
Scoringissues[], overall_score and extended_data

Per-page score

Each page starts at 100 and loses points for each issue by severity: critical -20, high -15, warning -10, medium -8, low -3, info -2, floored at 0.

  • Crawl summary carries the site graph (nodes + edges), crawl budget, sitemap stats, security headers and computed site warnings
  • Per-brand page cap: Free 500, Starter 10,000, Lite 50,000, Pro 100,000, Enterprise 200,000 — enforced by a post-run truncation
  • Image optimization is a byproduct of the crawl: every <img> is extracted and HEAD-fetched for file size, alt text, format, dimensions, indexability and loading attribute

On-Page SEO Checker (Single URL)

The On-Page SEO Checker is an on-demand tool that audits any single public URL in under 45 seconds and returns roughly 90 checks across 10 weighted categories, each with recommendations and quick wins. It is distinct from the site-wide crawler audit — use the Checker for a fast deep-dive on one page.

CategoryWeight
Meta14
Content12
Headings10
Images10
Links10
Security10
Performance10
Schema8
Mobile8
Accessibility8
  • Each category score = (passed x 1.0 + warning x 0.5) / checks x 100; the overall is the weighted average
  • Letter grade: A >= 90, B >= 80, C >= 70, D >= 50, F < 50
  • Render modes: auto, browser (Playwright fallback for SPAs) or http
  • Works on any public URL — the brand only owns the scan for quota and history purposes

Competitor SEO Comparison

Compare your SEO metrics against tracked competitors to see how your domain authority, backlinks and keyword footprint stack up. Competitor metrics come from the paid-checks competitor comparison run.

  • Domain Authority, trust score, backlinks and referring domains per competitor
  • Competitor top keywords with a dropdown selector
  • Keyword overlap analysis — shared vs unique keywords
  • DA & Trust vs Competitors comparison chart
  • Track multiple competitors simultaneously, up to your plan limit

Competitor limits

Tracked competitors per brand: Free 1, Starter 1, Lite 3, Pro 5, Enterprise 5. Competitor SEO data only refreshes as a byproduct of a full paid-checks run.

Keyword Suggestions

Keyword Suggestions returns up to 50 related keywords from the DataForSEO Labs keyword-suggestions API for a seed keyword you enter, scoped to your country. Each suggestion includes search volume and difficulty so you can prioritize, and history is saved for reuse.

  • Enter a seed keyword to get up to 50 country-scoped suggestions
  • Each suggestion shows search volume and keyword difficulty
  • One-click add to your tracking keyword list
  • Suggestion history is saved per brand

Not AI-powered — costs 1 credit per request

Suggestions come from DataForSEO Labs seeded by your keyword, not from an AI model. Each request costs 1 AI credit from your monthly pool (Starter 50, Lite 150, Pro 500, Enterprise 1000 credits/mo). A paid plan is required; there is no separate monthly suggestion cap.

Image Optimization

The image audit is a byproduct of the site crawl. Every image on crawled pages is extracted, HEAD-fetched for its file size, and analyzed for SEO best practices including alt text, format, dimensions and indexability.

  • Detect oversized images that slow down page load (real file sizes via HEAD fetch)
  • Flag missing or poor alt text and decorative images
  • Recommend modern format conversions (e.g. PNG to WebP)
  • Identify images without specified dimensions or proper loading attributes
  • Track indexability per image alongside the page it appears on

Backfill sizes

A backfill-sizes action re-fetches file sizes for images that were missing size data, so the audit can flag heavy images even after the initial crawl.

Crawl Visualization

Crawl Visualization renders your site's internal link structure as an interactive directed graph built from the crawler's forward links. It uses React Flow to draw pages as nodes and internal links as edges, helping you spot orphan pages, overly deep pages and crawl issues.

  • Interactive graph with zoom, pan and node selection
  • Detail panel showing page title, path, status, depth, score, issues, response time, word count, noindex flag and link counts
  • Orphan page detection — pages with no internal links pointing to them
  • Crawl-depth view — how far each page sits from the homepage
  • Graph metadata: total nodes/edges, max depth and root URL

SEO Monitoring Schedule

SEO checks run on the Celery beat scheduler in Asia/Kolkata (IST). All times below are genuine IST. On-demand refreshes are also available, subject to per-plan quotas and a rate limit.

TaskWhen (IST)Plans
Monthly full SEO (free + paid + crawl)1st of month, 04:00All paid
Weekly SEO (DA, backlinks, competitors, crawl)Monday 04:00Pro + Enterprise only
Daily GSC keyword syncDaily 05:00Paid, GSC connected
Daily indexation checkDaily 05:30Pro+ with GSC
Weekly backlink verificationWednesday 04:00All paid
SEO report cleanup (delete > 180 days)QuarterlyAll

On-demand refresh

  • Default refresh runs free checks only (homepage PageSpeed mobile + desktop, SSL, meta, robots/sitemap, structured data, readability, content quality, tech)
  • A full refresh also queues paid checks (DA/backlinks/competitors) and a site crawl — paid plans only; on Free these are skipped
  • Rate limit: 1 refresh per hour per brand (the first-time onboarding full check is exempt)
  • Each refresh consumes 1 of the monthly PageSpeed quota

Weekly SEO is Pro+ only

The weekly DA/backlinks/competitors/crawl pass runs Monday at 04:00 IST and is limited to Pro and Enterprise. Starter and Lite get the monthly full pass only.

SEO Plan Limits & Gating

SEO capabilities scale with your plan. Dashboard, PageSpeed, Site Audit, On-Page Checker and Crawl Visualization pages are route-accessible on every plan, but Free brands only ever see data from their single onboarding audit and paid tiles show "—" or an upgrade prompt.

CapabilityFreeStarterLiteProEnterprise
Free checks (PSI/CWV/SSL/meta)1 audit totalYesYesYesYes
Scheduled SEO refreshOnboarding onlyMonthlyMonthlyWeekly + MonthlyWeekly + Monthly
PageSpeed checks / month1551530
Tracked SEO keywords07502,0005,00010,000
Top-organic keywords5050100200500
Crawl pages50010,00050,000100,000200,000
Competitors11355
Toxic backlinks + disavowNoNoNoYesYes
Keyword Gap / Backlink GapNoNoNoYesYes
Keyword SuggestionsNo1 credit each1 credit each1 credit each1 credit each
Rank TrackingNoNoNoYesYes
Indexation MonitoringNoNoNoYesYes

Adjacent "Analyze" SEO features

Internal Linking (Free), Indexation Monitoring (Pro+, via GSC URL Inspection), CTR Optimization (Starter+, from GSC performance data) and Rank Tracking (Pro+, DataForSEO SERP) live in the SEO Analyze nav group and are documented in their own sections.

SEO Analyze Tools

New

Overview

The SEO Analyze tools are four on-page and ranking utilities that turn your existing crawl, Google Search Console, and SERP data into specific, actionable fixes. They live under the SEO section nav in two groups: "On-Page & Indexing" (Internal Linking, Indexation Monitoring, CTR Optimization) and "Keywords & Rankings" (Rank Tracking).

Internal Linking

On-demand crawl that surfaces orphan pages, suggested internal-link opportunities with anchor + context sentence, and a PageRank-style authority map. Starter+.

Indexation Monitoring

Tracks which pages Google has indexed via the GSC URL Inspection API, alerts on deindexation, and charts coverage over time. Pro+ with a connected GSC.

CTR Optimization

Finds high-impression / low-CTR pages from your synced GSC data and generates query-aware AI title + meta rewrites with a before/after preview. Starter+.

Rank Tracking

Brand-scoped Google SERP-position tracking via DataForSEO, organised into keyword projects with movement, distribution, and history. Pro+, paid, manual runs.

Where each tool gets its data

ToolData sourceNeeds GSC?Extra cost?
Internal LinkingOn-demand site crawler (own crawler)NoNo
Indexation MonitoringGSC URL Inspection API (webmasters.readonly scope)YesNo (free Google API)
CTR OptimizationGSC Search Analytics performance data (already synced)YesNo
Rank TrackingDataForSEO Google organic SERPNoYes (metered)

GSC dependency, in one line

Indexation Monitoring and CTR Optimization both ride your existing Google Search Console connection (no re-consent, no new vendor). The account-wide token can analyze any verified property. Internal Linking and Rank Tracking do not need GSC at all.

Plan gates at a glance

ToolMinimum planCadence
Internal LinkingStarterManual / on-demand
CTR OptimizationStarterManual / on-demand
Indexation MonitoringProDaily 05:30 IST + on-demand
Rank TrackingProManual / on-demand only

Reachable vs. usable

Internal Linking and Indexation pages are reachable on any plan, but below the paid gate the API returns an in-page upgrade state ("Internal Linking is a paid feature" / "Indexation Monitoring is a Pro feature"). CTR Optimization and Rank Tracking are gated at the route level (minimum Starter and Pro respectively).

Internal Linking

Internal Linking runs an on-demand scan of any public website (defaulting to your brand domain) and returns three things: orphan pages with no inbound internal links, internal-linking opportunities (a source page that already talks about a target topic but does not yet link to it), and a PageRank-style link-authority distribution that flags important pages starved of internal links.

Plan gate

Starter and up. Monthly scan quota: Starter 5, Lite 15, Pro 50, Enterprise 200. The quota resets on the 1st of each month. Free returns an in-page "paid feature" upgrade state.

What a scan finds

Orphan pages

Pages with zero inbound internal links. Search engines and users struggle to discover these, so they typically under-perform.

Linking opportunities

A source page that mentions a target page topic but does not link to it. Each opportunity includes a suggested 2-5 word anchor and the verbatim existing sentence to place the link in.

Link authority

A PageRank-style 0-100 distribution across pages, plus an "under-linked important pages" list (300+ words with only 1-2 inbound links).

How it works

Each scan runs a fresh same-site crawl (it does not read a cached content index), then builds the page corpus and link graph in memory. The only AI step validates candidate opportunities and writes the anchor text.

ParameterValue
Crawl typeHTML-only, same-site BFS, robots-respecting
Max depth / concurrencydepth 4 / 6 concurrent requests
Pages per scanDefault 100, configurable 5-300
Orphan definition0 inbound internal links
Under-linked definition300+ words AND only 1-2 inbound links
Targets analysedTop 15 (orphans first, then under-linked)
Candidate rankingTF-IDF cosine + keyword overlap (title/H1 up-weighted), top 5 per target
PageRankDamping 0.85, 40 iterations, scaled 0-100

AI is optional, not load-bearing

The LLM (via the provider-agnostic chain) confirms relevance, proposes the anchor, and returns the context sentence, dropping anything below 40 relevance. If the LLM is unavailable, a deterministic fallback keeps the top 2 candidates and clamps relevance to the 40-80 range so scans never fail outright.

Applying a suggestion

1

CMS-authored page

Apply inserts the link into the content and republishes the page to the edge automatically.

2

Any non-CMS page

TruIntel returns a "manual insertion required" response and the UI shows a Copy button that copies the ready-made <a href="target">anchor</a> for you to paste.

The page

The landing hero invites a scan; once a scan completes you get a stat strip (Orphan pages, Opportunities, Pages analysed, Avg links / page) and sticky pill tabs.

  • Opportunities tab: a table of "Source to Target" rows with the italic context sentence, a suggested-anchor pill, a relevance score, and Apply / Copy / Dismiss actions.
  • Orphan Pages tab: the list of pages with no inbound links.
  • Authority tab: the link-authority distribution plus the under-linked important pages table.
  • States covered: empty ("No linking opportunities found" / "No orphan pages"), loading ("Discovering internal links..."), error, scan-incomplete, and the paid-feature upgrade gate.

Manual only

Internal Linking scans are on-demand only. There is no scheduled job, and a scan is guarded so you cannot launch a second one while one is already running for the same brand and target.

Internal Linking page

/internal-links

Run scans and review orphans, opportunities, and authority.

Queue a scan

POST /api/v1/seo/{brand_id}/internal-links/scan

Body { target_url?, max_pages? }. Consumes 1 monthly scan slot.

Get results

GET /api/v1/seo/{brand_id}/internal-links

Orphans + opportunities + authority; filter=active|pending|applied|dismissed.

Scan status

GET /api/v1/seo/{brand_id}/internal-links/status

Live scan progress (pending/running/complete/failed/idle).

Apply / Dismiss

POST .../internal-links/{suggestion_id}/apply | /dismiss

Insert the link (CMS republish) or dismiss the suggestion.

Indexation Monitoring

Indexation Monitoring tracks whether Google has indexed each of your pages using the Google Search Console URL Inspection API. It buckets every URL as indexed, not-indexed, excluded, or error, detects deindexation transitions (was indexed, now not), emails an alert when that happens, and charts coverage over time.

Plan gate + requirement

Pro and Enterprise only, and it requires a connected Google Search Console. It rides the existing webmasters.readonly OAuth scope, so there is no re-consent and no new vendor.

TruIntel never force-indexes

There is no API to force a page into Google index. A "re-check" only re-inspects the URL and the UI never promises indexing. Indexation Monitoring is observability, not a submission tool.

The coverage buckets

BucketMeaning
IndexedVerdict PASS / "Submitted and indexed". The only bucket where is_indexed is true (deindexation alerts key off it).
Not indexedCrawled or discovered but not currently indexed.
ExcludedDeliberately excluded: noindex, canonical, duplicate, redirect, or robots-disallowed.
ErrorFetch, robots, or server failure including 404, soft-404, and server errors.
UnknownNo coverage signal returned.

Rule order matters

Robots/meta blocking is evaluated BEFORE the PASS check, so a page reported as "indexed though blocked by robots.txt" is bucketed as Excluded and can surface as a deindexation event. This ordering is deliberate.

Daily budget and pacing

Google caps URL Inspection at roughly 2,000 calls/day and 600/min per property. TruIntel enforces a per-brand, per-property daily counter capped at min(plan limit, 2000) and paces requests at about 6/second to stay under the per-minute ceiling.

PlanURL inspections / day / property
Pro1,000
Enterprise2,000

The list of URLs to inspect is built on demand by crawling the chosen property (sitemap + links, hard-capped at 1,000 pages, cached 6h). Within the daily budget it prioritises never-checked URLs first, then the least-recently-checked, rotating the long tail across days so coverage stays fresh.

Schedule and alerts

  • A daily scheduled indexation check runs at 05:30 AM IST (staggered just after the 05:00 GSC sync) for Pro+ brands with a connected GSC.
  • You can also run a check on demand ("Check now") or re-check a single URL.
  • A single concise deindexation email is sent after a run commits, only for confirmed indexed-to-not transitions, never for a transient error.
  • A daily IndexationSnapshot row records the indexed / not-indexed / excluded / error counts that power the trend chart.

The page

  • Stat cards: Indexed, Not indexed, Excluded, Errors.
  • A coverage donut (Indexed / Not indexed / Excluded / Errors) plus an "Indexed over time" trend line.
  • A URL table with columns URL, Status, "Google's reason" (coverage state), Last crawled, and a per-row Re-check action.
  • A Recent checks history with expandable check detail.
  • States: no-brand, error, the "Indexation Monitoring is a Pro feature" upgrade gate, "Connect Google Search Console", "This site isn't in your Search Console account" (reconnect), and "Run first check" / "Try again".

Indexation page

/indexation

Coverage summary, donut, trend, and per-URL status.

Summary + URLs

GET /api/v1/seo/{brand_id}/indexation

Counts + paginated URL list; filter, search, property_url, budget snapshot.

Coverage trend

GET /api/v1/seo/{brand_id}/indexation/trend

IndexationSnapshot series by day and property.

Run a check

POST /api/v1/seo/{brand_id}/indexation/check

Queue a full property check; respects the daily budget (429 when exhausted).

Re-check one URL

POST /api/v1/seo/{brand_id}/indexation/recheck

Re-inspect a single URL on demand.

Check history

GET /api/v1/seo/{brand_id}/indexation/checks

Recent-check list and per-check detail.

CTR Optimization

CTR Optimization finds pages that already earn impressions in Google but get clicked far less than their position should deliver, then writes query-aware AI title and meta-description rewrites for the biggest opportunities, with a before/after Google preview and one-click apply (CMS pages) or copy (anything else).

Plan gate + requirement

Starter and up. It uses the GSC performance data TruIntel already syncs, so there is no extra cost, but it does require a connected Google Search Console. Monthly suggestion quota: Starter 5, Lite 15, Pro 50, Enterprise 200, resetting on the 1st.

How an opportunity is found

TruIntel pulls GSC Search Analytics on the page dimension over a default 28-day lookback that ends 3 days back (to dodge GSC data lag), then compares each page's actual CTR against an expected-CTR-by-position curve.

SettingValue
Default lookback28 days, ending 3 days back (configurable 7-90)
Minimum impressions50 (configurable 10-10000)
Position rangePositions 1-30 qualify
Gap thresholdActual CTR below 0.7x expected CTR
Potential clicksround(impressions x (expected - actual)), must be at least 1
AI rewrites generatedTop 12 opportunities per scan, by potential clicks
Title / meta limitsTitle up to 60 chars, meta up to 155 chars

Site-calibrated curve avoids false positives

Rather than only using a static benchmark curve (pos1 ~28%, pos2 ~15%, decaying to ~0.4% at pos30), TruIntel builds a site-specific curve from the median actual CTR in each position bucket (positions with at least 5 qualifying rows). This stops a brand or geo query already earning ~50% CTR at position 1 from being wrongly flagged against the generic 28% benchmark; sparse buckets fall back to the static curve.

Two ways to run it

1

Full "Analyze CTR" scan

Set Property, Lookback, and Min impressions, then run a scan. It creates a queued analysis, ranks opportunities, and generates AI rewrites for the top 12. Gated on the monthly suggestion limit but not run-metered.

2

Inline single-page suggestion

Generate an AI title/meta for one page on demand. This consumes 1 monthly slot, and the slot is refunded if generation fails.

Applying a suggestion mirrors Internal Linking: a CMS-managed page is updated and republished to the edge, while any other page falls back to manual copy buttons.

The page

  • Landing hero "Find your CTR wins" with Property + Lookback + Min impressions inputs and an "Analyze CTR" button, plus Recent Analyses pills.
  • Scan detail: a stats header (Opportunities count, Potential clicks +N, Window) and an Opportunities table (Page, impressions, CTR, position, potential clicks).
  • Optimize modal: a before/after Google SERP preview with the AI title/meta and apply or copy actions.
  • States: GSC-required, the Free-plan "Upgrade to Connect" gate, and empty "No CTR opportunities".

Manual only

CTR Optimization is on-demand only. There is no scheduled job; you trigger every analysis and suggestion yourself.

CTR Optimization page

/ctr-optimization

Run analyses and review CTR opportunities.

Opportunities

GET /api/v1/seo/{brand_id}/ctr/opportunities

Ranked opportunities + summary for a property.

Suggest (1 slot)

POST /api/v1/seo/{brand_id}/ctr/suggest

Generate AI title/meta for one page; refunded on failure.

Apply / Dismiss

POST .../ctr/apply | /ctr/dismiss

Apply title/meta (CMS republish or manual copy) or dismiss.

Analyze CTR scan

POST /api/v1/seo/{brand_id}/ctr/scans

Queue a scan { property_url?, lookback_days, min_impressions, max_opportunities }.

Scan history / triage

GET .../ctr/scans · PATCH .../scans/{id}/opportunities/{id}

Recent analyses and open/dismissed/done triage.

Rank Tracking

Rank Tracking monitors your keywords' Google organic SERP positions via DataForSEO. You group a domain or URL plus a set of keywords into a "project" (with a chosen country, device, and language), and each on-demand run checks every active keyword's position, diffs it against the previous run, and stores the movement.

Pro+, paid, manual only

Rank Tracking uses DataForSEO, which is metered paid spend, so it is Pro and Enterprise only, runs on-demand only (no scheduled job), and is protected by a triple budget guard. An unfunded account fails a run loudly rather than silently storing "all not ranking".

Project configuration

SettingValue / default
Countrycountry_code, default "us"
Devicedesktop or mobile
DepthSERP depth 10-100, default 100
Languagelanguage_code, default "en"
Statusactive or paused

The triple spend guard

GuardProEnterprise
Keywords per project25100
Runs per month (per brand)30120
Monthly USD budget (per brand)$10$40

A run is blocked if the estimated spend would push the brand over its monthly USD budget. The run-count and budget counters both reset on the 1st of the month.

Cost model

A live Google-organic SERP check at depth 100 costs about $0.0155 per keyword (scaled by depth, floor $0.0015/kw). Search-volume metric refreshes cost about $0.05 per request (covering up to 1,000 keywords). The actual charge is recorded exactly once per run from DataForSEO's own cost field in a finalize step, so it is never double-counted.

What a run records

  • Each keyword's current organic position and the change versus the previous run.
  • Movement summary: Avg position, Moved up, Moved down, Unchanged.
  • A distribution donut bucketed Top 3 / 4-10 / 11-100 / Not ranking.
  • An average-position-over-time line and a per-keyword history sparkline.
  • Per-keyword SERP competitors for the tracked query.

The page

  • An optional brand-wide spend strip, then a 2-column split: selectable project cards on the left (name, domain, keyword count, last run, latest avg position) and the ProjectPanel on the right.
  • ProjectPanel has a movement StatRow, the distribution donut + avg-position line, and Overview / Keywords / History tabs.
  • The Keywords table shows Keyword, Position, Change, Volume, and URL, with expandable per-keyword history sparkline and SERP competitors.
  • The "Run check" button shows a live cost estimate ("Run check ~ $X") before you spend.
  • Run status pills: Complete / Running / Queued / Failed, plus a run history list.

Rank Tracking page

/rank-tracking

Projects, keywords, runs, and spend.

Spend + caps

GET /api/v1/seo/{brand_id}/rank-tracking/spend

Brand spend with plan budget / runs / keyword caps.

Projects

GET/POST /api/v1/seo/{brand_id}/rank-tracking/projects

List or create a project with initial keywords.

Keywords

POST/DELETE .../projects/{id}/keywords

Add (capped) or soft-delete keywords; refresh-metrics enriches volume/CPC/competition.

Run estimate

GET .../projects/{id}/run-estimate

Estimated cost + remaining budget before running.

Queue a run

POST .../projects/{id}/runs

Triple-guarded rank check; queued to the seo worker.

Limits, Quotas & Resets

A consolidated reference for every plan limit, monthly reset, and route across the four Analyze tools.

Per-plan limits

LimitFreeStarterLiteProEnterprise
Internal-link scans / month051550200
CTR suggestions / month051550200
Indexation URL inspections / day0001,0002,000
Rank Tracking keywords / project00025100
Rank Tracking runs / month00030120
Rank Tracking budget / month$0$0$0$10$40

Everything resets on the 1st

Internal Linking scan quota, CTR suggestion quota, and the Rank Tracking run-count and USD budget all reset on the 1st of the month. Indexation's URL-inspection budget is separate — it is a per-day cap that resets every day, not monthly.

Routes

Internal Linking

/internal-links

Starter+. Reachable on any plan; shows an upgrade state below the gate.

Indexation Monitoring

/indexation

Pro+ with GSC. Reachable on any plan; shows an upgrade state below the gate.

CTR Optimization

/ctr-optimization

Route-gated at minimum Starter; requires GSC.

Rank Tracking

/rank-tracking

Route-gated at minimum Pro; paid DataForSEO spend.

Where they live in the nav

All four sit under the SEO section: Internal Linking, Indexation, and CTR Optimization in the "On-Page & Indexing" group, and Rank Tracking in the "Keywords & Rankings" group. All backend endpoints mount under /api/v1/seo.

Google Search Console

Overview

Connecting Google Search Console (GSC) links TruIntel directly to Google’s own Search Analytics and URL Inspection APIs, so every clicks / impressions / CTR / position number you see is pulled straight from Google — no third-party estimation or enrichment. The connection powers three distinct capabilities for each brand.

Search Performance dashboard

A live clicks / impressions / CTR / average-position dashboard that proxies the GSC Search Analytics API on demand, with a 15-minute cache for speed.

Daily keyword-ranking sync

Every day at 05:00 IST TruIntel stores GSC rows as KeywordRanking history records that feed the rest of the SEO surfaces.

Indexation Monitoring (Pro+)

Reuses the same read-only token to call the GSC URL Inspection API and track per-page index status.

Authorization uses a popup-based OAuth flow with a read-only scope, and the resulting tokens are encrypted at rest. Because the Google token is account-wide, one connected Google account can read every verified property in that account.

Two data paths, not one

The Search Performance page does NOT read the daily sync — it queries Google live per request (15-min cached). The daily 05:00 IST sync is a separate path that writes keyword-ranking history used by other SEO pages. Knowing which is which explains why the dashboard can be fresher than stored history.

Plan Availability

GSC connection and the Search Performance dashboard are available on every paid plan (Starter and up). The Free plan is explicitly blocked — the connect modal and the Search Performance page both render an upgrade prompt for Free accounts. Indexation Monitoring is gated higher, to Pro and Enterprise only.

CapabilityMinimum plan
Connect GSC / OAuth / manage propertyStarter (any paid plan)
Search Performance dashboard (summary / chart / table)Starter (any paid plan)
Search Performance page (/seo/keywords)Starter (any paid plan)
Immediate per-brand sync on connectStarter (Free brands rejected)
Daily 05:00 IST keyword syncStarter (any paid plan)
Indexation Monitoring (URL Inspection)Pro and Enterprise only

Free plan cannot connect GSC

GSC requires a paid plan. Free accounts see an upgrade state instead of the connect button, and any immediate-sync request from a Free brand is rejected on the backend.

Connecting Your Account

You can start the connection from two places: Settings → Integrations and the empty state of the Search Performance page. Both open the same shared connect modal.

1

Open the connect flow

Go to Settings → Integrations and click Connect Google Search Console, or use the Connect prompt on the Search Performance page empty state.

2

Authorize in the Google popup

A 600×700 OAuth popup opens. Sign in and grant read-only access. TruIntel requests offline access with a consent prompt so Google always returns a refresh token.

3

Pick a property (optional)

Choose the verified GSC property to track from the list. This step is now optional — if you skip it, TruIntel auto-selects the property matching your brand domain (or the only / first verified property).

4

Sync begins automatically

TruIntel queues an immediate keyword sync, then keeps it fresh with the daily 05:00 IST sync. The first sync pulls 90 days of history; each daily run refreshes the trailing 28 days.

Property selection is optional

If you close the modal before picking a property, TruIntel self-heals: it auto-resolves the property whose host matches your brand domain (preferring a sc-domain: Domain property), otherwise the sole or first verified property, and persists it. You no longer get silently-empty GSC data from skipping this step.

OAuth & Security

The connection is read-only and hardened against CSRF and token theft. TruIntel never requests write access to your Search Console.

  • Scope is webmasters.readonly — read-only access only, no ability to change anything in your Search Console.
  • The OAuth request uses access_type=offline and prompt=consent so Google always returns a refresh token for long-lived sync.
  • The OAuth state parameter is a signed JWT containing brand and user IDs plus a nonce, with a 10-minute expiry, protecting against CSRF.
  • The callback returns a tiny popup-close HTML page that postMessages the result back to the opener; the frontend validates the message origin before acting on it.
  • Both access and refresh tokens are Fernet-encrypted at rest (AES-128-CBC + HMAC-SHA256) using a server-side key.
  • Tokens auto-refresh proactively whenever they are within 5 minutes of expiry.

Revocation handling

If you revoke Google access, the next sync sees an invalid_grant error. TruIntel deactivates the integration, records the sync error, and raises a HIGH-severity in-app alert ("Google Search Console disconnected — reconnect required"). Performance requests then return a TOKEN_REVOKED error until you reconnect.

Disconnect is a hard delete

Disconnecting from Settings → Integrations deletes the stored integration row outright (tokens included) rather than just disabling it. Reconnecting starts a fresh OAuth flow.

Search Performance Dashboard

The Search Performance page lives at /seo/keywords (the URL says "keywords" but the page is titled Search Performance). It is a live mirror of your GSC Search Analytics data, queried per request with a 15-minute Redis cache, not a read of the daily sync.

Controls

ControlOptions
Date presets24h, 7d, 28d, 3 months (default), 6 months, 12 months, 16 months (16 months is the hard maximum range)
Search typeWeb (default), Image, Video, News (backend also accepts Discover and Google News)
Filter dimensionquery, page, country, device
Filter operatorcontains, notContains, equals, notEquals
Metric togglesclicks, impressions, CTR, position (all on by default)

Data table tabs

The results table has six dimension tabs, each sortable by clicks, impressions, CTR, or position, with page sizes of 10 / 25 / 50.

  • Queries — the search terms surfacing your site
  • Pages — per-URL performance
  • Countries — performance by geography
  • Devices — desktop / mobile / tablet split
  • Search Appearance — rich-result and feature breakdown
  • Days — the date-dimension time series

Data is 2–3 days behind Google

Google’s Search Analytics data is not real-time. Every TruIntel query ends its range at today minus 3 days, matching how fresh Google’s own data actually is. If the latest days look empty, that is expected.

Sync & Data Mechanics

Separate from the live dashboard, the daily keyword sync writes ranking history that other SEO surfaces read. Understanding its windows explains the position-change deltas you see elsewhere.

  • First sync (never synced before) pulls the last 90 days; every subsequent daily sync re-pulls the trailing 28 days.
  • Rows are fetched on the query and page dimensions, paginated up to 25,000 rows per page.
  • Results store one KeywordRanking row per query, aggregated across pages: the best page (lowest position) wins, while clicks and impressions are summed. Queries longer than 500 characters are skipped.
  • Position change is computed against the most recent prior GSC record that is at least 7 days old, so the overlapping 28-day windows still yield a meaningful delta.
  • Clicks, impressions, CTR, and average position come directly from Google — there is no DataForSEO or other third-party volume enrichment (a previously stored search_volume is simply carried over if it already exists).
  • Every sync writes an SEOReport record and is guarded by a Redis lock so global and per-brand syncs never overlap.
  • All GSC calls use a 3-try retry ladder with exponential backoff that respects Retry-After on 429s and retries 5xx / timeout errors.

DataForSEO enrichment was removed

Earlier docs and some UI copy mention "search volume enrichment via DataForSEO" — that path no longer exists. GSC metrics are served directly from Google. Treat any DataForSEO-volume claim about GSC as stale.

Connection status

The status surface exposes whether the integration is connected and active, whether a sync is currently running, the connected property URL, last sync time and status, any sync error, and the available data date range. The UI polls this every 10 seconds while a sync is in progress.

Indexation Monitoring (Pro+)

Indexation Monitoring is a Pro and Enterprise feature that rides the exact same read-only OAuth scope — no re-consent needed. It calls Google’s URL Inspection API to report the real index status of your pages and alerts you when pages fall out of the index.

  • Classifies each page as indexed, not_indexed, excluded, error, or neutral, using Google’s own inspection verdict.
  • The URL list is built on demand by a site crawler (sitemap + links); never-checked and least-recently-checked URLs are prioritized so the long tail rotates daily.
  • Google caps URL Inspection at ~2,000 inspections/day and 600/min per property. TruIntel enforces a per-(brand, property) daily budget of min(plan limit, 2,000) and paces requests at roughly 6/sec.
  • When a previously indexed page becomes not_indexed or excluded, a deindexation alert is raised.
  • The daily indexation check runs at 05:30 IST, staggered just after the 05:00 keyword sync.

Account-wide token

Because the Google token is account-wide, Indexation can analyze any verified property in your connected account — even though each brand stores only one selected property for the Search Performance dashboard.

Schedule

All GSC-related background jobs run on the Asia/Kolkata (IST) timezone. Times below are genuine IST.

TaskTime (IST)Applies to
Daily keyword-ranking sync (all active integrations)05:00 dailyAll paid plans with GSC connected
Daily indexation check (URL Inspection)05:30 dailyPro+ with GSC connected
Immediate per-brand syncOn connectStarter and up

Routes & Endpoints

Where GSC appears in the app, and the backend endpoints that power it.

Search Performance

/seo/keywords

The live GSC clicks / impressions / CTR / position dashboard with 6 tabs, date presets, search-type switch, filters, and metric toggles.

Settings → Integrations

/settings

Connect, view status, or disconnect GSC via the connection card and shared connect modal.

MethodEndpointPurpose
GET/integrations/gsc/authorizeBuild the Google OAuth consent URL
GET/integrations/gsc/callbackOAuth callback (no auth; returns popup-close HTML)
GET/integrations/gsc/propertiesList verified GSC properties (Google sites.list)
POST/integrations/gsc/connectLink a chosen property to a brand
DELETE/integrations/gsc/{brand_id}/disconnectDelete the integration (hard delete)
GET/integrations/gsc/{brand_id}/statusConnection status + sync freshness
GET/seo/{brand_id}/gsc/summaryAggregate totals (clicks / impressions / CTR / position)
GET/seo/{brand_id}/gsc/chartTime series on the date dimension
GET/seo/{brand_id}/gsc/tableDimension table, paginated

One property per brand

Each brand stores exactly one GSC property for its dashboard and daily sync. To track a different property, reconnect and select it (or let auto-resolution pick it).

AI Insights & Tasks

Overview

AI Insights is the brain that turns a brand's week of raw visibility, SEO, traffic and lead data into a ranked set of strategic Findings and concrete Tasks. Each brand gets a weekly Insight Report produced by a 4-step Gemini pipeline, then a closed-loop layer measures which completed tasks actually moved the needle and feeds that memory back into the next report.

Findings

Data-backed strategic observations with a priority, category, 0-100 impact score and supporting evidence — ranked so you focus on what matters most.

Tasks

Concrete actions derived from findings, split into Owned (your content/SEO) vs Earned (PR/UGC/outreach), each with category, effort, due date and impact tracking.

Outcome Attribution

A monthly closed loop that measures which completed tasks moved visibility and records a "what worked" memory per brand.

Opportunity Agent

Fuses AEO gaps with keyword/SERP gaps into ranked, evidence-backed content opportunities that feed the content calendar.

Powered by gemini-3.1-flash-lite

The full insights pipeline runs on gemini-3.1-flash-lite. If the primary Gemini key fails, generation falls over to the multi-provider llm_json chain (Anthropic, then a Gemini pool, OpenAI and OpenRouter) so a report still gets produced.

Where to find it

Insights live under the Insights nav section: /insights (Key Findings), /insights/:findingId (Finding detail) and /tasks (Task board). The closed-loop surfaces — Opportunities, Calendar and Accountability — live in Content Studio.

How the Pipeline Works

Every report is produced by a 4-step sequential Gemini pipeline where each step feeds the next. The pipeline first aggregates a rich week-over-week snapshot of the brand, then runs trend analysis, competitor analysis, strategy (findings) and task generation — finishing with a deterministic grounding pass that drops or hides anything the live data contradicts.

1

Step 1 — Trend Analysis

Reads the brand's week of data and writes a free-form narrative on what is changing: visibility score movement, platform shifts, emerging queries and sentiment changes.

2

Step 2 — Competitor Analysis

Examines what competitors are doing differently — which platforms mention them more, where they gain ground, and the source domains they win that you do not.

3

Step 3 — Strategy (Findings)

Emits a JSON array of 5-10 findings with priority, category, impact score and evidence. Runs at temperature 0.1 with structured JSON output for reliability.

4

Step 4 — Task Generation

Converts findings into a JSON array of 5-15 concrete tasks with category, effort, due date and target platform. Each task is heuristically linked to its best-match finding.

After the four steps, two final passes run before the report is marked complete:

  • Grounding pass (no LLM): deterministically DROPS findings/tasks that the live data hard-contradicts (e.g. a "robots.txt blocks AI crawlers" claim when the live crawler check says all bots are allowed) and FLAGS unverifiable ones (grounded=false), which are hidden from the default view.
  • Task-to-finding linking + query resolution: each task is matched to at most one source finding, and its affected queries are resolved to canonical tracked-query text so the attribution loop can join them later.

Anti-fabrication by design

A standing grounding/anti-fabrication system instruction is injected on every step, reinforced by per-step in-prompt grounding rules and a today's-date context so analysis stays current. The deterministic grounding pass is the final backstop — findings the data cannot support never reach you.

What the Pipeline Reads

The differentiator is the breadth of input. Before any LLM call, the aggregator builds a week-over-week snapshot (current period vs the prior period) from full visibility checks plus every other connected data channel. The richer the input, the sharper and more grounded the findings.

AEO Visibility

Overall + per-platform + per-query results from full visibility checks, with week-over-week deltas, query intent distribution and high-value queries.

Competitors

Per-competitor mention data and how it changed this week, driving competitive findings and earned-media tasks.

Sources (Earned vs Owned)

Citation source domains split into brand-citing vs competitor-only — the split that powers earned-media task targeting.

Brand Attributes

The attributes AI associates with the brand, including which were newly gained or lost this week.

SEO Detail

Domain Authority, keywords, backlinks, on-page issues with specific URLs, PageSpeed and Core Web Vitals.

Traffic Classification

Human / agent / bot split plus the AI-crawler breakdown from the traffic engine.

Lead Verification

Verified / review / rejected counts and AI-referred lead share.

Live AI-Crawler Access

A live robots.txt evaluation per AI vendor (the same source as the AI Crawlability page) so crawler findings reflect reality.

Period windows

Scheduled weekly runs analyse the previous calendar week (Mon-Sun). A manual generation uses the window from the previous Monday through today, so today's fresh check is included. Brand-new brands with no prior data get a "baseline" framing instead of an error.

Findings & Evidence

Each report contains roughly 5-10 findings (the grounding pass may drop or hide some, so a report can show fewer). Findings are ordered by impact score, descending, so the most consequential observations sit at the top.

Every finding carries the following fields:

FieldValues / RangeNotes
Title & DescriptionFree textA clear observation plus its explanation.
Prioritycritical / high / medium / lowDrives ordering and visual emphasis.
Categoryperformance / competitive / content / technicalThe four UI filter categories.
Impact Score0-100 (float)Rendered to a whole number with score color. >80 ~ critical, >60 ~ high.
Finding Typevisibility_drop, platform_gap, competitor_threat, content_opportunity, citation_gap, and moreA finer descriptor than Category.
EvidenceJSON + metric name/value/changeThe specific data points backing the finding.
Affected scopequeries / platforms / competitorsWhich queries, platforms and rivals the finding touches.
Groundedtrue / false (+ notes)Grounding verdict; flagged (false) findings are hidden by default.

Category vs Finding Type

Category is the four-value enum (performance, competitive, content, technical) used by the UI filters. Finding Type is a separate, finer descriptor (visibility_drop, platform_gap, citation_gap, seo_issue, keyword_gap, lead_quality_insight, and more). They are different fields — do not confuse them.

The Insights page (/insights) shows a stats row (Visibility Score and change, Findings count, Critical/High, Tasks Generated, Mentions) above a Key Findings table with columns for Finding, Priority, Category, Impact, Platforms, Tasks count and Date. Search and Priority/Category filters narrow the list, and a week selector lets you browse report history. By default the page scopes to the latest completed report and shows grounded findings only. Clicking a row opens /insights/:findingId for the full evidence breakdown.

Tasks & Lifecycle

Tasks are the concrete actions derived from findings. Each report generates 5-15 tasks, and every task maps to at most one source finding via a heuristic match (it may be unlinked). A task is either Owned or Earned — a distinction that defines how you act on it.

Owned tasks

Actions on assets you control — your own content, SEO and technical fixes.

Earned tasks

Actions targeting sources AI engines already cite — PR, UGC and outreach to win earned media.

Tasks move through a simple three-state lifecycle:

StatusMeaningTransition rules
todoNew task awaiting action (default)Review and start work.
doneCompletedStamps completed_at and optional completion notes; eligible for impact tracking.
dismissedNot applicable / not actionableRequires a dismissal reason. Reverting to todo clears completion and dismissal fields.

Beyond status, each task exposes a rich set of fields you can use to plan and prioritise:

  • Category — content / seo / pr / technical / social
  • Priority — critical / high / medium / low
  • Content type — listicle, how-to guide, article, comparison, category page, profile, UGC (reddit/youtube/quora/forum), outreach, technical SEO
  • Targeting — target source and target platform (chatgpt / claude / gemini / perplexity / google_ai_overview / all)
  • Planning — estimated effort hours, suggested due date, success metrics, expected impact
  • Impact tracking — actual_impact and impact_measured_at, auto-stamped by attribution (prefixed "Auto:") or set manually on done tasks

Turn tasks into drafts

Any task with a content type can be auto-generated into a draft via the content tooling — the Tasks page surfaces "N tasks can be auto-generated" so you can go from insight to draft in one step.

The Task Board

The Tasks page (/tasks) offers two ways to work, plus summary analytics and quick filters. By default it scopes to the latest completed report, ordered by priority then date.

Kanban Board (default)

Three columns — To Do, Done, Dismissed — with drag-and-drop to change a task's status.

Split View

Two columns side by side — Owned Content vs Earned Media — so you can balance both motions at a glance.

Three independent filter axes plus search let you slice the board:

Filter axisValues
Statustodo / done / dismissed
Type (task group)earned / owned
Categorycontent / seo / pr / technical / social

A stat row across the top (Total, To Do, Urgent = critical+high, Done, Dismissed) doubles as a click-to-filter control. Summary cards show a status donut, priority bars and a progress card with completion rate, earned/owned counts and per-category breakdowns. Completing a task opens a modal for notes and optional impact; dismissing requires a reason. The completion rate is computed as done divided by (total minus dismissed).

Outcome Attribution — What Worked

Outcome Attribution is the closed loop that proves which completed tasks actually moved visibility. It runs period-over-period — primarily monthly, folded into the monthly brand-report task — rather than as a strict next-week check.

For each task completed in the period, attribution joins the task's affected queries to how those queries actually moved. A query only counts as a creditable win when one of these is true:

  • It flipped from not-mentioned to mentioned ("query won")
  • Its rank position improved
  • It gained a citation

Conservative crediting

Attribution is deliberately strict: it requires a genuine prior baseline (a brand-new query is not a "win"), enforces a reverse-causality guard (the movement must post-date the task's completion), and scopes by platform (a ChatGPT-targeted task cannot claim a Gemini-only win). Credited tasks get an "Auto:" actual_impact stamp, but a human-written note is never overwritten.

Each period writes a BrandPerformanceSnapshot (upserted per brand and period) capturing tasks completed/total, overall score and change, queries won, net position change, citations gained, attributed outcomes and a what_worked map (category to measured-impact weight). That what_worked memory then biases both the next report's strategy and task prompts and the Opportunity Agent's scoring — closing the loop. It surfaces at Content Studio's Accountability page (/content-studio/accountability) and via the performance-history and accountability endpoints.

Opportunity Agent & Content Opportunities

The Opportunity Agent turns gaps into ranked, evidence-backed content opportunities — the rows that populate the content calendar (there is no separate calendar table). It fuses three signals into a single opportunity_value score from 0-100.

Opportunity scoring

0.55
0.45
+/-0.20
AEO gap score (0.55)
Keyword/SERP gap score (0.45)
What-worked bias (+/-0.20)
  • AEO query gaps — tracked queries with one or fewer platform mentions
  • Keyword/backlink gaps — DataForSEO Labs gaps vs top-3 competitors (budget-guarded)
  • What-worked bias — a +/-0.20 nudge from the brand's proven-impact categories

Evidence-gated (anti-slop)

Every opportunity carries an evidence object — no evidence, no opportunity. Each row also has opportunity_value (0-100), sub-scores (aeo_gap_score, keyword_gap_score), search volume, difficulty, a source (aeo_gap / keyword_gap / serp_gap / combined) and a lifecycle status (suggested, scheduled, in_progress, published, dismissed). Off-topic and competitor-branded keywords are dropped, and duplicates are merged by canonical key.

DataForSEO budget guard

Each keyword-gap fan-out is bounded by the per-brand SEO/DataForSEO budget (default $5/brand/month). On exhaustion the agent degrades gracefully to AEO-only opportunities.

Opportunities refresh weekly for paid brands (Sundays 09:00 IST) and surface in Content Studio at /content-studio/opportunities and the publishing /content-studio/calendar. Although these pages sit under the Insights nav section, they are Content Studio surfaces of the same closed loop.

Generation, Schedules & States

Reports are generated automatically each week and can also be triggered manually. Manual generation runs asynchronously: the report row is pre-created in a "generating" state so the UI can poll for completion every few seconds.

JobSchedule (IST)Scope
Weekly insight generationMonday 06:00Paid brands with a full visibility check this week
Monthly outcome attribution2nd of month 06:00Writes the BrandPerformanceSnapshot / what_worked
Opportunity refreshSunday 09:00Paid brands (Opportunity Agent)
Cleanup old reportsQuarterly, 1st 06:00Deletes reports older than 90 days

All times are IST

Celery runs on the Asia/Kolkata timezone, so "Monday 06:00" is genuinely 6:00 AM IST. (A stale code docstring claiming 6:00 AM UTC is wrong.)

The Insights and Tasks pages handle every report state explicitly:

StateWhat you see
GeneratingA live loader; the page polls every 3 seconds until the report completes.
CompletedThe full Key Findings table and task board.
FailedAn explicit error with a retry action (the Celery task also auto-retries).
First weekA baseline framing for brands with no prior period of data.
EmptyA "Generate First Report" call to action.

How long does it take?

Generation makes four Gemini calls (each capped at 90–120s; the competitor step at 90s, the others at 120s) under a ~10-minute task limit, so a report usually completes in under a couple of minutes.

Plan Gating & Access

AI Insights is effectively a Starter-and-above feature. The Insights and Tasks pages are gated to Starter+, and generating a report requires a paid plan. The AI models themselves are global, not plan-tiered.

CapabilityRequired plan
View /insights and /tasks pagesStarter+ (Free sees an upgrade gate)
Generate / regenerate a reportPaid only (Starter+)
Weekly auto-generationPaid brands only
Read reports/findings/tasks via APIAny valid plan with an active org
Opportunity Agent keyword-gap fan-outBounded by per-brand SEO budget ($5/brand/mo default)

Free plan

On the Free plan the Insights and Tasks pages show an upgrade gate, and weekly auto-generation does not run. Upgrade to Starter or above to unlock the full insights loop.

Routes & Endpoints

The product surfaces for AI Insights and Tasks, plus the Content Studio surfaces of the closed loop:

Insights

/insights

Stats row + Key Findings table with search, filters and a week selector.

Finding Detail

/insights/:findingId

Full evidence and metrics for a single finding.

Tasks

/tasks

Kanban / Split View task board with status, type and category filters.

Opportunities

/content-studio/opportunities

Ranked, evidence-backed content opportunities from the Opportunity Agent.

Calendar

/content-studio/calendar

The publishing calendar built on scheduled content opportunities.

Accountability

/content-studio/accountability

Monthly performance snapshot and what-worked history.

Key backend endpoints under /api/v2/insights:

  • GET /{brand_id}/reports, /reports/latest, /reports/{report_id} — list and fetch reports
  • POST /{brand_id}/generate (async by default), POST /{brand_id}/generate-tasks — generate a report or regenerate tasks
  • GET /{brand_id}/findings, /findings/{finding_id} — read findings (latest report + grounded-only by default)
  • GET /{brand_id}/tasks, /tasks/summary, /tasks/{task_id} — read tasks and summary counts
  • PATCH /{brand_id}/tasks/{task_id}/status, /tasks/{task_id}/impact — change status or set impact
  • GET /{brand_id}/performance-history, /accountability?period=YYYY-MM — the closed-loop data

Legacy v1 insights

An older /api/v1/insights rule-based engine still exists in the backend but is not used by the live product UI — only the v2 pipeline described here is surfaced.

Reports

Overview

Brand Reports are pre-computed, point-in-time snapshots that consolidate your AI Visibility (AEO), SEO, traffic, and lead data into a single executive-ready document. Each report bundles headline metrics, an LLM-written executive summary, and linked findings and tasks, so a stakeholder can understand a brand's standing without opening five different dashboards.

Reports are computed once and stored as a record — they do not re-query live data when you open them. This makes them fast to load and gives you a stable historical archive you can compare period over period. You can browse them at /reports and open any single report at /reports/:reportId.

Consolidated snapshot

AEO, SEO, traffic, and lead data captured together for one period, plus denormalized headline metrics (overall score, score change, recognition rate, total mentions).

AI executive summary

A short, data-grounded narrative written by gemini-3.1-flash-lite, with a deterministic fallback so a summary always exists even if the model is unavailable.

Findings and tasks

Each report links to overlapping AI insights and surfaces a task summary, turning the snapshot into an actionable to-do list.

PDF export

Any completed report can be exported to a clean, multi-page A4 PDF for sharing with clients or leadership.

Reports are a paid feature

The Free plan does not receive any reports — every scheduler skips Free brands, and onboarding and instant reports are paid-gated. Viewing reports requires an active subscription; manually generating one requires Starter or above.

Report Types

TruIntel produces three distinct report types. All three share the same underlying data model and detail layout — they differ in the window they cover, how they are triggered, and how their executive summary is framed.

TypePeriod coveredHow it is createdNotes
WeeklyPrevious calendar Mon-Sun (scheduled) or a single "today" (instant)Scheduled Monday 10:00 IST, instant on every full AEO check, or manualThe most common type; cadence rows show in the list, instant single-day rows are hidden
MonthlyThe full previous calendar monthScheduled on the 2nd at 06:00 IST, or manualAdds month-over-month deltas and an accountability narrative; also emails org members
OnboardingA single day (the day onboarding finished)Auto-generated once, when onboarding completes and the first AEO + SEO checks are doneExactly one per brand, ever; appears in the Reports list as a baseline

The onboarding report is your baseline

Generated automatically the first time a brand finishes onboarding, the onboarding report establishes a "day one" baseline with no week-over-week comparison. Every brand gets exactly one, and it cannot be regenerated.

Brand Reports are separate from AI Insight Reports. When an insight report overlaps a brand report's window, the brand report optionally links to it so its findings appear inside the report detail page.

What Is Inside a Report

The report detail page renders its data as a sequence of section cards (around 13 — the three brand-narrative sections, How AI Describes Your Brand / New This Period / Earned Media Opportunities, share a single three-card row), opening with a hero that shows the overall visibility score, recognition rate, total mentions, the five AI platforms, and a button to jump to the linked insight report. Underneath, the sections walk through every dimension of the brand's performance.

  1. Executive Summary — the AI-written narrative for the period
  2. AI Visibility Overview — a stat row of the headline AEO metrics
  3. Platform Breakdown — per-platform performance across ChatGPT, Claude, Gemini, Perplexity, and Google AI Overview
  4. Query Performance — how individual tracked queries surfaced the brand
  5. Competitor Landscape — a comparison table against tracked competitors
  6. Brand Perception — sentiment distribution for the period
  7. How AI Describes Your Brand — extracted brand attributes
  8. New This Period — what changed since the last snapshot
  9. Earned Media Opportunities — citation and outreach openings
  10. Citation Sources — the domains AI engines cited
  11. SEO Health — domain authority, PageSpeed, backlinks, keywords, and crawl issues
  12. Top Keywords — the brand's strongest keyword positions
  13. Traffic Intelligence — a visitor-classification donut plus agent breakdown
  14. Lead Verification — verified, review, and rejected lead counts
  15. Findings & Actions — the task summary plus linked findings

Under the hood, a report stores four JSONB snapshots — AEO, SEO, traffic, and lead — built by reusing the same aggregation used elsewhere, so generating a report does not re-query the source tables. The SEO, traffic, and lead snapshots are null when a brand has no data for them, which is common on lower tiers where that underlying data is feature-gated. The AEO snapshot is the richest, carrying current metrics, changes, platforms, competitors, sources, attributes, queries by intent, query highlights, sentiment distribution, totals, a task summary, and (monthly only) accountability data.

Lower tiers may see partial reports

A report always includes the AEO snapshot. SEO, traffic, and lead sections appear only when that data exists — brands on plans that do not unlock those features will see those cards omitted rather than empty.

The AI Executive Summary

Every report opens with a short executive summary written by gemini-3.1-flash-lite at a low temperature (0.3) for consistency. The model receives the aggregated metrics for the period and returns a tight, data-grounded narrative — never marketing fluff.

Report typeSummary styleLength budget
WeeklyA 3-4 sentence data summary of the week300 tokens
MonthlyA two-part accountability narrative driven by the attribution payload (what was promised vs. what happened)400 tokens
OnboardingA welcoming "here is your baseline" framing with no week-over-week comparison300 tokens

A summary always exists

Each of the three summary prompts has a deterministic fallback. If the model is unavailable or fails, TruIntel writes the narrative from the raw numbers so a report is never published without a summary.

Generation Schedules

Reports are generated automatically on the platform's Celery beat schedule. All times are genuine India Standard Time (Asia/Kolkata) — the scheduler runs in IST, so no timezone conversion is needed.

JobWhen (IST)Scope
Weekly brand reportMonday 10:00All paid brands with a visibility check in the last 14 days
Monthly brand report2nd of month 06:00All paid brands with a visibility check in the last 14 days
Weekly visibility emailMonday 08:00Org members of active paid brands (built from VisibilityChecks, not a report)
Instant "State of Your Brand"On every full AEO checkAuto-dispatched ~20s after a full visibility check completes
Onboarding reportAt onboarding completionOnce per brand, after first AEO + SEO checks finish

The weekly email fires before the weekly report

The Monday 08:00 IST visibility email is built from your two most recent VisibilityChecks, not from a brand report — and it runs two hours before the 10:00 IST brand-report generation. The two are independent jobs. The weekly brand-report task itself sends no email.

Both scheduled generators only process paid brands that have a visibility check within the past 14 days. The monthly job does extra work: it also regenerates content opportunities and fans out a monthly accountability email to every org member.

Instant and Onboarding Reports

Beyond the scheduled cadence, two automatic mechanisms keep a fresh report available without you asking.

Instant "State of Your Brand"

Every time a full visibility check completes, TruIntel auto-dispatches a weekly-type report scoped to a single day (today), about 20 seconds later. It is idempotent per day, so repeated checks do not pile up duplicate rows. This instant report is hidden from the historical list — it powers the "current state" view rather than the archive. The frontend polls for it every 4 seconds while it builds.

Onboarding report coordinator

When onboarding finishes, TruIntel creates a placeholder onboarding report and dispatches a coordinator task. Because AEO and SEO checks finish at different times, the coordinator polls readiness and re-dispatches itself every 45 seconds until both are ready, then generates the report.

1

Placeholder created

A paid-gated onboarding report row is created for today the moment onboarding completes.

2

Coordinator dispatched

A coordinator task starts after a 60-second countdown and begins polling readiness.

3

Readiness polling

AEO is ready once a full check completes; SEO is ready when a Redis flag or any SEO report exists. The coordinator re-dispatches itself every 45 seconds.

4

Generate or force-finalize

When both are ready it generates. After up to 50 attempts (~37 minutes) it force-generates or marks the report failed so the loading state always resolves.

Two different poll intervals

The 4-second interval is the frontend polling a generating report so the UI updates. The 45-second interval is the backend onboarding coordinator polling whether AEO and SEO data are ready. They are unrelated.

Weekly Email Report

Separately from the in-app brand reports, TruIntel emails a weekly visibility digest every Monday at 08:00 IST to each org member of an active paid brand. It is built directly from your two most recent VisibilityChecks — not from a stored brand report — so it can go out before the brand report is generated.

  • A circular visibility-score gauge with the week-over-week delta
  • A Week-over-Week Movement table
  • Top Insights for the week (up to 3)
  • A list of open tasks (top 5)
  • A "Full Report" link back to /overview

Delivery via Resend

Weekly emails are sent through Resend. If no Resend API key is configured the job skips gracefully rather than failing. The monthly accountability email is a separate job that fans out to every org member.

There is no email-frequency setting

Older docs pointed to "Settings -> Notifications" to configure email frequency. That section is an in-app alert feed — it does not control report-email cadence. The weekly/monthly email schedule is fixed.

Exporting to PDF

Any completed report can be exported as a clean, multi-page A4 PDF for sharing with clients or leadership. The exporter uses your browser's native print pipeline rather than a screenshot library, so text stays crisp and selectable.

1

Open a completed report

Navigate to /reports and open a report whose status is completed — only completed reports are downloadable.

2

Click the download icon

This opens the report with a ?download=1 flag, which prepares the print-optimized layout.

3

Save as PDF

TruIntel injects print CSS (A4 page size, a cover page, a repeating header, and page-break control) and triggers the browser print dialog automatically. Choose "Save as PDF".

Native print, not a screenshot

Export is powered by the browser print dialog (window.print) with injected @media print styles — there is no html2canvas or jsPDF involved, so tables and text export as real, selectable content.

Reports Page and States

The Reports area lives under the REPORT group in the sidebar. The list page at /reports gives you a filterable archive, and each report opens at /reports/:reportId.

List page (/reports)

  • Tabs to filter by All / Onboarding / Weekly / Monthly
  • A table paginated at 20 rows per page
  • Type badges: weekly (info), monthly (default), onboarding (success)
  • An empty state that explains the automatic onboarding report and the weekly/monthly cadence
  • Instant single-day weekly rows are hidden; onboarding rows do appear

Detail page (/reports/:reportId)

  • A hero with the score, recognition rate, mentions, "5 AI platforms", and a linked-insight button
  • The ~13 section cards described above
  • A generating guard with a spinner (e.g. "Building your onboarding report") while a report is still computing
  • A failed state with a "Retry generation" action
  • A developer-only Raw JSON view

Live polling while generating

The list, the detail page, and the instant report all poll every 4 seconds while a report is in the generating state, so the UI flips to the finished report automatically without a manual refresh.

API Reference

Report endpoints live under the /api/v1/reports prefix. The router requires an active subscription for all reads; manual generation additionally requires a paid plan (Starter or above).

List reports

GET /api/v1/reports/{brand_id}

Paginated list (limit 1-50, default 20) with an optional type filter.

Latest report

GET /api/v1/reports/{brand_id}/latest

The most recent completed report for the brand.

Instant report

GET /api/v1/reports/{brand_id}/instant

Today's instant report in any status (generating, completed, or failed).

Kick instant report

POST /api/v1/reports/{brand_id}/instant

Self-kicks generation of the instant "State of Your Brand" report.

Single report

GET /api/v1/reports/{brand_id}/{report_id}

The full record for one report, including all four snapshots.

Generate report

POST /api/v1/reports/{brand_id}/generate

Manually generate a report. Body { report_type } accepts weekly, monthly, or onboarding. Requires a paid plan; returns a task_id.

Idempotent per window

A unique constraint on (brand, type, period_start, period_end) means re-running generation for the same window updates the existing report rather than creating a duplicate.

Plan Availability

Reports are entirely a paid capability. The table below summarizes what each plan can do with reports.

CapabilityFreeStarterLitePro / Enterprise
Scheduled weekly/monthly reportsNoYesYesYes
Onboarding + instant reportsNoYesYesYes
View reportsNoYesYesYes
Manually generate a reportNoYesYesYes
PDF exportNoYesYesYes
Weekly + monthly emailNoYesYesYes

Free plan receives no reports

Every report scheduler filters out Free brands, the onboarding and instant flows are paid-gated, and the email loops exclude Free. Upgrade to Starter or above to unlock reports.

There is no further per-tier gating on reports themselves — a Starter report and a Pro report are structurally identical. However, lower tiers may see null SEO, traffic, or lead sections because that underlying data is feature-gated elsewhere in the product.

Content Studio & Opportunities

New

Overview

Content Studio is TruIntel's in-app editorial production hub. It turns your measurement signals — AI-answer gaps, keyword and backlink gaps, and SERP gaps — into a ranked plan of what to write, a research-grounded staged draft flow, a publishing calendar that auto-publishes real articles to your website, a unified drafts library, and a monthly accountability view that proves the work moved the needle.

It lives under the Insights section of the left navigation, and every page sits under the /content-studio/* route family. Content Studio is the v2.1 successor to the older standalone "Plus" express generator: the frontend feature key and plan gate are still labelled "plus" / "TruIntel Plus" internally, but the user-facing product is Content Studio.

Opportunities

A ranked, evidence-backed list of what to write next, fused from AEO mention gaps, keyword/backlink gaps, and SERP gaps and scored 0-100.

Staged Create

A resumable wizard — Brief, Keywords, Outline, Draft, CMS — that grounds every decision in real research before spending a credit.

Publishing Calendar

A month grid that schedules real CMS articles and auto-publishes them to your connected website at the chosen time.

Library

One unified view of every draft across both the Plus generation store and the CMS, with source badges and per-row actions.

Accountability

A monthly value-proof surface: tasks completed, queries won, rank movement, citations gained, and per-task attributed outcomes.

Paid plans only (Starter and up)

Every Content Studio page is gated to paid plans. The backend require_paid_plan dependency returns 403 PAID_PLAN_REQUIRED for Free or no-plan organizations, and the frontend wraps each route in a PlanGatedRoute with a Starter minimum. Free accounts do not see Content Studio.

Opportunities

/content-studio/opportunities

Front door — ranked table of content opportunities (also where /content-studio bare redirects).

Staged Create

/content-studio/create

The Brief to CMS wizard. Always opportunity-seeded — entered from an opportunity's Create button, not a top-level nav item.

Resume Create

/content-studio/create/:briefId

Resume an in-progress brief by its id.

Calendar

/content-studio/calendar

Publishing calendar over real CMS articles.

Library

/content-studio/library

Unified drafts across Plus generations and CMS content.

Accountability

/content-studio/accountability

Monthly value-proof and looking-forward opportunities.

Opportunities

The Opportunities page is the front door of Content Studio. It presents a ranked table of content ideas, each one carrying the evidence behind it — search volume, difficulty, the target AI query, ranking competitors, and the specific gap that was found. Rows are sorted by opportunity value (0-100) descending so the highest-impact ideas surface first.

Three signals fused into one ranked plan

Each opportunity is fused from up to three independent gap signals. A candidate that appears in more than one signal is merged into a single combined opportunity rather than duplicated.

AEO query gaps

Active tracked queries where your brand has zero or low mentions across AI platforms. Sub-score scales with how few mentions you have and the query's business value (1-5).

Keyword / backlink gaps

Keywords your top-mentioned competitors rank for but you do not (missing / weak / untapped), pulled from DataForSEO Labs and filtered for relevance.

SERP gaps

Search-result opportunities folded into the same ranking, contributing evidence such as competing pages and median content depth.

Combined opportunity value (when both AEO and keyword signals are present)

0.55
0.45
AEO gap (0.55)
Keyword gap (0.45)

When only one signal is present, that sub-score is used directly. The final value is then biased up to plus or minus 20% by the latest performance snapshot's "what worked" weighting — keyword-gap ideas lean to the "seo" category, everything else to "content" — so the plan adapts to what has actually been moving your numbers.

Anti-slop by construction

A candidate with no evidence metric — no query, keyword, competitor, search volume, or SERP data — is dropped before it is ever produced. Every opportunity you see is backed by a verifiable signal, and re-running the generator dedupes against your existing non-dismissed ideas so the list never piles up duplicates.

Status lifecycle

StatusMeaning
suggestedFreshly generated and ranked, awaiting your decision.
scheduledYou set a target date for it (sets scheduled_date).
in_progressA brief or draft is being built from it.
publishedThe resulting article went live.
dismissedYou discarded it; dismissed ideas are excluded from dedup so they stay gone.

Page actions and states

  • Per-row Create — opens the staged Create wizard seeded with that opportunity (?opportunity_id=).
  • Per-row Schedule — a date picker that sets scheduled_date and flips status to scheduled. This action is hidden until a CMS domain is connected.
  • Header Refresh — re-derives opportunities on demand.
  • Filters — server-side status filter (suggested / scheduled / in_progress / published / dismissed) plus a client-side title search.
  • Summary StatRow — total count, top value, high-impact count (value 75 or higher), and scheduled count.
  • States — no-brand, loading skeleton, error with Retry, empty (a setup checklist prompting you to run your first scan when none exists, otherwise a Refresh CTA), and the ranked table.

How Opportunities Appear

You rarely have to ask for opportunities — TruIntel generates them for you. There are four paths that populate the list, ranging from a one-time back-fill when you onboard to a weekly scheduled refresh.

1

Auto back-fill at onboarding

After your first visibility check completes, a one-time task back-fills Opportunities (alongside Off-Page Outreach and Directory) — but only when the table is still empty for the brand. It runs roughly 45 seconds after source-gap data settles, on paid plans only, behind a per-brand lock.

2

Weekly refresh

Every Sunday at 09:00 IST, a scheduled task regenerates and commits opportunities for every active paid brand, spaced out to stay within budget.

3

Manual refresh

The header Refresh button (POST /content/opportunities/refresh) re-derives and returns a fresh list any time you want.

4

Report-driven

Opportunity generation also runs as part of brand-report runs, tagging each idea with the report it came from for provenance.

Kill switch

The onboarding auto back-fill is governed by the GROWTH_AUTOGEN_ENABLED flag (default on). It skips Free / no-plan organizations entirely and only fills tables that are empty, so it never overwrites work you have already started.

What powers the keyword signal

The keyword/backlink gap signal diffs your domain against your top three most-mentioned active competitors that have a domain, using DataForSEO Labs. It requires a connected domain, at least one qualifying competitor, and an available per-brand SEO budget.

Graceful degradation

Each per-competitor lookup is budget-gated before the call and records real spend after. If the budget is exhausted, or you have no domain or no competitor with a domain, the keyword signal simply returns nothing and the plan degrades to AEO-only — it never errors out.

Staged Create Wizard

Staged Create is a resumable five-step wizard that grounds every editorial decision in real research before you spend a single credit. You always enter it from an opportunity (or with an explicit topic and seed keyword); it is intentionally not a standalone nav item. Every checkpoint surfaces the evidence behind its recommendation.

1

Brief

TruIntel assembles a research brief from the seed: keyword research, SERP-derived word count, a merged table of contents, and People-Also-Ask questions. This step is free.

2

Keywords

Review the primary keyword and the secondary cluster (each tagged with its source). Confirm or edit.

3

Outline

Review the LLM-merged table of contents drawn from the top-ranking pages and PAA. Confirm or adjust.

4

Draft

Generate the full article. This charges credits (standard 1, premium 3).

5

CMS

Send the finished draft to your CMS, ready to schedule and publish.

Express mode and resuming

Express mode skips the Keywords and Outline checkpoints and takes the built brief straight to Draft. Briefs are persisted and resumable — return to any in-progress brief via /content-studio/create/:briefId, and a fresh build can be seeded by an opportunity_id or by an explicit topic plus seed keyword.

What goes into a brief (free)

Building a brief is free — the credit charge only happens at the Draft step. Before any paid call, a budget gate runs; if the per-brand SEO budget is exhausted the request returns 429 PLAN_LIMIT_REACHED. The research that goes into a brief:

  • Keyword research — DataForSEO Labs keyword suggestions (up to 50) plus search volume for the seed keyword.
  • GSC demand — your top 25 Google Search Console query rows over a 90-day lookback, where impressions represent real demand (degrades to DataForSEO-only when GSC is not connected).
  • Secondary cluster — Labs suggestions ranked by volume with GSC terms folded in, deduped by token-set, capped at 8 keywords, each evidence-tagged with its source (dataforseo or gsc).
  • SERP analysis — one paid advanced live-SERP call (depth 10) returning organic URLs and PAA; the top pages are fetched and analyzed to compute an outlier-filtered median word count (with a 120-word floor).
  • Merged outline — an LLM-merged table of contents (up to 14 sections) built from the analyzed pages, with a deterministic frequency-merge fallback if the LLM is unavailable.
  • H1 synthesis — a small utility-LLM call proposes the H1 (opportunity titles are used as-is).

Never raises

The SERP analysis is designed to never fail the brief — if a page fetch or LLM call fails, it degrades to a partial result rather than blocking you. Every keyword in the brief carries an evidence object, including bare keywords you type yourself (wrapped with a "user" source).

Editing a brief (free)

You can patch any field on a brief without charge — topic, H1, primary and secondary keywords, target location, audience, tone, word count, table of contents, PAA, and status. Briefs move through their own status lifecycle: draft, keywords_confirmed, toc_confirmed, drafted, archived.

Drafting, Repurposing & Credits

The Draft step is the only part of the staged flow that costs credits. TruIntel deducts the credits up front (under a row lock to prevent double-charging), creates a placeholder generation, marks the brief drafted, and dispatches a background task that runs the full content-generation pipeline. If the dispatch fails, the credits are automatically refunded and the brief is reset.

ActionCredit costModel used
Build briefFreeDataForSEO research + utility-LLM (Anthropic-first) for TOC merge and H1
Edit briefFreeNo model — direct field patch
Draft (standard tier)1 creditgemini-3.1-flash-lite
Draft (premium tier)3 creditsclaude-haiku-4-5
Repurpose (each format)1 creditgemini-3.1-flash-lite

Premium is Haiku, not Sonnet or GPT

The 3-credit premium draft tier pins the Anthropic-first utility chain, which resolves to claude-haiku-4-5. The standard 1-credit tier uses gemini-3.1-flash-lite. Research grounding (keywords, SERP, PAA) always comes from DataForSEO.

Repurpose one brief into many surfaces

The primary blog draft comes from the Draft step. Repurpose takes the same brief and produces the other fast, grounded answer surfaces from it — each becomes its own generation that you poll until ready. The brief's status and its opportunity link are left untouched.

FAQ page

A question-and-answer page derived from the brief. 1 credit.

Structured answer

A concise, citation-ready answer block tuned for AI engines. 1 credit.

Meta descriptions

Search-snippet meta descriptions for the topic. 1 credit.

Credit pools and monthly allowances

Credits come from two live pools: plan_credits, your monthly allowance that resets on the 1st, and extra_credits, top-up packs that never expire. The discontinued legacy "Plus" credit pool is no longer spendable.

Starter

$59/mo

  • 50 AI credits / month
  • Full Content Studio
  • Standard + premium drafts

Lite

$139/mo

  • 150 AI credits / month
  • Full Content Studio
  • 2 brands

Pro

$479/mo

  • 500 AI credits / month
  • Full Content Studio
  • 3 brands

Enterprise

Custom

  • 1000 AI credits / month
  • Full Content Studio
  • 4 brands

Top-up packs (one-time, never expire)

Need more credits mid-month? Starter Pack — 50 credits for $10; Growth Pack — 150 credits for $25; Pro Pack — 400 credits for $50. Free plan has 0 monthly credits, so drafting requires a paid plan or a top-up.

Publishing Calendar

The Calendar page is a publishing calendar over your real CMS articles — not over opportunities. The month grid shows scheduled, publishing, published, and failed articles on the day they go live, and a side Planner drawer lets you queue new work.

Two different calendars

Do not confuse the opportunity-level scheduled_date (an internal planning field, served by the legacy /content/calendar endpoint) with this Calendar page, which schedules and publishes real CMS articles via /cms/content/{id}/schedule. The Calendar page is a true publishing calendar.

The Planner drawer

Ready tab

Draft articles you can drag onto a day (or click Schedule) to publish.

Ideas tab

Content opportunities you can turn into an article without leaving the calendar.

How scheduling and auto-publishing work

1

Drop a draft on a day

A date-time picker opens. You pick a time, which must be in the future. The article moves to status scheduled and any previous publish error is cleared.

2

The every-minute poller fires

A beat task (cms.run_due_scheduled_publishes) runs every minute. It atomically claims due scheduled rows, flips them to publishing, pushes the article to your website, and sets the final status. This poller is the single source of truth — there is deliberately no per-item timer, which would be unreliable and could double-publish.

3

Reschedule or unschedule

Drag a scheduled chip to another day to move its fire time. Unschedule returns an article to draft and clears its scheduled time.

StatusChip behavior
scheduled (violet)Draggable to reschedule; can be unscheduled back to draft.
publishing (amber)Locked while it publishes (409 if you try to move it).
publishedAnchored and immutable — it has already gone live.
failedRetryable — re-schedule it to try again.
draftLives in the Ready tab until you schedule it.
generatingLocked while content is still being produced.
archivedLocked.

Clicking any chip opens that article in the CMS editor. The calendar reads from GET /cms/content/calendar?month= and uses POST /cms/content/{id}/schedule, POST /cms/content/{id}/unschedule, and GET /cms/content/{id}/publish-status.

Library

The Library is a single unified "my drafts" view that merges both content stores behind one table, each row carrying a source badge so you always know where a draft came from.

TruIntel Plus generations

Publishable drafts produced by the staged Create flow and repurpose actions. Rows offer Preview, Send-to-CMS, Schedule, and status actions.

CMS content

Articles already in your CMS — landing pages, comparisons, how-tos, listicles. Rows offer Open-in-CMS and View-live.

CMS is additive

The CMS feed is layered on top of the Plus drafts. If the CMS source errors, the Library still renders your Plus drafts rather than failing the whole page.

  • Source and status filters plus a title search.
  • A freshness stamp showing when the list was last loaded.
  • States — no-brand, loading skeleton, error with Retry, empty (a generate CTA), and the merged table.

Accountability

Accountability is the "did the work move the needle?" surface. It answers, month by month, whether the content and SEO work TruIntel recommended actually changed your numbers — and what to do next. It has two halves.

Looking back

Defaulting to the latest monthly snapshot (or any period you pick), the looking-back view proves impact with concrete, attributed evidence rather than vanity charts.

Task completion

A ring showing how many recommended tasks were completed in the period.

Queries won

AI queries where your brand started getting recognized.

Rank movement

How your overall score and positions shifted across the period.

Citations gained

New citation URLs your brand earned in AI answers.

Attributed outcomes

Which specific task moved which metric — anti-slop proof, not correlation.

Performance trend

A history of overall_score over time from the performance-history endpoint.

Looking forward

The second half lists that period's top-ranked content opportunities, each with evidence pills that link straight into the staged Create flow — closing the loop from proof back into the next round of work.

Monthly accountability email

On the monthly brand-report run (the 2nd of the month at 06:00 IST), a monthly accountability email — tasks done, what moved, and the top forward opportunities — is sent to every member of the organization.

Data comes from GET /api/v2/insights/{brand_id}/accountability?period=YYYY-MM and GET /api/v2/insights/{brand_id}/performance-history.

Plan Gating & Reference

All of Content Studio is a paid-plan feature. The capability-level gates and the full route reference are below.

CapabilityGate
All Content Studio pages (Opportunities, Create, Calendar, Library, Accountability)Paid only — Starter and up
Auto-generate opportunities at onboardingSkips Free/no-plan; GROWTH_AUTOGEN_ENABLED (default on)
Build / edit a briefFree step, still Starter+
Draft from a briefCharges credits — standard 1, premium 3
Repurpose a format1 credit each
Keyword-gap opportunity signalNeeds DataForSEO + at least one competitor with a domain + available per-brand SEO budget

Frontend routes

Bare redirect

/content-studio

Redirects to /content-studio/opportunities.

Opportunities

/content-studio/opportunities

Ranked opportunities table.

Create

/content-studio/create

Staged Create wizard (opportunity- or topic-seeded).

Resume Create

/content-studio/create/:briefId

Resume a saved brief.

Calendar

/content-studio/calendar

Publishing calendar over CMS articles.

Library

/content-studio/library

Unified drafts (Plus + CMS).

Accountability

/content-studio/accountability

Monthly value-proof and forward opportunities.

Backend endpoints

Build brief (free)

POST /content/brief

Assembles a research-grounded brief.

Fetch / edit brief

GET, PATCH /content/brief/{id}

Read or patch brief fields (editing is free).

Draft from brief

POST /content/brief/{id}/draft

Kicks the draft — charges credits (tier standard/premium).

Repurpose brief

POST /content/brief/{id}/repurpose

Produces faq_page / structured_answer / meta_descriptions (1 credit each).

List opportunities

GET /content/opportunities

Ranked list, filterable by status.

Refresh opportunities

POST /content/opportunities/refresh

Regenerates opportunities on demand.

Schedule opportunity

PATCH /content/opportunities/{id}

Sets scheduled_date and/or status.

CMS publishing calendar

GET /cms/content/calendar, POST /cms/content/{id}/schedule, /unschedule

Schedule and publish real CMS articles.

Accountability

GET /api/v2/insights/{brand_id}/accountability, /performance-history

Looking-back proof and the score trend.

Key schedules (IST, Asia/Kolkata)

Weekly opportunity refresh runs Sunday 09:00. The CMS scheduled-publish poller runs every minute. The monthly accountability email goes out on the 2nd at 06:00 with the monthly brand report. AI credits reset on the 1st at 00:00.

TruIntel Plus (AI Content)

Overview

TruIntel Plus (branded "TruPlus" in the app) is a credit-metered AI content generator. It turns your brand's AEO and SEO visibility data into ready-to-use marketing assets — SEO blog posts, FAQ pages, structured answers, schema markup, and metadata/social tags — that are pre-optimized to win mentions and citations across AI engines.

Every generation deducts credits from your organization's credit ledger. Output can be copied as Markdown or HTML, downloaded as a .md file, marked Published or Archived, or sent straight to the CMS as an editable draft.

Paid plans only

TruPlus is unavailable on the Free plan. The entire /api/v1/plus router is gated by require_paid_plan, so Free / no-plan organizations receive an upgrade lock screen on every Plus page. Starter and above unlock it.

Grounded in your data

Generators are seeded with your brand's real visibility, competitor, and source data — not generic prompts — so output reflects how AI engines actually describe your space.

Credit-metered

Each express generation costs 1 credit drawn from your monthly plan pool, then a never-expiring extra-credit pool. Briefs and CMS hand-off are free.

CMS-ready output

Blog, FAQ, and Structured Answer drafts can be sent to the CMS for free, where you edit, score, schedule, and publish them.

Fast inline generation

The live UI runs generation inline (synchronous), typically 30-60 seconds, via the provider-agnostic LLM fallback chain.

The Create Catalog

The create surface offers 5 grounded generators across 2 tiers. (The old "Backlink Strategy" tier — directory listings, outreach templates, citation plans — was retired from Plus and moved to the dedicated Outreach workspace at /outreach.)

Content tier

GeneratorOutputWhat it produces
Blog PostHTMLA ~2000-word SEO article with an FAQ section, routed through the unified CMS 5-step HTML pipeline — including AEO answer blocks, schema markup, meta title/description, OpenGraph tags, and quality + AEO-citation scores.
FAQ PageMarkdown8-12 question/answer pairs grounded in visibility data and an optional target query / People-Also-Ask, structured for JSON-LD FAQPage schema.
Structured AnswerMarkdownA citation-friendly, definitive 150-300 word answer written for AI engines to quote directly.

Technical SEO tier

GeneratorOutputWhat it produces
Schema MarkupMarkdown + JSON-LDReady-to-paste Organization, Product/Service, FAQPage, and Article structured-data blocks.
Metadata & Social TagsMarkdown + HTMLA merged generator: an SEO title/meta-description table for 8-10 pages, plus OpenGraph and Twitter-card markup for the top 5-7 pages.

Blog Post is the differentiator

Unlike the other express types, Blog Post runs the full unified CMS HTML pipeline. That means it ships with structured AEO answer blocks, schema markup, meta and OpenGraph tags, and computed quality + AEO-citation scores baked in — not just plain prose.

Where each generator lives

Blog Post, FAQ Page, Structured Answer, and Metadata & Social Tags appear in the generic wizard's step-0 grid. Schema Markup is reachable only via its own landing card / route (/plus/schema-markup). All five also have dedicated single-type pages.

Generating Content

You can generate from a dedicated single-type page (a single form) or from the generic 4-step wizard at /plus/generate. Both call the same backend and both cost 1 credit.

1

Pick a generator

Choose a surface from the TruPlus hub cards, a dedicated type page, or the wizard's Select step.

2

Enter a Target Query

A Target Query is required — it anchors the generation to a real search intent. Additional Context is optional and lets you steer tone, audience, or specifics.

3

Generate

The form submits POST /api/v1/plus/generate (synchronous by default). The system checks your credit balance, validates the brand belongs to your org, runs the generator, stores a PlusGeneration row, and deducts 1 credit.

4

Review & act on the preview

The preview screen offers Copy Markdown, Copy HTML, Download .md, Send to CMS (eligible types), and Publish / Archive.

Typical generation time

The live UI runs generation inline (synchronously), usually 30-60 seconds. A failed generation automatically refunds the credit to your extra-credit pool.

Which model runs it

Plus labels every generation gemini-3.1-flash-lite in its metadata, but execution actually routes through the provider-agnostic llm_json fallback chain, which is Anthropic-first (Claude Haiku 4.5) and only falls back to Gemini, OpenAI, or OpenRouter on failure. The displayed model name is nominal, not necessarily the provider that produced the text.

Output, CMS Hand-off & Lifecycle

Once generated, content lives as a PlusGeneration record you can export, push to the CMS, or move through a simple publish lifecycle.

Export actions

  • Copy Markdown — copy the raw Markdown to your clipboard.
  • Copy HTML — copy the rendered HTML to your clipboard.
  • Download .md — save the generation as a Markdown file.

Send to CMS

Eligible types (Blog Post, FAQ Page, Structured Answer) can be pushed into the CMS with one click. The bridge converts Markdown to HTML, parses frontmatter, runs a free Gemini SEO-optimization pass, and creates a CMSContent draft linked back to the generation. It is free, charges no credit, and is idempotent (re-sending updates the same draft). Structured Answers map to the CMS blog_post type.

Free publish bridge

Send to CMS never costs a credit. Once in the CMS, the draft can be edited, AI-SEO scored, scheduled, and published using the full Content Studio toolset.

Lifecycle & statuses

StatusMeaning
generatedDefault state for a new generation.
publishedMarked published by you (sets published_at). Use Mark Published from the preview or history row.
archivedHidden from the active list via Archive.
processingIn-flight marker shown while a staged/async generation runs ("Generating").
failedA staged/async generation failed; the credit is refunded.

Delete permanently removes a generation row. Publish and Archive are reversible status changes via PATCH /plus/generations/{brand}/{id}/status.

Generation History

The /plus/history page is a searchable, filterable record of everything you have generated for a brand.

Search & filter

Search by title and filter by generator type and status. Results are paginated 10 per page.

Per-row actions

View, Send to CMS, Mark Published, Archive, and Delete directly from each row.

CMS indicator

Rows that have been pushed to the CMS show a "Sent to CMS" indicator so you can track what has crossed over.

Reopen any generation

View a saved generation in the wizard viewer via /plus/generate?view=<id>&brand_id=<id>.

Credit System

Plus content consumes AI credits. Credits are drawn from two live pools in a fixed order, and unused express generations are refunded on failure.

PoolSourceResetSpend order
Plan CreditsIncluded with your subscription planResets to the plan allowance on the 1st of each month (00:00 IST)Spent first
Extra CreditsOne-time top-up purchasesNever reset, never expireSpent after plan credits are exhausted

No more "Plus credits" pool

The old plus_credits pool (the discontinued "TruIntel Plus $99/mo" subscription) is unspendable and always 0. Only the Plan Credits and Extra Credits pools are live, and there is no sellable Plus subscription.

Monthly plan allowance

PlanMonthly CreditsPer-plan extra-credit price
Free0 (Plus locked)
Starter50$2.00 / credit
Lite150$1.75 / credit
Pro500$1.50 / credit
Enterprise1,000$1.00 / credit

What each action costs

ActionCredit cost
Express generation (any of the 5 surfaces, incl. Blog Post)1 credit
Staged draft — standard quality1 credit
Staged draft — premium quality3 credits
Repurpose a brief into another format1 credit per format
Brief generationFree
Send to CMSFree
Internal-link suggestionsFree
Failed generationRefunded to extra-credit pool

Prompt Volumes redemption

On paid plans, once your daily/monthly Prompt-Volumes cap is exhausted, 5 credits can be redeemed for one additional Prompt-Volumes page lookup.

Buying Extra Credits

When your plan credits run low, the TruPlus hub surfaces a low-credits banner and a "Buy Extra Credits" modal. The live UI sells flat top-up packs purchased via Razorpay — one-time, and the credits never expire.

PackCreditsPricePer credit
Starter Pack50$10$0.20
Growth Pack150$25$0.167
Pro Pack400$50$0.125

Two purchase paths exist

The Plus "Buy Extra Credits" modal sells the flat packs above. A separate per-plan endpoint also lets you buy 5-100 credits at your plan's per-credit rate ($2.00 Starter down to $1.00 Enterprise). Both land in the same never-expiring extra-credit pool; the flat packs are the in-app default.

Your live credit balance and usage are shown on the TruPlus hub (low-credits banner + balance widget) and the Buy-Credits modal, and are also surfaced in Settings → Billing. For India, 18% GST is added on top of the listed USD price.

Advanced: Briefs, Repurpose & Internal Links

These Plus-service capabilities share the same credit pool and PlusGeneration table but are surfaced through the Content Studio brief flow rather than the core Plus pages.

Draft from brief

Build a content brief for free, then generate a draft. Standard quality costs 1 credit; premium quality costs 3 credits. The async worker fills the draft and refunds credits on failure.

Repurpose a brief

Turn one brief into many grounded formats — FAQ Page, Structured Answer, and Metadata & Social Tags — at 1 credit per format.

Internal-link suggestions

Free and read-only. Given a finished generation plus your brand's crawled content index, it proposes grounded anchor-to-URL internal links where the anchor text appears verbatim and the target is a real indexed page.

Premium tier

Premium-tier drafts pin the Anthropic-first chain (Claude Haiku 4.5) for higher quality at 3 credits. Brief generation itself is always free — you only pay at draft time.

Routes & Endpoints

TruPlus pages and the dedicated single-type generators in the product app:

TruPlus Hub

/plus

Generator cards (5 surfaces), Off-page pointer to /outreach, Recent Generations, and the Buy Credits modal.

Generate Wizard

/plus/generate

4-step wizard (Select → Configure → Generate → Preview); also the viewer for a saved generation.

Generation History

/plus/history

Searchable, filterable table of all generations with per-row actions.

Blog Post

/plus/blog-post

Dedicated ~2000-word HTML SEO article generator (CMS pipeline).

FAQ Page

/plus/faq-page

Dedicated 8-12 pair FAQ generator.

Structured Answer

/plus/structured-answer

Dedicated citation-friendly definitive-answer generator.

Schema Markup

/plus/schema-markup

Dedicated JSON-LD structured-data generator.

Metadata & Social Tags

/plus/meta-tags

Dedicated merged meta + OpenGraph/Twitter generator.

Key backend endpoints (all under /api/v1/plus, gated by require_paid_plan):

Method & pathPurpose
GET /plus/creditsCurrent credit balance and usage.
POST /plus/generateGenerate content (1 credit); inline or via the plus worker.
GET /plus/generations/{brand_id}Paginated list with type/status filters.
GET /plus/generations/{brand_id}/{id}Full content of one generation.
PATCH /plus/generations/{brand_id}/{id}/statusPublish or archive.
POST /plus/generations/{brand_id}/{id}/send-to-cmsFree CMS draft bridge.
POST /plus/generations/{brand_id}/{id}/internal-link-suggestionsFree internal-link proposals.
DELETE /plus/generations/{brand_id}/{id}Delete a generation.
POST /plus/credits/purchase + /verifyPer-plan variable credit purchase and verification.
GET /plus/templatesTemplate catalog with estimated token counts.

Off-page work moved out of Plus

Directory listings, outreach emails, and citation recommendations are no longer generated in Plus. Those live in the Off-page Outreach workspace at /outreach. Invoking the retired types returns a guidance error pointing you there.

CMS & Publishing

Starter+

CMS Overview

The TruIntel CMS is an in-app content module mounted under /cms/* in the product app (app.truintel.ai) — not a separate cms.truintel.ai portal. It lets a brand scan its own website, generate AEO-optimized articles with AI, edit them in a rich-text editor with a live AI SEO score, and publish them to Cloudflare’s global edge so the page looks like it lives on the brand’s own site.

Scan

BFS-crawl up to 200 pages to build a content index, extract a reusable brand template, detect page templates, and surface SEO issues + content gaps.

Generate

Produce AEO-optimized articles through a 5-step AI pipeline grounded in your real visibility gaps and site facts.

Edit

A TipTap rich-text editor with a live AI SEO/AEO score, free AI-assist (rewrite/expand/shorten), and editable meta + schema.

Publish

Push to Cloudflare KV + Workers via a multi-tier renderer; publish now, schedule for later, or auto-refresh monthly.

Optimize

AI fix-preview, batch apply, and undo on existing pages plus live-page editing (Visual Page Editor, robots.txt, sitemap).

Schedule

Drag-to-schedule publishing over a calendar, backed by a durable every-minute poller (no dropped jobs).

Plan gate

The entire CMS module (all 16 pages) is gated to Starter and above. The Free plan cannot access CMS because CMS spend is funded by the monthly AI credit allowance, which is 0 on Free.

The module is 16 pages / 16 routes, every one wrapped in a CMS protected route plus the Starter+ plan gate. It reuses your org-level AI credit pools rather than a separate CMS wallet.

5-Step Content Pipeline

Each new article is produced by a 5-step AI pipeline. Before step 1 runs, a pre-step gathers grounding data: your brand’s latest full AEO visibility check (overall/recognition/citation scores, per-platform scores, the queries where your brand is NOT mentioned, and your top 5 competitors), real product/pricing/feature snippets from the content index, relevant existing pages for internal linking, and your scanned brand tone. The pipeline grounds content in your actual AEO gaps and site facts — it does not crawl the live web.

1

Research

Analyzes the AEO landscape and your visibility gaps. Outputs key points, audience, intent, citation analysis, internal-link targets, a suggested word count, and direct-answer queries for FAQ seeds.

2

Outline

Builds a citation-optimized structure: title, quick answer, sections, key takeaways, FAQ questions, and internal links.

3

Full Draft

Writes the complete article as HTML. This is the only hard-fail step — if drafting fails the pipeline aborts and held credits are refunded.

4

SEO Optimization

Produces the meta title, meta description, Open Graph tags, and schema objects (see schema note below).

5

Quality Check

Returns a quality score, an AEO citation score, issues, strengths, AEO elements present, and a citation prediction.

Every step is a separate LLM call and has a deterministic fallback, so a transient model outage degrades quality rather than crashing the job. Output is stored as HTML plus a TipTap-compatible JSON wrapper. Generation progress is pushed live so the New page can show each step completing in real time.

Which model writes your content

The generation pipeline runs through TruIntel’s provider-agnostic fallback chain (default order Anthropic → Gemini → OpenAI → OpenRouter), so the primary model is Anthropic claude-haiku-4-5, then gemini-3.1-flash-lite, then gpt-5.4-mini, then OpenRouter moonshotai/kimi-k2.5. Gemini Flash is only the primary model for the site scan and the monthly content refresh.

Schema generated

The SEO Optimization step emits FAQPage, Article, HowTo, and a Speakable spec, combined into a single schema_markup array. There is no generic WebPage schema.

Content typeUse
blog_postStandard editorial / blog article
faq_pageQuestion-and-answer page optimized for direct-answer citation
landing_pageConversion-focused landing page
comparisonBrand vs competitor / X vs Y comparison
how_to_guideStep-by-step instructional content
listicleList-format article

Generation Entry Points & Credits

There are two ways to kick off generation: a quick Express path from the CMS New page, and a staged, brief-driven path from Content Studio. They differ in how much research happens up front and in credit cost.

Express (New page)

Give a target keyword, content type, and context, and the full pipeline runs end to end. Costs 2 credits.

Staged / brief-driven (Content Studio)

First build a free ContentBrief (keyword research + SERP analysis + merged TOC + People Also Ask), confirm it, then draft. Standard tier costs 1 credit; premium costs 3.

The premium brief tier biases the chain Anthropic-first and adds a premium editorial note. Despite an internal “Sonnet-first” label, premium still resolves to claude-haiku-4-5 — there is no Sonnet model wired in.

CMS actionCredits
Express content generation (New page)2
Staged brief draft — standard tier1
Staged brief draft — premium tier3
Brief generation (research / SERP / outline / PAA)0 (free)
Repurpose existing content1 per format
AI-assist (rewrite / expand / shorten)0 (free)
AI SEO/AEO score0 (free)
Auto page-optimization fix (per auto-fixable issue)1 each
Monthly auto-refresh (per piece)1
Manual (non-auto-fixable) optimization guidance0 (free)

CMS spends from your org-level AI credit pools in the order plan_credits (monthly allowance, resets on the 1st) then extra_credits (top-ups that never expire). Monthly allowance by plan: Free 0, Starter 50, Lite 150, Pro 500, Enterprise 1000. One-time top-up packs never expire: 50 credits for $10, 150 credits for $25, 400 credits for $50.

Credits are refunded on failure

Credits are pre-deducted at the start of a job and refunded on any definitive failure. A cleanup task marks anything stuck in the generating state for over 15 minutes as failed and refunds the held credits, so a dead job never silently burns credits.

Content Editor & AI SEO Score

Generated content opens in a full TipTap rich-text editor with rich text, images (with alt text), code blocks, links, an SEO sidebar, AI-assist, and editable schema.

Rich Text Editing

Headings, bold, italic, lists, blockquotes, and links with a familiar toolbar.

Image Support

Insert images with alt text via drag-and-drop or paste from the clipboard.

Code Blocks

Syntax-highlighted code blocks for technical content.

SEO Sidebar

Edit meta title and description with live character counts.

AI Assist runs on selected text with three actions — rewrite, expand, or shorten (up to 5,000 characters of input). It is free (0 credits) and runs through the multi-provider LLM chain, so it survives a single provider outage.

AI SEO/AEO Score

The editor scores your draft against a 5-dimension rubric summing to 100. Scoring is LLM-judged (gemini-3.1-flash-lite via the chain), free, and cached on the content’s publish metadata keyed by a SHA-256 fingerprint of title, meta title, meta description, slug, schema, and content HTML — so re-running skips the LLM unless the content meaningfully changed.

DimensionMaxCovers
Content Quality25Depth, originality, expertise, factual specificity
Readability & Structure20Heading hierarchy, paragraph length, scannability
SEO Optimization20Meta craft, keyword integration, slug, internal linking
AI Engine Readiness (AEO)20Citation-worthy facts, direct answers, FAQ, schema, listicles
Engagement & Hook15Opening hook, examples, CTAs, value-prop clarity

Ratings: excellent at 85% or above, good 65–84%, needs work 40–64%, and poor below 40% of each dimension’s max. Note that the page title is rendered as the page H1 by the publish template, so the scorer counts the title as the H1 and will not penalize the body for a “missing H1.”

Multi-Tier Edge Publishing

TruIntel publishes content to Cloudflare’s global edge (KV + Workers) using a multi-tier renderer that makes the published page blend into your existing site. The system picks the highest tier it can, falling back gracefully.

TierMethodBest for
reference_clone (Tier 1)Fetch a real reference page from your site, clone its full HTML, and replace only the content areaSites with consistent templates — nav, sidebar, and footer are preserved so the page looks identical to your existing pages
main_replacement (Tier 1.5)Clone the full page and replace the <main> element (used when you pick a template but the content selector is not found)Template chosen but content selector missing; a missing footer is re-injected from the brand template
clone_wrap (Tier 2)Wrap the content in your extracted brand header, footer, and CSSSites where no usable reference page exists but a brand template was captured
standalone (Tier 3)A built-in template using your brand colors and fontsFinal fallback when site extraction failed

All HTML passes through a single sanitization choke point before serving. After render, the page is written to Cloudflare KV, sitemap.xml is regenerated, the published URL is built (preferring your real domain), search engines are pinged (Bing IndexNow plus a best-effort Google sitemap ping), and the edge cache is purged for the slug and sitemap. If the publish satisfied a linked task, that task is auto-marked done.

Content lifecycle statuses

  • draft — created or generated, not yet published
  • generating — the AI pipeline is running
  • failed — generation failed (credits refunded)
  • scheduled — queued for a future publish time
  • publishing — actively being rendered and pushed to the edge
  • published — live on the edge
  • publish_failed — the publish step failed
  • archived — retired from active management

You can unpublish a live piece at any time, and a publish-preview endpoint lets you see the rendered page before it goes out.

Scheduled Publishing

Instead of publishing immediately, you can schedule a piece for a future date and time. Scheduling is surfaced through the Content Studio publishing calendar, where you drag content onto a date to set its publish time.

1

Schedule

Set a future ISO 8601 publish time on a piece that has HTML. Its status flips to scheduled.

2

Wait for the poller

A beat task runs every minute, atomically claims due scheduled rows in batches, flips them to publishing, and publishes them.

3

Reschedule or unschedule

Change the time, or unschedule to send the piece back to draft.

Durable by design

The every-minute poller is a deliberate replacement for per-item delayed jobs, which Railway’s broker can silently drop. Because the poller re-checks due rows continuously, a scheduled publish will fire even if a worker was restarting at the exact target minute.

  • Content that is published, publishing, generating, or archived cannot be (re)scheduled.
  • A piece must have HTML before it can be scheduled.
  • The scheduled time must be in the future.

Domain Setup & Edge Onboarding

To publish on your own website you connect a custom domain. TruIntel supports two connection modes depending on how much of your DNS you want to delegate.

ModeHow it worksCoverage
custom_hostname (default)You add a CNAME for www (or a subdomain) pointing to TruIntel’s Cloudflare proxy; we provision a custom hostname with automatic SSL. Your apex stays on your existing host.www / subdomain only
full_zoneYou delegate your nameservers; we create a dedicated Cloudflare zone, import your DNS, set up proxy topology, origin pinning, the Worker route, and SSL mode.Both apex and www proxy through the Worker
1

Add your domain

Enter the domain where you want to publish (e.g. blog.yoursite.com or yoursite.com).

2

Point DNS

For custom_hostname mode, add the CNAME for www to TruIntel’s proxy. DNS and SSL status are tracked from pending to connected.

3

Brand template extraction

TruIntel crawls your site to capture header, footer, CSS, colors, fonts, and logo so published pages match your look and feel.

4

Start publishing

Once DNS status is connected, content is served from Cloudflare’s edge worldwide under your real domain.

Hostinger apex → www SSL footgun

The connect flow only CNAMEs www to us; your apex stays on Hostinger and must 301-redirect to www. Use Hostinger’s website Redirects tool (or .htaccess with an https:// target) — NOT “Domains → Redirect your domain,” which has no SSL and breaks https:// visitors. Do not touch the www CNAME or the apex A record.

Helper endpoints validate and diagnose the connection: detect-origin, validate-origin, check-canonical, dns-status, kv-status, and disconnect-info. You can also re-extract the brand template at any time if your site’s design changes.

Site Scanning & Brand Template Extraction

The site scanner BFS-crawls up to 200 pages (concurrency 3, max depth 10, with a 20-minute crawl cap) to build a content index and capture everything needed for on-brand publishing. Per-page AI analysis, content-gap analysis, and recommendations use gemini-3.1-flash-lite directly — so for the scan, Gemini Flash is correct.

1

BFS crawl

Breadth-first crawl that respects robots.txt and builds the content index (up to 200 pages).

2

Brand template extraction

Captures header, footer, CSS, colors, fonts, logo, and favicon — with a Playwright headless fallback for JS-rendered (React/Next/Astro) sites and CSS inlining to survive redeploys.

3

Layout archetype detection

Identifies layout archetypes that power Tier-1 reference cloning.

4

Page template detection

Detects up to 20 page templates and marks the best blog template as recommended.

5

Per-page AI analysis

Gemini analyzes each page for topics, summary, and tone (capped at 5 concurrent AI calls; auto-skips remaining AI if over 60% fail).

6

Content gap analysis

Surfaces missing topics and gaps relative to competitors.

7

Recommendations

Generates prioritized recommendations for content creation and optimization.

8

Historical comparison

Compares against the previous scan; the content index is swapped atomically and fix markers carry across re-scans.

Brand template captures more than colors

The extracted brand template stores header HTML, footer HTML, external + inlined CSS, primary/secondary colors, fonts, logo, favicon, background color, a separate content background color (pulled from a real blog page to fix homepage-vs-blog theme mismatch), nav links, raw head tags, and layout archetypes. This is the engine behind Tier-1 reference cloning.

A cleanup task marks any scan stuck for more than 30 minutes as failed so the scan UI never hangs indefinitely.

Page Optimization & Fix Chain

The Optimization page turns the crawler’s detected issues into actionable fixes. Each issue carries severity, a credit cost, and whether it is auto-fixable. Auto-fixable issues are applied as edge modifications to KV; non-auto-fixable issues come with manual guidance only.

Issue typeCostExamples
Auto-fixable1 credit eachmissing/duplicate/too-long/too-short title, missing or bad meta description, duplicate meta, missing schema, missing Open Graph tags
Manual guidance only0 creditsbroken page, redirect loop, missing/multiple H1, thin content, missing canonical, slow/large page, images without alt, noindex, internal broken links
1

Scan & detect

The crawler detects issues across meta tags, headings, content, and structured data.

2

Preview the fix

Each fix preview is generated via the multi-provider LLM chain and cached for an hour, so you see exactly what will change before applying.

3

Apply (single or batch)

Apply one fix, or use fix-all to pre-generate every preview in parallel then apply them sequentially.

4

Undo

Revert any applied fix to its original state.

A connected domain is required to deploy fixes

Because fixes deploy as edge modifications to KV, the batch aborts with a no-domain-connected error unless you have a domain whose DNS status is connected. Connect and verify a domain before applying optimization fixes.

Content Refresh

TruIntel keeps published content current by refreshing it on a monthly schedule. Refresh rewrites only the outdated sections, updates meta, and adds new internal links — it is not a full rewrite. The refresh model is gemini-3.1-flash-lite.

  • Runs monthly on the 1st at 03:00 IST.
  • A piece is eligible when it is over 3 months old, has new internal-link opportunities (pages crawled after its last refresh), or was published over 30 days ago and never refreshed.
  • Refresh updates only outdated sections plus meta and internal links.

Refresh costs 1 credit per piece

Content refresh is automatic in scheduling, but it is not free. It deducts 1 credit per refreshed piece, and a piece is skipped if your org has fewer than 1 credit remaining. Keep credits available if you want monthly refresh to run.

CMS Pages & Live-Site Tools

Beyond generation, editing, and publishing, the CMS includes a set of live-site management pages for a connected domain. All 16 CMS pages share the single Starter+ gate.

Dashboard

/cms/dashboard

CMS home with scan status and a content overview.

Content Library

/cms/content

List of all generated content with its current status.

New Content

/cms/content/new

Express generation entry point (target keyword + content type + context).

Content Editor

/cms/content/:id/edit

TipTap editor with the live AI SEO score, AI-assist, and editable meta + schema.

Optimization

/cms/optimization

Detected issues with fix-preview, batch apply, and undo.

Onboarding

/cms/onboarding

Initial CMS / domain setup flow.

Visual Page Editor

/cms/edit-page

Sidebar-only live-page editor (Elements / SEO / History / Pages / Settings); edits deploy to KV and auto-publish.

Edit Pages

/cms/edit-pages

List of live pages on a connected domain that can be edited.

Robots.txt Editor

/cms/robots-txt

Edit the robots.txt stored and served from edge KV.

Sitemap Editor

/cms/sitemap

Manage the auto-generated sitemap URL list.

CMS Competitors

/cms/competitors

Competitor view scoped to the CMS module.

CMS Tasks

/cms/tasks

Content tasks tied to insights and optimization.

Backlink Fixes

/cms/backlink-fixes

Broken-backlink redirect manager that deploys redirect maps to Worker KV.

Credit History

/cms/credits

Per-action credit usage ledger.

Settings

/cms/settings

Domain and brand-template settings.

Upgrade

/cms/upgrade

Plan upgrade prompt for unlocking more credits/capacity.

Backend support comes from roughly 60 endpoints under /api/v1/cms (scan, content index, credits, content CRUD + calendar, SEO analysis, domains, publish + schedule, optimization, AI-assist, brand template, page editor, page SEO, robots.txt, and sitemap) plus the Content Studio brief flow under /api/v1/content (brief create/get/patch, paid draft, repurpose, opportunities, and calendar).

Outreach

New

What Off-Page Outreach Is

Off-Page Outreach is a human-in-the-loop backlink and earned-media workspace. It finds high-value link and AI-citation prospects, drafts one finished, ready-to-send email per prospect signed with your real identity, and tracks every prospect through an honest 5-stage CRM funnel. It does not auto-send email — sending is a one-click handoff to your own email client.

Surface prospects

Fuses three off-page signals — backlink gaps, AI-citation gaps, and broken links — into one ranked, evidence-tagged prospect list.

Draft one finished email

AI writes a complete, placeholder-free email per prospect, grounded in that prospect's evidence and signed with your real sender identity.

Track an honest funnel

Move each prospect through prospect to drafted to sent to replied to linked, with every stage clearly labelled "auto" or "you mark".

Auto-find contacts

A free background site-scrape finds a public contact email for each prospect, ranking role inboxes (editor, press, partnerships) highest.

Auto-confirm wins

A sent or replied prospect is auto-promoted to "linked" on the next refresh, once its backlink appears in your tracked backlink table.

Send from your inbox

A mailto handoff opens your own email client with the subject and body pre-filled, plus a "Copy all" button. No connected mailbox, no server-side send.

A manual CRM, not an auto-sender

Outreach is deliberately honest about its limits. Only the "drafted" and "linked" stages advance automatically; you mark "sent" and "replied" yourself. Connected-mailbox auto-send is planned for a future phase — until then, Outreach is a tracker with a mailto handoff.

Plans, Access & Cost

Off-Page Outreach is available on the Pro and Enterprise plans. Drafting and regenerating emails is completely free — it never spends AI credits. The only metered cost is the paid backlink-gap lookup during a refresh, which draws on your brand's SEO budget.

Free / Starter / Lite

Not available

  • Outreach page is plan-gated
  • Prospects still auto-generate at onboarding for paid brands only
  • Upgrade to Pro to plan and track outreach

Pro

$479/mo

  • Full Off-Page Outreach access
  • Up to 3 brands, 5 competitors per brand
  • AI-drafted emails (free, unlimited)
  • SEO budget $5/brand/month for paid lookups

Enterprise

Custom

  • Full Off-Page Outreach access
  • Up to 4 brands, 5 competitors per brand
  • AI-drafted emails (free, unlimited)
  • Contact sales for custom limits

Drafting is free

Generating and regenerating an outreach email does NOT charge AI credits. It calls the utility-LLM text generator directly rather than the credit-metered content path, so you can rewrite a draft as many times as you like at no cost.

India GST

For accounts billed in India, 18% GST is added on top of the listed USD plan price.

Where It Lives & Routes

Outreach lives in the left sidebar under the Insights section, in the "Off-Page" group as "Off-Page Outreach". It is a two-page experience: a ranked prospect table and a single-prospect composer.

Off-Page Outreach (list)

/outreach

Ranked prospect table with source, evidence, score, funnel stage and a per-row action. "Find prospects" triggers a refresh.

Prospect composer (detail)

/outreach/:prospectId

Full-width single-column composer: sender identity, tone and angle controls, the AI email, the funnel stepper and the mailto send bar.

Deep-link from Sources

Opening /outreach?domain=<gap-domain> (for example from a "Draft outreach" button on the Sources gap table) finds the matching prospect and jumps straight to its composer. If that prospect has not been materialized yet, Outreach kicks one refresh and opens it as soon as it appears.

The Three Prospect Sources

A refresh fuses three off-page signals into one ranked list. Each prospect carries an evidence object — there is no prospect without a concrete grounding signal, which keeps the list (and the emails written from it) free of generic filler.

Backlink gap

A referring domain that links to a tracked competitor but not to you. Found via a paid DataForSEO backlink-gap lookup fanned across your competitors.

AI-citation gap

A domain that AI assistants cite in answers mentioning competitors but not you. A free read of your source-gap analysis — no paid lookup.

Broken-link reclaim

An external site that links to a 404 / broken page on YOUR site. High-intent: they already link to you, so it is an easy fix-and-reclaim ask.

SourceUI labelScore basis
Backlink gapBacklink gap (blue)Estimated Domain Authority (or rank/10, capped at 100), plus +8 for each additional competitor the domain also links to
AI-citation gapAI-citation gap (violet)Opportunity score from the source-gap analysis
Broken-link reclaimBroken link (orange)Fixed 75.0 — high intent because they already link to your site

Unlinked mentions are not surfaced yet

A fourth "unlinked mention" source (a site that names your brand without linking) exists in the data model and email angles but is not generated today — there is no collector for it. Only backlink-gap, AI-citation-gap, and broken-link prospects appear in your list.

Merge, rank and cap

When the same domain shows up from more than one signal, the highest-scoring source becomes the primary and the other signals are folded into the evidence as "also seen". The final list is ranked by score (highest first) and capped at 100 prospects per refresh.

Fan-out capValueWhy
Competitors used for the gap5Top competitors by mention count
Domains pulled per competitor30Keeps the paid lookup affordable
Broken-link prospects25Caps the reclaim list
Total prospects per refresh100Hard cap on the merged, ranked list

Who Never Gets Pitched

Outreach filters out domains that should never receive a pitch, both when building the list and again defensively in the UI. This keeps you from emailing yourself, your competitors, or unreachable infrastructure hosts.

  • Non-targetable AI-infrastructure, search and CDN hosts (a denylist including vertexaisearch.cloud.google.com, google.com, amazonaws.com and similar) — flagged "Not targetable" with no email offered.
  • Your own brand domain and its name-slug variants (.com / .in / .co.in / .net / .org / .ai / .io for slugs of four or more characters).
  • Your tracked competitor domains, and any prospect whose evidence marks it as a competitor.
  • Stale, untouched prospects that are now excluded are deleted on the next refresh — but manually-advanced prospects (anything past "prospect") are left untouched.

Manual progress is preserved

A refresh only deletes prospects still in the "prospect" stage that have become excluded. Once you advance a prospect (draft, mark sent, and so on), refreshes never overwrite or discard your work.

Surfacing Prospects: Onboarding & Refresh

Prospects arrive two ways: a one-time back-fill at onboarding so the page is never empty, and an on-demand "Find prospects" refresh you trigger yourself.

1

Onboarding back-fill

When your first AEO visibility check completes, a one-time job back-fills Outreach (alongside Opportunities and Directory) for paid brands only. It runs "empty-only" — it generates a surface just once, so later refreshes are a cheap no-op.

2

On-demand refresh

Click "Find prospects" on the list page to regenerate and upsert the prospect list. The list re-ranks, excluded stale prospects are cleaned up, and won backlinks are auto-promoted.

3

Contact enrichment

Two seconds after a refresh, a background task auto-finds public contact emails for prospects missing one. It never overwrites an address you typed.

Refresh cost & budget

Only the backlink-gap part of a refresh costs money (a paid DataForSEO lookup). It is checked against your SEO/SERP per-brand monthly budget — $5 per brand per month by default — BEFORE running. The AI-citation gap (a DB read) and broken-link reclaim (cached data) are free. A refresh is also skipped entirely when a brand has no competitors or no domain set.

Budget exhausted? 429

If the backlink-gap lookup would exceed your brand's monthly SEO budget, the refresh returns a 429 ("plan limit reached") and no paid work runs. The AI-citation and broken-link prospects still refresh because they are free.

The AI-Drafted Email

Outreach writes one complete, ready-to-send email per prospect — not a template menu. The draft is grounded in that specific prospect's domain, gap reason and the competitor it links to, and is signed with your real identity. There are no placeholders or square brackets to fill in.

One finished email

A real subject and body, 110-190 words, value-first and warm. Send it as-is; the subject is never repeated inside the body.

Per-prospect grounding

The prompt is built from that prospect's evidence (the gap reason, the competitor, the citing query), not your generic brand pitch — so every email is specific.

Signed with your identity

Pulls your name, job title, phone, email and custom signature from your profile. A verbatim custom signature wins; otherwise a name/title/email/phone block; otherwise a "The {brand} Team" fallback.

No placeholders, ever

A hard rule forbids [Name], [Company], [DATE], [LINK] and the like. The recipient greeting is inferred from the domain (surferseo.com to "Surfer SEO").

Tone & angle controls

ControlOptions
Tone (5)Professional (default), Friendly, Concise, Persuasive, Casual
Angle (6)Broken-link replacement, Add to resource page, Convert unlinked mention, Guest-post pitch, Better than competitor, Cite our data / study

The angle is auto-seeded from the prospect's source — backlink-gap defaults to "add to resource page", AI-citation gap to "cite our data", and broken link to "broken-link replacement". Regenerating re-runs the draft with your chosen tone and angle, keeping the existing draft visible while the new one is written.

Resilient model chain — and free

Drafts use a provider-agnostic fallback chain — Anthropic (claude-haiku-4-5), then Gemini (gemini-3.1-flash-lite), then OpenAI (gpt-5.4-mini), then OpenRouter (moonshotai/kimi-k2.5) — so a single provider outage never blocks drafting. Generation never charges credits.

Your Sender Identity

Because every email is signed with a real person, you set up your sender identity once and it is reused for every draft across all of your brands. Generation is blocked until you provide at least a name and job title.

FieldUsed for
NameThe sign-off and the greeting from-line (required)
Job titleThe sign-off block (required before you can generate)
PhoneOptional contact line in the signature
EmailReply-to identity in the signature
Email signatureOptional verbatim custom sign-off that overrides the composed block

Set it once, manage it in Settings

The composer shows an inline form to capture your name, job title and phone the first time. These are saved to your user profile and shown as a "Sending as {name} · {job title} · {email}" summary with an Edit toggle. You can change them anytime under Settings, Profile — the change applies to every brand.

Generate is blocked when

You have not added your name and job title ("Add your sender details first"), or the prospect is a non-targetable infrastructure host (no email is offered).

The Honest CRM Funnel

Each prospect moves through a five-stage funnel (plus a dismissed state). The UI labels every stage "auto" or "you mark" so you always know what the system tracks versus what you record yourself.

StageModeHow it advances
ProspectstartInitial state when the prospect is created
DraftedautoSet automatically the moment you click Generate
Sentyou mark"Mark sent" — requires a contact email, stamps the sent time, and opens your email client via the mailto handoff
Repliedyou mark"Mark replied" — you record it when the recipient responds
LinkedautoAuto-detected when the backlink goes live; you can also "Mark linked" manually
Dismissed"Dismiss" / "Restore" — removed from the active funnel, never miscounted as a live prospect

Why "you mark" exists

Without a connected mailbox, TruIntel cannot see that you actually sent or got a reply, so it asks you to mark those stages honestly rather than faking automation. When mailbox connection ships in a future phase, "sent" and "replied" will graduate to automatic.

Sending the email

Sending is a mailto handoff: "Open in email" launches your own mail client with the recipient, subject and body pre-filled, and "Copy all" puts the subject and body on your clipboard. Nothing is sent from TruIntel's servers — you stay in full control of your own outbox.

Contact-Email Auto-Find

A free, best-effort background scrape tries to find a public contact email for each prospect so you do not have to. It uses TruIntel's own crawler — no paid vendor — and a missing email is a normal outcome you can simply type in.

1

Scrape a few pages

Checks the cited URL first, then common contact paths (/contact, /contact-us, /about, /about-us, /get-in-touch, /write-for-us). Capped at 4 pages, 4-second timeout each.

2

Extract addresses

Pulls emails from mailto: links and plain-text regex on each page.

3

Rank candidates

Same-site domain +4, role inbox (editor, press, pr, media, contact, hello, info, partnerships, outreach) +3, free mailbox (gmail, yahoo, outlook) -1. Rejects noreply, postmaster, abuse, unsubscribe, disposable and placeholder addresses. Ties break to the shorter local-part; exits early at score 6+.

When and how much it runs

The enrichment task runs after every refresh (and after onboarding back-fill), filling up to 60 prospects at a time, 8 at once. It only touches prospects missing an email in the "prospect" or "drafted" stage — it never overwrites an address you entered or touches sent / replied / linked prospects.

Always editable

The composer keeps the contact email in sync if auto-find lands one later, and the helper text reminds you: "We try to auto-find it from their contact page — edit if needed."

Pages, Columns & States

Both Outreach pages design every render state — no brand, loading, error, empty and content — so the experience is clear whether your list is full or still being built.

List page

ColumnShows
ProspectFavicon plus the linked domain
SourceColored source pill (backlink gap / AI-citation gap / broken link)
WhyThe top evidence line explaining the opportunity
ScoreOpportunity score pill (0-100)
StageFunnel stage pill, with a "Draft ready" badge when an email exists
ActionAdapts to funnel position: Generate draft / Review draft / Track / View / "Not targetable" (disabled)

The table auto-paginates at 15 rows per page, defaults to score-descending sort, and shows a "Updated {relative time}" freshness label. "Find prospects" triggers a refresh; the empty state offers the same CTA.

Detail (composer) page

A full-width single-column composer: header (favicon, linked domain, source and score pills), the honest funnel stepper, and then either a "Set up your email" card (sender identity, tone, angle, contact email and Generate) for un-drafted prospects, or the AI email itself (subject and body with copy links, inline regenerate, the mailto send bar and the funnel action buttons) once drafted. States cover no-brand, skeleton, error, not-found and content.

API Reference

All Outreach endpoints sit under /api/v1/backlinks/{brand_id}/outreach and require a paid plan. There is no single-prospect GET — the composer reads its prospect from the cached list.

Method & pathPurpose
GET /prospectsList ranked prospects (score desc). Params: status, limit (1-500, default 100), offset (>=0). Returns data, total, limit, offset.
POST /refreshRegenerate and upsert the list, then dispatch contact enrichment. 429 when the SEO budget is exhausted.
POST /{prospect_id}/draftAI-draft the email. Body: tone, campaign_angle. 502 on generation failure, 404 if the prospect is missing.
PATCH /{prospect_id}Update funnel status (and optional contact email). 400 on an invalid status, 404 if the prospect is missing.

Side effects of a status update

Marking "sent" stamps the sent time (if unset) and stores the contact email; marking "linked" best-effort links the matching tracked backlink; any status update stores a supplied contact email.

Data model

Each prospect (the outreach_prospects table) stores its domain, url, source, score (0-100), a JSON evidence object, contact email, draft subject and body, status, an optional linked-backlink id, the sent time and timestamps — indexed by (brand, status) and (brand, score desc).

Directory Submissions

New

Overview

Directory & Citation Submissions is the earned half of off-page AEO. It surfaces a ranked, evidence-backed list of directory, review, and reference sites your brand should get listed on so AI answer engines — ChatGPT, Claude, Gemini, Perplexity, and Google AI Overview — start citing you in their answers. Each target explains why it matters, scores the opportunity, and can produce paste-ready listing copy on demand.

In the app the page is titled "Directory & Citations" and lives at /directory, inside the Insights nav section under the "Off-Page" group. Its sibling feature is Off-Page Outreach (the earned link / PR half) — Directory is the "get-listed-where-AI-looks" half. Both back-fill automatically once after your first AEO visibility check.

It is a manual CRM-style tracker

TruIntel finds the directories and drafts the copy, but you submit the listing on the directory's own site and then mark the status by hand. There is no automatic detection that a listing went live — advancing a target through the funnel only updates your tracking status, it does not submit anything for you.

Grounded targets

The primary source is your AEO source gap — high-authority sites where AI cites your competitors but not you. Every target is backed by real visibility evidence, not a generic list.

Opportunity score

Each directory carries a 0–100 opportunity score so you work the highest-leverage citation gaps first. Grounded gap entries always outrank cold-start catalog suggestions.

AI-drafted listing copy

Generate paste-ready submission copy for any directory — title, best-fit category, short and full descriptions, plus approval tips. Free, no credits charged.

Listing funnel

Track each target through not listed → submitted → pending → live. Refreshing the list preserves any status you have already advanced by hand.

Plan Access & Limits

In the product, the /directory page is a Pro+ feature — the route is gated to Pro and Enterprise. There is no per-plan quota on directory submissions beyond a hard cap of 100 targets per brand, and the feature carries no DataForSEO or credit cost: both refreshing the list and generating listing copy are completely free.

SurfacePlans allowedNotes
Directory page (/directory)Pro, EnterpriseThe UI route is gated to Pro+, blocking Starter and Lite even though the raw API allows them.
Directory API endpointsAny paid planThe backend requires a paid plan; Free / no-plan organizations receive a 403 PAID_PLAN_REQUIRED.
Auto-generate at onboardingAny paid planThe one-time back-fill runs for every non-Free plan; Free is skipped.

No credits, no DataForSEO spend

Refreshing the directory list reads your existing AEO source-gap data (a free database read) plus a best-effort utility-LLM cold-start catalog. Listing-copy generation is also uncharged — it is not a credit-metered TruPlus generation. Nothing here touches your AI credit balance or any paid data vendor.

LimitValue
Max targets per brand100 rows (highest-scoring kept after each refresh)
Max cold-start catalog entriesUp to 20 per refresh, when the source gap is thin
Per-plan quotaNone — only the 100-target cap applies
CostFree (no AI credits, no DataForSEO)

How Targets Are Found

When you click "Find directories" (or when onboarding back-fills the page), TruIntel blends two sources into one ranked, de-duplicated list. The grounded source-gap data always wins, with the cold-start catalog filling in when your gap data is thin.

Source A — AEO source gap (primary, grounded)

This is the trustworthy source. It reuses the source-gap analysis from your AEO visibility check: high-authority domains that AI platforms cite in answers where your competitors are mentioned but your brand is not. Only earned-type sites are kept — editorial, community (UGC), reference, institutional, marketplace, and other — while corporate and competitor domains are dropped. The opportunity score for each target is the gap's own score (capped at 100), and the evidence records the surfacing query, which competitors are cited there, citation counts, and which platforms cite it.

Always present at onboarding

Source-gap data is written by the AEO visibility check, so by the time directories are generated after your first check, the grounded targets are guaranteed to be available.

Source B — Industry catalog (cold-start, best-effort)

When the source gap is thin or empty, a utility LLM is asked for up to 20 well-known directory, review, and reference sites for your brand's industry and country. The prompt steers a deliberate mix: a general business profile (e.g. Google Business Profile), a consumer or local review site (e.g. Yelp or the local equivalent), software / industry review sites (e.g. G2, Capterra, Trustpilot — only when relevant), reference and knowledge bases (e.g. Wikipedia, Wikidata), and vertical directories specific to your niche.

  • Catalog entries get a fixed opportunity score of 40, so grounded source-gap entries always rank above them.
  • The LLM call runs through the provider-agnostic fallback chain (Anthropic-first), so a single provider outage does not break the refresh.
  • The whole catalog step is wrapped so that even a total LLM outage never fails the refresh — you still get your grounded targets.

Merge, rank, and upsert

1

Merge

Grounded source-gap targets are merged first and win any same-domain collision. The losing entry's reason is folded under evidence so no grounding is lost, and a real submission URL from the loser is preserved.

2

Exclude

Non-targetable hosts, your own domain, and your tracked competitors' domains are removed (see Why some sites never appear).

3

Flag already-cited

Domains that already cite you are marked with an "Already cited" flag — informational only, they are not excluded.

4

Rank and cap

Targets are sorted by opportunity score (descending) and capped at the top 100 per brand.

5

Upsert

Targets are de-duplicated by domain and saved without disturbing your tracking progress (see Refresh behavior).

Category Taxonomy

Every target is tagged with a category derived from its domain type. These categories appear in the Category column and detail modal so you can tell at a glance what kind of site you are dealing with.

Category labelWhat it covers
EditorialEditorial and publisher sites that publish reviews, roundups, or coverage.
ReferenceReference and knowledge bases such as Wikipedia or Wikidata.
MarketplaceMarketplaces and software review platforms (e.g. G2, Capterra).
InstitutionalInstitutional, governmental, or association directories.
CommunityUser-generated-content and community sites (forums, Q&A, social communities).
CorporateCorporate sites (rarely shown as a target; corporate-type gap rows are dropped).
DirectoryThe default label for general or uncategorized directory sites.

AI-Drafted Listing Copy

For any target you can generate paste-ready listing copy tailored to that one directory's submission form. The draft is grounded in your brand profile, voice, the directory's category, the surfacing query, and only the competitors cited on that specific directory. It is plain text, output in a fixed order so you can copy each field straight into the directory's form.

  1. Listing title — your business name plus an optional 3–6 word descriptor.
  2. Best-fit category — the single best category to pick on that directory.
  3. Short description — a summary / tagline field, kept to 160 characters or fewer.
  4. Full description — 70–110 words written in your brand's voice.
  5. Submission tips — 2–3 practical tips to improve approval and citation odds.

Free and anti-hallucination guarded

Generating listing copy is free — it does not deduct any AI credits. The prompt forbids inventing facts, metrics, addresses, phone numbers, prices, or awards, so the draft stays grounded in your real brand data. You can pass an optional tone or extra context, and regenerate as many times as you like.

The generated copy is stored on the target itself (alongside a generated-at timestamp), so once drafted it persists. In the detail modal you can Copy it, Get it for the first time, or Regenerate. If the LLM call fails, the request returns a 502 GENERATION_FAILED and nothing is saved.

The Listing Funnel

Each target moves through a four-stage manual funnel. You advance it by hand as you actually submit the listing on the directory's own site — no scheduled job ever changes the status for you.

StatusMeaningSide effect
Not listedThe default — you have not submitted a listing here yet.None.
SubmittedYou have filled out and submitted the listing on the directory.Stamps a submitted-at timestamp the first time.
PendingThe directory is reviewing or has not yet published your listing.None.
LiveYour listing is published and live on the directory.Stamps an approved-at timestamp and stores the live listing URL when you supply one.

You submit; TruIntel tracks

Advancing a target to "Live" does not publish anything — it only records your tracking status. TruIntel never auto-submits a listing and never auto-detects that a listing went live; you mark each step yourself after acting on the directory's own site.

In the UI the funnel is reinforced by a stat strip with a count per status (Not listed / Submitted / Pending / Live) that you can click to filter, plus colored status pills and "Mark submitted / Mark pending / Mark live" buttons on each row and in the detail modal. Passing an invalid status returns a 400 VALIDATION_ERROR.

Working With the Page

The Directory & Citations page is built around a single ranked opportunities table with a detail modal. Here is what each part does.

Find directories

The primary header button re-derives the list (blending source gap + catalog, then re-ranking). An "Updated … ago" label shows freshness.

Status filters

A stat strip and filter chips let you slice the table by funnel status. Counts update live and clicking a count filters the table.

Opportunities table

Columns: Directory (favicon, name, domain link), Category, AEO signal, Opportunity score (sortable), Competitors, Status (sortable), and Actions. Paginates at 20 rows.

Detail modal

"Why this directory" (reason, surfacing query, platforms cited, competitors listed, whether you are already cited), submit / listing links, the listing-copy block, and funnel buttons.

The AEO signal pill

The AEO signal column tells you how strong the evidence is for each target: "Already cited" means AI already cites you there, "Cited by AI·N" means N competitors are cited there, and "Recommended" marks a cold-start catalog suggestion with no direct gap evidence yet.

Render states

  • Loading skeleton while the list is being fetched.
  • Error state with a Retry button if the fetch fails.
  • Empty state ("No directories yet") with a "Find directories" call to action.
  • Content state with the ranked table.
  • Filtered-empty state when a status filter matches nothing.

Score color coding

Opportunity scores are color-coded: 70 and above render as success (green), 40–69 as warning (amber), and below 40 as neutral. Cold-start catalog entries sit at exactly 40, so they appear amber until grounded evidence raises them.

Why Some Sites Never Appear

Several classes of domain are filtered out of the target list on every refresh. This is intentional — listing on these would not earn you AI citations, or would be impossible, so they are removed to keep the list actionable.

ExcludedWhy
Mega-platforms & AI infrastructureHosts like Google, Bing, DuckDuckGo, Yahoo, YouTube, and Facebook (plus AI-infra hosts and their subdomains) are not targetable directory listings.
Your own domainYour brand's domain and close name-domain variants are removed so you do not "submit" to yourself.
Your tracked competitorsDomains owned by your active tracked competitors are dropped — you are looking for neutral citation sites, not competitor properties.
Competitor-type gap rowsAny source-gap entry whose domain type is "competitor" is excluded.

Stale targets are cleaned up

On each refresh, any not-listed target that has since become excluded (for example a domain you just added as a competitor) is purged from the list. Targets you have already advanced in the funnel are never purged.

Auto-Population & Refresh Behavior

You rarely have to think about populating this page — it back-fills itself once after onboarding, and every refresh afterward is careful never to overwrite your manual progress.

One-time back-fill at onboarding

After your first successful AEO visibility check, a background task (growth.generate_initial_surfaces) back-fills the three off-page growth surfaces at once — Content Opportunities, Off-Page Outreach, and Directory & Citations — so they arrive populated instead of empty. It is dispatched roughly 45 seconds after the visibility check completes (to let source-gap writes settle).

  • Empty-only: each surface generates only if the brand has no rows yet, so it runs once at onboarding and is a cheap no-op afterward.
  • Paid plans only: Free / no-plan organizations are skipped.
  • Isolated: each surface runs in its own try/except, so one failure never affects the others.
  • Controlled by a kill switch (GROWTH_AUTOGEN_ENABLED, on by default) and a per-brand lock that prevents double-generation.

What a manual refresh preserves

Row state at refreshWhat happens
New targetInserted as Not listed with its score and evidence.
Existing, still Not listedScore, evidence, name, and URLs refreshed in place.
Manually advanced (Submitted / Pending / Live)Status is kept untouched — only the evidence is refreshed.
Now excluded & still Not listedPurged from the list.

Refresh is safe to run anytime

Because manually-advanced rows keep their status and only their evidence is refreshed, you can click "Find directories" whenever you want fresh targets without losing track of where you are in the funnel.

Routes & Endpoints

The feature is a single front-end page backed by four brand-scoped API endpoints. All endpoints require a paid plan and verify that the brand belongs to your organization (returning 404 if not).

Directory & Citations

/directory

The product page (Insights → Off-Page). Pro+ in the UI.

MethodEndpointPurpose
GET/backlinks/{brand_id}/directories/submissionsList ranked targets (filter by status, paginate; ordered by opportunity score then recency).
POST/backlinks/{brand_id}/directories/refreshRe-derive the list (blend source gap + catalog, exclude, rank, upsert) and return it.
POST/backlinks/{brand_id}/directories/{id}/generate-listing-copyAI-draft listing copy for one target (optional tone / extra context).
PATCH/backlinks/{brand_id}/directories/{id}Advance the funnel status and optionally set the live listing URL.

Related monitoring surfaces

Directory & Citations is the action surface for closing citation gaps. To see where you are already cited, use Citation & Source Tracking and the Sources view under AI Visibility — those monitor your citations, while Directory & Citations helps you earn new ones.

Traffic Classification

Overview

TruIntel's Traffic Classification system analyzes every visitor to your website and classifies them into one of four categories. This helps you understand your real traffic, identify AI agent visits, and filter malicious bots.

CategoryDescriptionExamples
HUMANReal human visitors browsing your websiteChrome/Safari users, mobile visitors
GOOD_AGENTLegitimate AI agents and crawlers fetching contentChatGPT browser, Claude, Perplexity, Googlebot, Bingbot
BAD_BOTMalicious or unwanted automated trafficScrapers, spam bots, credential stuffers
SYNTHETICTraffic from automated tools that mimics human behaviorHeadless browsers, automated testing, click fraud

Classification Score

Classification runs through a deterministic, pure-Python pipeline (no LLM, no external API, evaluated in-process on every beacon). A visitor is matched against a sequence of layers, and only the visitors that fall through every rule-based layer reach the weighted Classification Score. The score (0–100) combines four signals:

Classification Score

40%
30%
20%
10%
Behavior Analysis (40%)
Browser Fingerprint (30%)
User Agent (20%)
Network Analysis (10%)
  • Behavior Analysis (40%) — mouse/touch events, natural-mouse and natural-scroll patterns, scroll/click/key activity, and time-on-page tiers (>5s / >15s / >30s). Passive readers stay human thanks to a forgiving base score; zero time-on-page and impossible event rates (>50 events/sec) are penalized.
  • Browser Fingerprint (30%) — realistic screen dimensions per device type, valid color depth, timezone, language(s), WebGL vendor/renderer (real GPU vendors), hardware concurrency, and device memory.
  • User Agent (20%) — browser signature validity, platform consistency, realistic version numbers, and penalties for missing or suspicious tokens (bot, crawler, spider, curl, python, wget, axios, …).
  • Network Analysis (10%) — presence and validity of a referrer (search-engine and social referrers earn bonuses) and a valid connection type.

Score bands and confidence

The weighted total maps to a classification band. Note that score and confidence are different numbers: a real human only needs a score of 60 or above, while confidence (how sure the engine is) rises separately toward 95.

Total scoreClassificationActionConfidence
60–100HUMANALLOWEDmin(95, 70 + (total − 60))
40–59 (borderline)SYNTHETIC if ≥3 synthetic indicators, else HUMANFLAGGED / ALLOWED75 / 65
20–39SYNTHETICFLAGGED80
Below 20BAD_BOTBLOCKED85

Synthetic indicators (any 3 flip a borderline 40–59 score to SYNTHETIC): excessive event rate (>30/sec), default headless resolution (exactly 800×600), headless fingerprint (no WebGL + no device memory + hardware concurrency ≤ 1), no interaction despite >30s on page, cookies disabled with no Do Not Track signal, and webdriver detected in the user-agent.

Labels are advisory, never enforcement

Actions like BLOCKED and FLAGGED are labels recorded in your traffic log — TruIntel never blocks or alters a visitor request. The optional server middleware always passes the request through (it calls next() immediately), and custom blacklist rules only change the recorded classification label. Use them for visibility and reporting, not as a firewall.

Classification Pipeline

Before any visitor reaches the weighted score above, the classifier evaluates a sequence of rule-based layers. Layers are checked in order and the first match wins, so the deterministic checks (your own rules, then the known-agent and known-bot catalogs) take precedence over heuristic scoring.

LayerTriggerResultActionConfidence
0 — Custom whitelistYour brand whitelist regex matches the user-agentGOOD_AGENTWHITELISTED98
1 — Custom blacklistYour brand blacklist regex matches the user-agentBAD_BOTBLOCKED98
2a — Known AI agentUA matches an AI training / search / browsing / shopping agentGOOD_AGENTWHITELISTED95
2b — Other known agentUA matches a search engine, social-preview, or monitoring agentGOOD_AGENTALLOWED90
3 — Known bad botUA matches a bad-bot patternBAD_BOTBLOCKED or FLAGGED90
4 — Suspicious patternHeadless / automation signature detectedSYNTHETICFLAGGED85
5 — Score-basedNone of the above — falls through to the weighted scoreHUMAN / SYNTHETIC / BAD_BOTVaries65–95

In-app browser guard

When a full real browser is used by a social-preview agent (for example a LinkedIn or WhatsApp in-app browser opening your page), the agent match is skipped and the visit falls through to score-based classification — so it is treated as a human, not a bot. Search-engine and monitoring agents (Googlebot WRS, Lighthouse) are deliberately NOT skipped because they legitimately render pages with browser-like user-agents.

Pattern Catalog

The known-agent and known-bot catalogs power layers 2 and 3, and you can browse them in the dashboard Pattern Catalog (paid plans). They are bundled in the product — there is no external lookup at classification time.

CatalogEntriesCategoriesExamples
Known AI agents937 (ai_training, ai_search, ai_browsing, shopping_agent, search_engine, social_preview, monitoring)GPTBot, ClaudeBot, PerplexityBot, Gemini-DeepResearch, Googlebot, Bingbot, Slackbot, Twitterbot, Lighthouse
Known bad bots556 (scraper, scanner, attack_tool, http_client, spam, fake)SemrushBot, AhrefsBot, Scrapy, Nikto, sqlmap, python-requests, XRumer, HeadlessChrome

Each bad bot carries a severity (low / medium / high / critical) and a default action of BLOCK or FLAG — both surfaced in the Threat Analysis view. GOOD_AGENT is broader than just AI assistants: it also covers traditional search engines (Googlebot, Bingbot), social-preview bots (Slackbot, Twitterbot, LinkedInBot), and uptime monitoring (Lighthouse).

Custom rules

Paid plans can add per-brand whitelist and blacklist rules from the Rules Manager. Each rule is a regex/substring pattern matched against the user-agent; a whitelist hit forces GOOD_AGENT / WHITELISTED and a blacklist hit forces BAD_BOT / BLOCKED, both at confidence 98 (the highest, ahead of the bundled catalogs). Saving rules replaces the full rule set for the brand. As with all actions, blacklist rules only relabel a visit — they do not stop traffic on your site.

Installation

TruIntel uses a two-part tracking system for complete traffic intelligence. The client-side script runs in the browser to detect real humans, headless browsers, and browser-based bots. The server-side middleware intercepts AI crawlers (GPTBot, ClaudeBot, PerplexityBot, etc.) that never execute JavaScript. Deploy both for the most accurate classification.

Client-Side ScriptServer-Side Middleware
Runs inBrowser (visitor's device)Your server (every HTTP request)
DetectsHumans, headless browsers, browser botsAI crawlers, search bots, social preview bots
MethodBehavior analysis + browser fingerprintUser-Agent string matching + heuristics
Payload size~4 KB gzipped, asyncZero client impact (server-only)
Required?YesStrongly recommended
EndpointHandled by tracker.js automaticallyPOST /api/v1/i/e (fire-and-forget)
1

Find your Brand ID

Open your TruIntel dashboard → Settings → Integrations. Copy the Brand ID shown under your brand. Each brand has a unique ID.

2

Install the client-side script

Choose your framework below and paste the snippet into your site. The config object (window.TruIntel) must load before the tracker script. Works on every page automatically.

3

Add server-side middleware (strongly recommended)

Install middleware to catch AI crawlers that skip JavaScript. Without this, visits from GPTBot, ClaudeBot, PerplexityBot, and 50+ other AI agents will be invisible.

4

Verify installation

Visit your website in a browser, then check the Traffic page in TruIntel. Your visit should appear within 10 seconds. Test server-side with the curl command in the Verification section below.

Replace YOUR_BRAND_ID

Every code snippet on this page uses YOUR_BRAND_ID as a placeholder. Replace it with your actual Brand ID from Settings → Integrations before deploying. Using the wrong ID means traffic will not appear in your dashboard.


Client-Side Script

The client-side script classifies visitors using behavior analysis (mouse movements, scroll patterns, click timing), browser fingerprinting (canvas, WebGL, fonts, timezone), and user-agent parsing. It loads asynchronously, never blocks rendering, and sends one beacon per session in fire-and-forget mode. It sets two first-party cookies (no cross-site tracking), honors Do Not Track as a hard opt-out, and the traffic classifier itself collects no personally identifiable information. Note that the same script also includes optional lead-capture, which does read submitted contact-form fields — see Privacy & Performance below.

Signal CollectedPurposePII?
Mouse movement patternsDistinguish humans from headless browsersNo
Scroll depth & timingDetect automated scroll behaviorNo
Session ID (random UUID)Group pageviews into sessionsNo
Visitor ID (random UUID)Identify returning visitors (no cross-site tracking)No
Browser fingerprint (canvas hash)Detect headless/spoofed browsersNo
Page URL & referrerAttribute traffic sourcesNo
Screen resolution & timezoneDetect datacenter-based botsNo
User-agent stringIdentify browser/OS and known botsNo

Performance

The tracker script is ~4 KB gzipped, loads with async (non-blocking), and the collect endpoint rate-limits to 30 requests/minute per IP. It has zero impact on your Core Web Vitals (LCP, FID, CLS). It sets only first-party cookies on your own domain (a 365-day visitor ID and a ~30-minute session ID) — no third-party or cross-site tracking.

HTML

Add this snippet inside the <head> tag on every page you want to track. Both script tags are required — the first sets the config, the second loads the tracker.

index.html
<!-- TruIntel Traffic Tracking -->
<script>
  window.TruIntel = {
    brandId: 'YOUR_BRAND_ID',
    apiUrl: 'https://api.truintel.ai/api/v1'
  };
</script>
<script async src="https://api.truintel.ai/api/v1/traffic/tracker.js"></script>

React

Create a tracker component and render it once at the root of your app (App.tsx or main layout). The cleanup function removes the script on unmount to prevent duplicates in development mode.

TruIntelTracker.tsx
import { useEffect } from 'react';

export function TruIntelTracker() {
  useEffect(() => {
    window.TruIntel = {
      brandId: 'YOUR_BRAND_ID',
      apiUrl: 'https://api.truintel.ai/api/v1'
    };
    const s = document.createElement('script');
    s.async = true;
    s.src = 'https://api.truintel.ai/api/v1/traffic/tracker.js';
    document.head.appendChild(s);
    return () => { document.head.removeChild(s); };
  }, []);
  return null;
}

// Usage in App.tsx:
// import { TruIntelTracker } from './TruIntelTracker';
// function App() { return <><TruIntelTracker /><Router>...</Router></>; }

Next.js

Use the Next.js Script component for optimized loading. The config must use beforeInteractive to ensure it loads before the tracker. Works with both App Router (app/layout.tsx) and Pages Router (_app.tsx).

app/layout.tsx
import Script from 'next/script';

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        {/* Config MUST load before tracker.js */}
        <Script id="truintel-config" strategy="beforeInteractive"
          dangerouslySetInnerHTML={{
            __html: `window.TruIntel={brandId:'YOUR_BRAND_ID',apiUrl:'https://api.truintel.ai/api/v1'};`,
          }} />
        <Script src="https://api.truintel.ai/api/v1/traffic/tracker.js"
          strategy="afterInteractive" />
      </head>
      <body>{children}</body>
    </html>
  );
}

Vue

Use lifecycle hooks to inject the script in your root App.vue or main layout component. The script is cleaned up on component unmount.

App.vue
<script setup>
import { onMounted, onUnmounted } from 'vue';

let script = null;

onMounted(() => {
  window.TruIntel = {
    brandId: 'YOUR_BRAND_ID',
    apiUrl: 'https://api.truintel.ai/api/v1'
  };
  script = document.createElement('script');
  script.async = true;
  script.src = 'https://api.truintel.ai/api/v1/traffic/tracker.js';
  document.head.appendChild(script);
});

onUnmounted(() => {
  if (script) document.head.removeChild(script);
});
</script>

Nuxt

Add to your nuxt.config.ts to inject the script globally on every page. Nuxt handles the script loading order automatically.

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      script: [
        {
          innerHTML: "window.TruIntel={brandId:'YOUR_BRAND_ID',apiUrl:'https://api.truintel.ai/api/v1'};",
        },
        {
          src: 'https://api.truintel.ai/api/v1/traffic/tracker.js',
          async: true,
        },
      ],
    },
  },
});

Svelte / SvelteKit

For SvelteKit, add to src/app.html inside the <head> tag. Alternatively, use <svelte:head> in your root +layout.svelte for dynamic injection.

src/routes/+layout.svelte
<svelte:head>
  {@html `<script>window.TruIntel={brandId:'YOUR_BRAND_ID',apiUrl:'https://api.truintel.ai/api/v1'};</script>`}
  {@html `<script async src="https://api.truintel.ai/api/v1/traffic/tracker.js"></script>`}
</svelte:head>

Angular

Add the script tags directly to your src/index.html inside the <head> tag. This is the simplest approach and works for all Angular versions.

src/index.html
<!-- Inside <head> -->
<script>
  window.TruIntel = {
    brandId: 'YOUR_BRAND_ID',
    apiUrl: 'https://api.truintel.ai/api/v1'
  };
</script>
<script async src="https://api.truintel.ai/api/v1/traffic/tracker.js"></script>

WordPress

Add to your theme's functions.php file. If you use a child theme, add it there instead so updates don't overwrite it. Alternatively, use a plugin like "Insert Headers and Footers" or "WPCode" to inject without editing theme files.

functions.php
// Add to your theme's functions.php
function truintel_tracking_script() {
  echo '<!-- TruIntel Traffic Tracking -->
<script>
  window.TruIntel = {
    brandId: "YOUR_BRAND_ID",
    apiUrl: "https://api.truintel.ai/api/v1"
  };
</script>
<script async src="https://api.truintel.ai/api/v1/traffic/tracker.js"></script>';
}
add_action('wp_head', 'truintel_tracking_script');

Script Load Order

The config script (window.TruIntel = {...}) MUST load before tracker.js. If the tracker loads first, it will not find the config and silently fail. In frameworks like Next.js, use strategy="beforeInteractive" for the config and strategy="afterInteractive" for the tracker.

Single-Page Apps (SPA)

The tracker script automatically detects client-side route changes (pushState/replaceState and popstate events). No extra configuration is needed for React Router, Vue Router, Next.js App Router, or any other SPA routing library. Each route change is tracked as a new pageview.


Server-Side Middleware

AI crawlers like GPTBot, ClaudeBot, and PerplexityBot typically don't execute JavaScript — they fetch raw HTML and parse it directly. The client-side script alone cannot detect them. Server-side middleware inspects the User-Agent header on every incoming request and forwards matching bot traffic to TruIntel's classification API. The API call is fire-and-forget: it runs asynchronously and never blocks or slows down the response to the visitor.

Best practice: use both

The client-side script handles humans and browser-based bots (scoring via behavior + fingerprint). The server-side middleware catches headless AI crawlers (scoring via user-agent + network). Together they give you complete visibility. Without middleware, 30-60% of AI agent traffic is invisible.

Next.js Middleware

Create middleware.ts at the root of your Next.js project (next to package.json, not inside src/). The matcher config excludes static assets, images, and API routes from bot detection.

middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

const BRAND_ID = 'YOUR_BRAND_ID';
const TRUINTEL_API = 'https://api.truintel.ai/api/v1/i/e';

// AI crawlers — expand from Pattern Catalog for 90+ patterns
const AI_CRAWLERS = [
  'GPTBot','ChatGPT-User','OAI-SearchBot','ChatGPT-Agent',
  'ClaudeBot','Claude-Web','Claude-SearchBot','anthropic-ai',
  'Google-Extended','GoogleOther','Gemini-Deep-Research',
  'bingbot','BingPreview','Copilot','AzureAI-SearchBot',
  'PerplexityBot','Perplexity-User',
  'Meta-ExternalAgent','Meta-ExternalFetcher',
  'Applebot','Applebot-Extended',
  'GrokBot','xAI-Grok','Bytespider',
  'DeepseekBot','MistralAI-User','Amazonbot',
  'CCBot','Diffbot','YouBot','FirecrawlAgent',
];
const OTHER_BOTS = [
  'Googlebot','DuckDuckBot','YandexBot','Baiduspider',
  'Slackbot','Twitterbot','LinkedInBot',
  'facebookexternalhit','WhatsApp','Discordbot',
];
const ALL = [...AI_CRAWLERS, ...OTHER_BOTS];

function isBot(ua: string): boolean {
  if (!ua) return true;
  const lower = ua.toLowerCase();
  if (ALL.some(p => lower.includes(p.toLowerCase()))) return true;
  if (lower.includes('bot/') || lower.includes('spider/')
      || lower.includes('crawler/')) return true;
  if (lower.includes('mozilla/5.0') && lower.includes('applewebkit')) return false;
  return true;
}

export function middleware(req: NextRequest) {
  const ua = req.headers.get('user-agent') || '';

  if (isBot(ua)) {
    const ip = req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() || '';

    // Fire-and-forget — never blocks or slows the response
    fetch(TRUINTEL_API, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'X-Forwarded-For': ip },
      body: JSON.stringify({
        brand_id: BRAND_ID,
        page: req.nextUrl.pathname + req.nextUrl.search,
        user_agent: ua,
        referrer: req.headers.get('referer') || null,
        is_new_session: true,
        is_new_visitor: true,
      }),
    }).catch(() => {});
  }

  return NextResponse.next();
}

// Exclude static assets, images, and API routes
export const config = {
  matcher: [
    '/((?!_next/static|_next/image|favicon.ico|api/|.*\\.(svg|png|jpg|jpeg|gif|webp|ico|css|js|woff|woff2)$).*)',
  ],
};

Express.js

Create a middleware file and register it with app.use(). Place it early in your middleware chain (before route handlers) so every request is checked.

truintel-middleware.js
const BRAND_ID = 'YOUR_BRAND_ID';
const TRUINTEL_API = 'https://api.truintel.ai/api/v1/i/e';

const AI_CRAWLERS = [
  'GPTBot','ChatGPT-User','OAI-SearchBot','ChatGPT-Agent',
  'ClaudeBot','Claude-Web','Claude-SearchBot','anthropic-ai',
  'Google-Extended','GoogleOther','Gemini-Deep-Research',
  'bingbot','BingPreview','Copilot',
  'PerplexityBot','Meta-ExternalAgent','Applebot',
  'GrokBot','Bytespider','DeepseekBot','Amazonbot',
  'CCBot','Diffbot','YouBot','FirecrawlAgent',
];
const OTHER_BOTS = [
  'Googlebot','DuckDuckBot','YandexBot','Slackbot',
  'Twitterbot','LinkedInBot','facebookexternalhit','Discordbot',
];
const ALL = [...AI_CRAWLERS, ...OTHER_BOTS];

function isBot(ua) {
  if (!ua) return true;
  const lower = ua.toLowerCase();
  if (ALL.some(p => lower.includes(p.toLowerCase()))) return true;
  if (lower.includes('bot/') || lower.includes('spider/')
      || lower.includes('crawler/')) return true;
  if (lower.includes('mozilla/5.0') && lower.includes('applewebkit')) return false;
  return true;
}

function truintelMiddleware(req, res, next) {
  const ua = req.headers['user-agent'] || '';
  if (isBot(ua)) {
    const ip = (req.headers['x-forwarded-for'] || '').split(',')[0].trim()
        || req.socket?.remoteAddress || '';
    fetch(TRUINTEL_API, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'X-Forwarded-For': ip },
      body: JSON.stringify({
        brand_id: BRAND_ID,
        page: req.originalUrl || req.url,
        user_agent: ua,
        referrer: req.headers['referer'] || null,
        is_new_session: true,
        is_new_visitor: true,
      }),
    }).catch(() => {});
  }
  next();
}

module.exports = truintelMiddleware;

// Usage: const truintel = require('./truintel-middleware');
//        app.use(truintel);

Django

Create a middleware class and add it to your MIDDLEWARE list in settings.py. The API call runs in a background thread so it never blocks request processing.

truintel_middleware.py
import threading, json, urllib.request

BRAND_ID = 'YOUR_BRAND_ID'
TRUINTEL_API = 'https://api.truintel.ai/api/v1/i/e'

AI_CRAWLERS = [
    'GPTBot','ChatGPT-User','OAI-SearchBot','ChatGPT-Agent',
    'ClaudeBot','Claude-Web','Claude-SearchBot','anthropic-ai',
    'Google-Extended','GoogleOther','Gemini-Deep-Research',
    'bingbot','BingPreview','Copilot',
    'PerplexityBot','Meta-ExternalAgent','Applebot',
    'GrokBot','Bytespider','DeepseekBot','Amazonbot',
    'CCBot','Diffbot','YouBot','FirecrawlAgent',
]
OTHER_BOTS = [
    'Googlebot','DuckDuckBot','YandexBot','Slackbot',
    'Twitterbot','LinkedInBot','facebookexternalhit','Discordbot',
]
ALL_PATTERNS = AI_CRAWLERS + OTHER_BOTS

def is_bot(ua):
    if not ua:
        return True
    lower = ua.lower()
    if any(p.lower() in lower for p in ALL_PATTERNS):
        return True
    if any(x in lower for x in ['bot/', 'spider/', 'crawler/']):
        return True
    if 'mozilla/5.0' in lower and 'applewebkit' in lower:
        return False
    return True

def _send(data, ip):
    try:
        req = urllib.request.Request(
            TRUINTEL_API, json.dumps(data).encode(),
            headers={'Content-Type': 'application/json', 'X-Forwarded-For': ip},
            method='POST'
        )
        urllib.request.urlopen(req, timeout=5)
    except Exception:
        pass

class TruIntelCrawlerMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        ua = request.META.get('HTTP_USER_AGENT', '')
        if is_bot(ua):
            forwarded = request.META.get('HTTP_X_FORWARDED_FOR', '')
            ip = forwarded.split(',')[0].strip() if forwarded else request.META.get('REMOTE_ADDR', '')
            data = {
                'brand_id': BRAND_ID,
                'page': request.get_full_path(),
                'user_agent': ua,
                'referrer': request.META.get('HTTP_REFERER'),
                'is_new_session': True,
                'is_new_visitor': True,
            }
            threading.Thread(target=_send, args=(data, ip), daemon=True).start()
        return self.get_response(request)

# settings.py:
# MIDDLEWARE = ['yourapp.truintel_middleware.TruIntelCrawlerMiddleware', ...]

FastAPI

Add middleware using Starlette's BaseHTTPMiddleware. The API call runs in a background thread to keep the async event loop unblocked.

truintel_middleware.py
import threading, json, urllib.request
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request

BRAND_ID = 'YOUR_BRAND_ID'
TRUINTEL_API = 'https://api.truintel.ai/api/v1/i/e'

AI_CRAWLERS = [
    'GPTBot','ChatGPT-User','OAI-SearchBot','ChatGPT-Agent',
    'ClaudeBot','Claude-Web','Claude-SearchBot','anthropic-ai',
    'Google-Extended','GoogleOther','Gemini-Deep-Research',
    'PerplexityBot','Meta-ExternalAgent','Applebot',
    'GrokBot','Bytespider','DeepseekBot','Amazonbot','CCBot',
]
OTHER_BOTS = [
    'Googlebot','DuckDuckBot','YandexBot','Slackbot',
    'Twitterbot','LinkedInBot','facebookexternalhit','Discordbot',
]
ALL_PATTERNS = AI_CRAWLERS + OTHER_BOTS

def _is_bot(ua):
    if not ua:
        return True
    lower = ua.lower()
    if any(p.lower() in lower for p in ALL_PATTERNS):
        return True
    if any(x in lower for x in ['bot/', 'spider/', 'crawler/']):
        return True
    if 'mozilla/5.0' in lower and 'applewebkit' in lower:
        return False
    return True

def _send(data, ip):
    try:
        req = urllib.request.Request(
            TRUINTEL_API, json.dumps(data).encode(),
            headers={'Content-Type': 'application/json', 'X-Forwarded-For': ip},
            method='POST'
        )
        urllib.request.urlopen(req, timeout=5)
    except Exception:
        pass

class TruIntelMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        ua = request.headers.get('user-agent', '')
        if _is_bot(ua):
            forwarded = request.headers.get('x-forwarded-for', '')
            ip = forwarded.split(',')[0].strip() if forwarded else (str(request.client.host) if request.client else '')
            data = {
                'brand_id': BRAND_ID,
                'page': str(request.url.path) + ('?' + str(request.url.query) if request.url.query else ''),
                'user_agent': ua,
                'referrer': request.headers.get('referer'),
                'is_new_session': True,
                'is_new_visitor': True,
            }
            threading.Thread(target=_send, args=(data, ip), daemon=True).start()
        return await call_next(request)

# main.py:
# from truintel_middleware import TruIntelMiddleware
# app.add_middleware(TruIntelMiddleware)

Flask

Use Flask's before_request hook to check every incoming request. Import and call init_truintel(app) in your main app file.

truintel_middleware.py
import threading, json, urllib.request
from flask import request

BRAND_ID = 'YOUR_BRAND_ID'
TRUINTEL_API = 'https://api.truintel.ai/api/v1/i/e'

AI_CRAWLERS = [
    'GPTBot','ChatGPT-User','OAI-SearchBot','ChatGPT-Agent',
    'ClaudeBot','Claude-Web','Claude-SearchBot','anthropic-ai',
    'Google-Extended','GoogleOther','Gemini-Deep-Research',
    'PerplexityBot','Meta-ExternalAgent','Applebot',
    'GrokBot','Bytespider','DeepseekBot','Amazonbot','CCBot',
]
OTHER_BOTS = [
    'Googlebot','DuckDuckBot','YandexBot','Slackbot',
    'Twitterbot','LinkedInBot','facebookexternalhit','Discordbot',
]
ALL_PATTERNS = AI_CRAWLERS + OTHER_BOTS

def _is_bot(ua):
    if not ua:
        return True
    lower = ua.lower()
    if any(p.lower() in lower for p in ALL_PATTERNS):
        return True
    if any(x in lower for x in ['bot/', 'spider/', 'crawler/']):
        return True
    if 'mozilla/5.0' in lower and 'applewebkit' in lower:
        return False
    return True

def _send(data, ip):
    try:
        req = urllib.request.Request(
            TRUINTEL_API, json.dumps(data).encode(),
            headers={'Content-Type': 'application/json', 'X-Forwarded-For': ip},
            method='POST'
        )
        urllib.request.urlopen(req, timeout=5)
    except Exception:
        pass

def init_truintel(app):
    @app.before_request
    def track_bots():
        ua = request.headers.get('User-Agent', '')
        if _is_bot(ua):
            forwarded = request.headers.get('X-Forwarded-For', '')
            ip = forwarded.split(',')[0].strip() if forwarded else (request.remote_addr or '')
            data = {
                'brand_id': BRAND_ID,
                'page': request.full_path,
                'user_agent': ua,
                'referrer': request.referrer,
                'is_new_session': True,
                'is_new_visitor': True,
            }
            threading.Thread(target=_send, args=(data, ip), daemon=True).start()

# app.py:
# from truintel_middleware import init_truintel
# init_truintel(app)

Go (net/http)

Create an HTTP middleware handler. The API call runs in a goroutine so it never blocks the response. Wrap your router with TruIntelMiddleware(router).

truintel.go
package main

import (
	"bytes"
	"encoding/json"
	"net/http"
	"strings"
)

const brandID = "YOUR_BRAND_ID"
const truintelAPI = "https://api.truintel.ai/api/v1/i/e"

var aiCrawlers = []string{
	"GPTBot","ChatGPT-User","OAI-SearchBot","ChatGPT-Agent",
	"ClaudeBot","Claude-Web","Claude-SearchBot","anthropic-ai",
	"Google-Extended","GoogleOther","Gemini-Deep-Research",
	"PerplexityBot","Meta-ExternalAgent","Applebot",
	"GrokBot","Bytespider","DeepseekBot","Amazonbot","CCBot",
}
var otherBots = []string{
	"Googlebot","DuckDuckBot","YandexBot","Slackbot",
	"Twitterbot","LinkedInBot","facebookexternalhit","Discordbot",
}

func isBot(ua string) bool {
	if ua == "" { return true }
	lower := strings.ToLower(ua)
	for _, p := range append(aiCrawlers, otherBots...) {
		if strings.Contains(lower, strings.ToLower(p)) { return true }
	}
	for _, x := range []string{"bot/", "spider/", "crawler/"} {
		if strings.Contains(lower, x) { return true }
	}
	if strings.Contains(lower, "mozilla/5.0") && strings.Contains(lower, "applewebkit") {
		return false
	}
	return true
}

func TruIntelMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ua := r.UserAgent()
		if isBot(ua) {
			ip := strings.Split(r.Header.Get("X-Forwarded-For"), ",")[0]
			if ip == "" { ip = strings.Split(r.RemoteAddr, ":")[0] }
			go func() {
				body, _ := json.Marshal(map[string]interface{}{
					"brand_id": brandID,
					"page": r.URL.RequestURI(),
					"user_agent": ua,
					"referrer": r.Referer(),
					"is_new_session": true, "is_new_visitor": true,
				})
				req, _ := http.NewRequest("POST", truintelAPI, bytes.NewReader(body))
				req.Header.Set("Content-Type", "application/json")
				req.Header.Set("X-Forwarded-For", ip)
				http.DefaultClient.Do(req)
			}()
		}
		next.ServeHTTP(w, r)
	})
}

// Usage: http.ListenAndServe(":8080", TruIntelMiddleware(router))

AI Crawler Coverage — 93 agents + 55 bad bots

The examples above show the most common patterns. TruIntel's Pattern Catalog includes 93 known-agent signatures (across OpenAI, Anthropic, Google, Microsoft, Meta, Apple, xAI/Grok, ByteDance, Perplexity, DeepSeek, Mistral, Amazon, Cohere, Common Crawl, dozens of AI search engines, traditional search engines and social-preview bots) plus 55 known bad bots. For the complete and always-updated list, use the one-click copy in your TruIntel dashboard (Traffic → Install Script) or browse the Pattern Catalog.

Existing middleware?

If you already have middleware (auth, CORS, logging), just add the TruIntel middleware to your chain. It calls next() immediately after the fire-and-forget API call — it never modifies the request or response. Order doesn't matter since it's non-blocking.


Verification & Testing

After installing both scripts, verify that traffic data is flowing correctly into your TruIntel dashboard.

1

Verify client-side

Open your website in a browser. Open DevTools → Network tab and filter by "tracker.js". You should see the script load successfully (200 status). Then filter by "/i/" to see the tracking beacon requests.

2

Check the dashboard

Go to TruIntel → Traffic. Your visit should appear in the Live Traffic Feed within 10 seconds, classified as HUMAN with a high confidence score.

3

Test server-side with curl

Run the curl command below from your terminal. This simulates a GPTBot visit. Check the Traffic page — you should see it classified as GOOD_AGENT within a few seconds.

4

Test edge cases

Visit from a mobile device, try incognito mode, and verify that each visit appears correctly classified. Check that static assets (images, CSS) are NOT being tracked.

Terminal
# Simulate GPTBot visiting your homepage
curl -s https://yoursite.com/ \
  -H "User-Agent: Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) GPTBot/1.0"

# Simulate ClaudeBot
curl -s https://yoursite.com/ \
  -H "User-Agent: ClaudeBot/1.0 (https://anthropic.com)"

# If your middleware is working, both visits appear in TruIntel
# within seconds, classified as GOOD_AGENT

What to expect

After successful installation: real browser visits are classified as HUMAN (score 60 or above, reported at high confidence), known AI agents appear as GOOD_AGENT, headless browsers appear as SYNTHETIC (score 20–39, or a borderline 40–59 with 3+ synthetic indicators), and scrapers/spam bots with the lowest scores appear as BAD_BOT. It typically takes 24-48 hours to build a meaningful traffic profile.


Content Security Policy (CSP)

If your site uses Content Security Policy headers, you need to allow the TruIntel tracker script and its API endpoint. Add these directives to your CSP header:

CSP Header
Content-Security-Policy:
  script-src 'self' https://api.truintel.ai;
  connect-src 'self' https://api.truintel.ai;

CSP and nonce-based policies

If you use nonce-based CSP (script-src 'nonce-xxx'), you need to add the nonce attribute to both TruIntel script tags. The async tracker script must also be whitelisted. Alternatively, add https://api.truintel.ai to your script-src allowlist.


Troubleshooting

IssueCauseSolution
No data appears in dashboardWrong Brand ID or script not loadingCheck DevTools → Console for errors. Verify Brand ID matches Settings → Integrations. Ensure both script tags are present.
Script loads but no beacon sentwindow.TruIntel config missing or loads after tracker.jsThe config script must be placed BEFORE the tracker script tag. In Next.js, use beforeInteractive for config.
CSP error in consoleContent Security Policy blocks tracker script or API callsAdd https://api.truintel.ai to script-src and connect-src in your CSP header.
Ad blocker blocks trackerBrowser ad blocker or privacy extension blocks third-party scriptsExpected behavior — ad-blocked visitors won't be tracked client-side. Server-side middleware still catches bots. Human traffic from ad-block users is typically 10-15%.
Double-counted pageviewsScript loaded twice (e.g., in both layout and page component)Ensure the tracker script is loaded only ONCE at the root layout level. Check React StrictMode (dev only — not an issue in production).
Static assets appearing as visitsServer-side middleware runs on image/CSS/JS requestsAdd path exclusions to your middleware. In Next.js, use the matcher config. In Express, check req.path for file extensions before calling isBot().
Server-side events not appearingMiddleware not registered or API endpoint wrongVerify the middleware is in your middleware chain. The endpoint is /api/v1/i/e (not /api/v1/traffic/middleware). Test with the curl command above.
All traffic shows as BOTServer behind a proxy that strips User-Agent headersEnsure your reverse proxy (Nginx, Cloudflare) forwards the original User-Agent header. Check X-Forwarded-For is set for correct IP attribution.
CORS errors in consoleBrowser blocks cross-origin API requestThe tracker uses fire-and-forget beacons — CORS should not apply. If you see CORS errors, verify you're using the async script tag, not a direct fetch() call.
Rate limit errors (429)More than 30 requests/minute from a single IPThis usually indicates a bot loop or misconfigured middleware. The collect endpoint allows 30 requests/minute per IP and returns Retry-After and X-RateLimit-* headers. Check for recursive middleware calls or scripts that re-inject themselves.

Edge Cases

ScenarioSolution
Single-page app (SPA) with client-side routingThe tracker automatically detects pushState/popstate route changes. No extra config needed for React Router, Vue Router, Next.js, etc.
Server-side rendering (SSR) / Static site generation (SSG)The client-side script runs only in the browser — SSR-rendered pages won't cause double tracking. Server-side middleware catches bots during SSR requests.
Behind Cloudflare / CDN / reverse proxyEnsure the proxy forwards the original User-Agent and X-Forwarded-For headers. Cloudflare does this by default. Cached CDN responses won't trigger middleware, which is correct behavior.
Behind Vercel / Netlify / similar platformNext.js middleware runs on the edge (before cache). Vercel automatically provides the real IP via x-forwarded-for. No extra config needed.
Multiple brands on one domain (e.g., /brand-a, /brand-b)Use different Brand IDs for each section. Set window.TruIntel.brandId dynamically based on the URL path. For middleware, use the URL path to determine which Brand ID to send.
Subdomains (blog.yoursite.com, app.yoursite.com)Each subdomain can use the same or different Brand ID. Install the script separately on each subdomain. Middleware runs per-deployment, so deploy it on each subdomain's server.
TypeScript strict mode (no window.TruIntel)Add a type declaration: declare global { interface Window { TruIntel?: { brandId: string; apiUrl: string } } } in a .d.ts file or at the top of your component.
Google Tag Manager (GTM)Add both script tags as a Custom HTML tag in GTM. Set the trigger to "All Pages" with firing priority higher than other tags. Alternatively, paste directly in your HTML for more reliable loading.
Iframes / embedded contentThe tracker runs in the parent page context. Content inside iframes on a different origin will not be tracked. Same-origin iframes may be tracked — add data-ti-ignore to the iframe to exclude it.
Testing in development (localhost)The tracker works on localhost. Traffic from localhost appears in your dashboard labeled with the localhost origin. Use this to verify your installation before deploying to production.

Privacy & Performance

Data CategoryCollectedNOT Collected
IdentityRandom session/visitor UUIDs (stored in first-party cookies)Names, emails, phone numbers, login credentials (by the traffic classifier)
BrowsingPage path + query on your domain, referrer domainBrowsing history, cross-site tracking
DeviceBrowser type, OS, screen resolution, timezone, device type, country (geo of IP)Precise geolocation; IP is used for geo/rate-limit, not stored on the log as a long-term identity
BehaviorMouse/touch movement patterns, scroll depth, click timingKeystrokes, passwords, clipboard content, screenshots
NetworkUser-agent string, connection typeCross-site cookies, third-party storage, session tokens

Cookies, form data & lead capture — read this

The tracker is NOT cookieless. It sets two first-party cookies on your own domain: _ti_vid (a 365-day visitor identifier) and _ti_sid (a ~30-minute session identifier), plus localStorage/sessionStorage dedup keys. Separately, the same script bundles optional lead-capture that listens to contact-form submissions and reads submitted values (email, name, company, phone, message) to power Lead Verification — email is PII. It SKIPS auth/login/password forms and any form marked data-ti-ignore, and never blocks the user submit. The traffic classification feature on its own collects no PII; the lead-capture does. Disable lead-capture or mark forms with data-ti-ignore if you do not want this.

  • Script size: ~4 KB gzipped (loads async, non-blocking)
  • Beacon size: ~200 bytes per event (fire-and-forget POST), one beacon per session — fired at 30s or on page exit
  • Rate limit: 30 requests/minute per IP on the collect endpoint (returns Retry-After + X-RateLimit-* headers)
  • Do Not Track is a hard opt-out: if the browser sets DNT=1, the tracker sends nothing at all
  • First-party cookies only (_ti_vid 365 days, _ti_sid ~30 min) — no third-party or cross-site tracking
  • No impact on Core Web Vitals (LCP, FID, CLS) — verified via Lighthouse
  • Server-side middleware adds 0ms latency — API call runs asynchronously in background

GDPR & Compliance

Visitor IDs are randomly generated UUIDs that cannot be traced back to individuals, and Do Not Track is honored as a hard opt-out (DNT=1 means nothing is sent). However, the tracker DOES set first-party cookies (_ti_vid is a persistent 365-day identifier) and the bundled lead-capture reads contact-form values such as email, so this is not a strictly cookieless or PII-free deployment. Treat it like first-party analytics: depending on your jurisdiction you may need cookie consent and a privacy-policy disclosure. If your legal team requires explicit consent, wrap the script tags in your consent management flow and use data-ti-ignore on forms you do not want read.

Dashboard & Analytics

The Traffic Intelligence dashboard (GROW ▸ Traffic Analysis, route /traffic) gives you real-time visibility into who visits your site. A time-range selector at the top switches every card between 24 Hours, 7 Days, and 30 Days; a Refresh button re-pulls the data and an Install Script button opens the multi-framework install modal.

Plan gating

The Traffic Intelligence dashboard, custom rules, and the Pattern Catalog require a paid plan (Starter and above) — Free accounts receive a 403. The tracking itself is not plan-gated: the script, the collect endpoints, and the install snippet work for any existing brand, including a Free brand. The net effect is that a Free brand can embed the tracker but cannot view results until it upgrades.

Live Traffic Feed

Real-time stream of the last N minutes of visitors (polls /recent), with classification, device, and country.

Agent Breakdown

AI-agent visits grouped by company (OpenAI, Anthropic, Google, Perplexity, Meta, Microsoft, xAI, …) with category and share.

Traffic Trends

Zero-filled daily time series of total / human / agent / bot / synthetic visits over the selected range.

Threat Analysis

BAD_BOT and SYNTHETIC threats grouped by source, with blocked/flagged counts and per-bot severity (low–critical).

Alongside these, the dashboard surfaces an Overview metric strip (totals, percentages, and period-over-period change), a Classification donut, and a paginated Visitor Log you can filter by classification and action. The Rules Manager edits your brand whitelist/blacklist, and the Pattern Catalog browser lets you explore the 93 known agents and 55 known bots.

Analytics endpoints

Overview

GET /traffic/{brand_id}/overview

Totals, percentages, and period-over-period change. days 1–90 (default 7), cached 60s.

Visitor logs

GET /traffic/{brand_id}/logs

Paginated visitor log; filter by classification and action. Limit 1–100 (default 50) + offset.

Agent breakdown

GET /traffic/{brand_id}/agents

AI agents grouped by company, with category and share. days default 30, cached 5 min.

Threats

GET /traffic/{brand_id}/threats

BAD_BOT + SYNTHETIC by source, with blocked/flagged counts. days default 30, cached 5 min.

Trends

GET /traffic/{brand_id}/trends

Zero-filled daily time series. days default 30, cached 10 min.

Recent feed

GET /traffic/{brand_id}/recent

Real-time feed of the last N minutes. minutes 1–60 (default 10).

Rules (read/replace)

GET / PUT /traffic/{brand_id}/rules

List or replace-all whitelist/blacklist rules; PUT invalidates the cache.

Pattern Catalog

GET /traffic/patterns

All 93 known agents + 55 known bots and their category lists (paid plans).

Data retention

Individual visitor rows are kept for 30 days, then purged by a weekly cleanup (Sundays at 04:00 IST). Daily aggregates are kept indefinitely, so long-term trends, totals, and agent breakdowns survive even though the raw per-visit log only goes back 30 days. Retention is a flat 30 days of raw logs for every plan — there is no per-plan retention tier.

Why same-day numbers can shift

Real-time stats are incremented as beacons arrive, but a daily aggregation job re-computes the previous day from scratch at 03:00 IST to self-heal any missed increments. As a result, yesterday's totals can adjust slightly after midnight IST — this is expected.

Session & visit model

  • One beacon per session — the tracker fires once, at 30 seconds or on page exit (visibilitychange/pagehide/beforeunload), with same-tab and cross-tab dedup.
  • Session window is ~30 minutes (_ti_sid cookie); the visitor identifier persists for 365 days (_ti_vid cookie).
  • Each visit records device type (desktop / mobile / tablet) and a best-effort 2-letter country from the IP (non-blocking geo lookup).
  • Redis dedup returns the cached classification for a repeated {brand_id, session_id} for 30 minutes without re-queuing a write.

Ingestion endpoints

Two public, no-auth endpoints feed the single classifier. The client tracker uses the descriptive path; the server middleware uses a short alias specifically so privacy/ad-blocker extensions do not strip it (the words "traffic" and "collect" are common blocklist triggers).

Client collect

POST /api/v1/traffic/collect

Main ingestion from tracker.js. Classifies in-process, queues the DB write, returns the result immediately.

Middleware alias

POST /api/v1/i/e

Ad-blocker-safe alias of /collect (same handler). Used by the server-side middleware snippets.

Install snippet

GET /api/v1/traffic/snippet/{brand_id}

Returns a ready-to-paste HTML install snippet for a brand (404 if the brand does not exist).

Tracker script

GET /api/v1/traffic/tracker.js

Serves the JavaScript tracker (Cache-Control public, max-age 3600).

Lead Verification

Installation

TruIntel's lead verification works by automatically intercepting form submissions on your website. A single script detects all <form> elements, captures submission data along with behavioral signals, and scores each lead in real time. No backend changes are required — the same tracker script used for traffic classification also handles lead verification.

One script, two features

If you've already installed the TruIntel tracker script for Traffic Classification, lead verification is already active. The same script handles both traffic tracking and form interception. No additional installation is needed — just verify that forms are being detected on the Leads page.

How It Works

Auto-Detects Forms

Finds every <form> that contains an email field, including forms added dynamically after page load (via MutationObserver). Forms without an email field are never tracked.

Captures Behavior

Records scroll events, mouse movements, keystrokes, touch events, and form-fill time (first focus to submit) before submission. The submit listener is passive — your form submits normally.

Scores in Real-Time

Deterministic Python scoring (no LLM, no external API, $0 per verification) across Behavior, Email, Identity, Source, and Device. Returns a 0-100 human score within milliseconds.

Zero Interruption

The form still submits normally to your backend. The listener is registered passive (cannot call preventDefault), so capture never blocks or alters your submission.

What Data Is Captured

The tracker reads form values through an explicit allowlist of CSS selectors — it only ever reads the specific contact fields below. Everything else (passwords, payment fields, hidden inputs, files) is simply never accessed. Behavioral counters and a few request metadata fields are sent alongside.

Data PointSourceScored?
email (required — nothing is sent if empty)Email input (allowlist selector)Email dimension (regex + disposable / suspicious-TLD / free-provider lists)
name (or first_name + last_name)Name input (allowlist selector)Identity dimension
company, phone, subject, messageAllowlist selectors onlyIdentity (company, phone); message/subject stored, not scored
mouse_movements, scroll_events, key_events, touch_eventsDocument-level event countersBehavior dimension
form_submit_time (first focus to submit, seconds)Tracker timer per formBehavior dimension
time_on_page, click_eventsTracker countersCaptured and sent but NOT used in the score
referrer / source, page (pathname+search)Browser location & referrerSource dimension (referrer/source only)
user_agentBrowserDevice dimension (User-Agent string only)
session_idTracker sessionLinks to traffic classification for a behavior +20 / -30 adjustment
honeypot_valueHidden/offscreen filled fieldIf non-empty -> instant REJECTED (score 0)

Allowlist capture — passwords are never even read

The tracker does not have an exclusion list; it has an allowlist. It only reads email, name, company, phone, subject, and message via specific selectors. Password fields, credit-card fields, SSN fields, hidden inputs, and file inputs are never accessed, so their values can never be transmitted. There is no credit-card pattern-matching or redaction code — those fields are simply not in the allowlist.

Do Not Track is respected

If the browser sends navigator.doNotTrack === "1", the script returns immediately and does nothing — no traffic beacon and no form capture. Honoring DNT is built in and cannot be overridden.

Installation Steps

1

Find your Brand ID

Go to Settings → Integrations in your TruIntel dashboard. Copy the Brand ID shown under your brand.

2

Install the tracking script

Choose your framework below and paste the snippet. The script must load on every page that has forms you want to track. If you've already installed it for Traffic Classification, skip this step.

3

Submit a test form

Fill out a form on your site with realistic data (real email, full name). Submit it and check the Leads page in TruIntel — the submission should appear within a few seconds with a score and status.

4

Review the score breakdown

Click on the test lead in TruIntel to see the full score breakdown: email analysis, behavior signals, identity match, traffic source quality, and device reputation.

Script Installation

This is the same script used for Traffic Classification. If you've already installed it, lead verification is already active.

HTML

Paste inside the <head> tag on every page that has forms you want to track.

index.html
<!-- TruIntel Lead Verification -->
<script>
  window.TruIntel = {
    brandId: 'YOUR_BRAND_ID',
    apiUrl: 'https://api.truintel.ai/api/v1'
  };
</script>
<script async src="https://api.truintel.ai/api/v1/traffic/tracker.js"></script>

React

Add once in your App.tsx or root layout component. The tracker persists across route changes and detects dynamically rendered forms.

TruIntelTracker.tsx
import { useEffect } from 'react';

export function TruIntelTracker() {
  useEffect(() => {
    window.TruIntel = {
      brandId: 'YOUR_BRAND_ID',
      apiUrl: 'https://api.truintel.ai/api/v1'
    };
    const s = document.createElement('script');
    s.async = true;
    s.src = 'https://api.truintel.ai/api/v1/traffic/tracker.js';
    document.head.appendChild(s);
    return () => { document.head.removeChild(s); };
  }, []);
  return null;
}

// Usage: <TruIntelTracker />

Next.js

Add to your root layout (app/layout.tsx for App Router, _app.tsx for Pages Router).

app/layout.tsx
import Script from 'next/script';

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        <Script id="truintel-config" strategy="beforeInteractive"
          dangerouslySetInnerHTML={{
            __html: `window.TruIntel={brandId:'YOUR_BRAND_ID',apiUrl:'https://api.truintel.ai/api/v1'};`,
          }} />
        <Script src="https://api.truintel.ai/api/v1/traffic/tracker.js"
          strategy="afterInteractive" />
      </head>
      <body>{children}</body>
    </html>
  );
}

Vue

Add to your root App.vue or main entry component.

App.vue
<script setup>
import { onMounted, onUnmounted } from 'vue';

let script = null;

onMounted(() => {
  window.TruIntel = {
    brandId: 'YOUR_BRAND_ID',
    apiUrl: 'https://api.truintel.ai/api/v1'
  };
  script = document.createElement('script');
  script.async = true;
  script.src = 'https://api.truintel.ai/api/v1/traffic/tracker.js';
  document.head.appendChild(script);
});

onUnmounted(() => {
  if (script) document.head.removeChild(script);
});
</script>

Nuxt

Add to your nuxt.config.ts to inject the script globally on every page.

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      script: [
        {
          innerHTML: "window.TruIntel={brandId:'YOUR_BRAND_ID',apiUrl:'https://api.truintel.ai/api/v1'};",
        },
        {
          src: 'https://api.truintel.ai/api/v1/traffic/tracker.js',
          async: true,
        },
      ],
    },
  },
});

Angular

Add to src/index.html inside the <head> tag.

src/index.html
<!-- Inside <head> -->
<script>
  window.TruIntel = {
    brandId: 'YOUR_BRAND_ID',
    apiUrl: 'https://api.truintel.ai/api/v1'
  };
</script>
<script async src="https://api.truintel.ai/api/v1/traffic/tracker.js"></script>

Svelte / SvelteKit

Add to src/app.html inside the <head> tag, or use <svelte:head> in your root layout.

src/routes/+layout.svelte
<svelte:head>
  {@html `<script>window.TruIntel={brandId:'YOUR_BRAND_ID',apiUrl:'https://api.truintel.ai/api/v1'};</script>`}
  {@html `<script async src="https://api.truintel.ai/api/v1/traffic/tracker.js"></script>`}
</svelte:head>

WordPress

Add to your theme's functions.php, or use a plugin like "Insert Headers and Footers" or "WPCode" to inject without editing theme files.

functions.php
// Add to your theme's functions.php
add_action('wp_head', function() {
  ?>
  <script>
    window.TruIntel = {
      brandId: 'YOUR_BRAND_ID',
      apiUrl: 'https://api.truintel.ai/api/v1'
    };
  </script>
  <script async src="https://api.truintel.ai/api/v1/traffic/tracker.js"></script>
  <?php
});

Script Load Order

Replace YOUR_BRAND_ID with your actual Brand ID from Settings → Integrations. The config object (window.TruIntel) must load before the tracker script — otherwise forms will not be tracked.


Excluding Forms

A form is hooked only if it (a) contains an email field, (b) is not an auth/login form, and (c) does not carry the data-ti-ignore attribute. To exclude any other form from being tracked, add data-ti-ignore to the <form> element.

Email field is required

TruIntel only hooks forms that contain an email field (an input[type=email], or a name/id/placeholder containing "email"). Search forms, filter forms, and any form with no email input are never tracked — regardless of method or markup.

example.html
<!-- This form will NOT be tracked -->
<form action="/login" method="POST" data-ti-ignore>
  <input type="email" name="email" />
  <input type="password" name="password" />
  <button type="submit">Log in</button>
</form>

<!-- This form WILL be tracked -->
<form action="/contact" method="POST">
  <input type="text" name="name" placeholder="Full name" />
  <input type="email" name="email" placeholder="Work email" />
  <textarea name="message"></textarea>
  <button type="submit">Send</button>
</form>
Form TypeAuto-BehaviorAction Needed
Contact / inquiry forms (with email)Tracked automaticallyNone — these are your leads
Login / sign-in / password-reset formsAuto-skipped (keyword + password-field heuristic)None
Registration / sign-up forms (with email)Tracked automaticallyAdd data-ti-ignore if you do not want sign-up tracking
Search / filter forms (no email field)Never tracked (no email field)None
Newsletter forms with an email fieldTracked automaticallyAdd data-ti-ignore to exclude
Internal admin forms (with email)Tracked automaticallyAdd data-ti-ignore to exclude
Checkout / payment formsOnly the email field is read; payment fields are never accessedAdd data-ti-ignore for belt-and-braces exclusion
Forms with no email fieldNever trackedNone

Auto-skipped patterns (exact)

A form is treated as an auth form (and skipped) if its action + id + className combined contains any of: login, signin, sign-in, log-in, auth, password-reset, forgot-password. It is ALSO skipped if it has a password-type field and 2 or fewer non-checkbox/radio fields. You only need data-ti-ignore for other forms you want to exclude.


Edge Cases & Advanced Scenarios

ScenarioHow TruIntel Handles It
Dynamically rendered forms (React, Vue, Angular)The tracker uses MutationObserver to detect forms added to the DOM after initial page load. Forms rendered by JavaScript frameworks are detected automatically — no extra config needed.
AJAX / fetch-based form submissionsIf your form uses preventDefault() and submits via fetch/axios, TruIntel's submit event listener fires first and captures the data. The form data is captured regardless of how the submission is handled.
Multi-step / wizard formsTruIntel captures the final submission (the actual form submit event). Intermediate "Next" buttons that don't trigger a form submit are not tracked. If each step is a separate <form>, each submission is tracked individually.
Forms inside modals or drawersForms in modals, popups, slide-out drawers, and dialog elements are detected when they're added to the DOM. Works with all UI libraries (Material UI, Chakra, Radix, Headless UI, etc.).
Third-party form builders (HubSpot, Typeform, Jotform)Embedded iframes from third-party builders cannot be tracked (cross-origin restriction). HubSpot forms embedded as JavaScript (not iframe) may be detected. For best results, use native HTML forms.
File upload forms (multipart/form-data)File inputs are never read at all. No file contents, no filename, and no file size are captured — only the allowlisted contact fields are read.
Forms submitted by pressing EnterEnter-key submissions trigger the same submit event as clicking a button. They are tracked identically.
Multiple forms on one pageEach form is tracked independently. If a page has a contact form, newsletter signup, and search form, each gets its own score and lead entry when submitted.
SPA route changesThe tracker re-scans for forms on every route change (detects pushState/popstate). Forms on dynamically loaded pages are found automatically.
Forms with custom validation (e.g., Zod, Yup)The tracker listens for the native submit event. If validation prevents the form from submitting (e.preventDefault without re-dispatching), the submission is not tracked. If the form eventually submits, it's tracked normally.
Honeypot fields for spam preventionDedicated detection: the tracker looks for a visually hidden / offscreen input that got filled (display:none, visibility:hidden, opacity:0, or positioned < -5000px) and sends it as honeypot_value. If it is non-empty, the server instant-rejects the lead — human_score 0, all dimensions 0, status REJECTED — overriding every other signal.
reCAPTCHA / hCaptcha formsCAPTCHA widgets don't interfere with form tracking. The tracker captures form data on submit, regardless of CAPTCHA status.

Troubleshooting

IssueCauseSolution
Form submissions not appearing in Leads pageScript not loading, wrong Brand ID, or form has data-ti-ignoreCheck DevTools → Network for tracker.js. Verify Brand ID. Remove data-ti-ignore if accidentally added. Ensure the form has a submit event (not just a button click handler).
Score shows 0 for all leadsForm submitted too quickly (bot-like behavior) or from localhostSubmit the form naturally: spend 10+ seconds on the page, move the mouse, scroll, then fill the form slowly. Localhost submissions may score low due to missing referrer data.
Duplicate lead entriesForm submits twice (double-click or script re-injection)Ensure the tracker script is loaded only once. Check for double form submission in your own code. React StrictMode causes double mounts in dev only — not an issue in production.
Login forms being tracked despite auto-skipForm action URL doesn't match auto-skip patternsAdd data-ti-ignore to the form element manually. The auto-skip only catches common patterns like /login, /signin, /auth.
Unexpected field appearing in lead detailsA custom field matched an allowlist selector (e.g. an input whose name/id/placeholder contains "email", "name", "company", "phone", "subject")Rename the field so it does not collide with the allowlisted keywords, or add data-ti-ignore to the whole form. Only the six allowlisted contact fields are ever read.
Third-party iframe form not trackedCross-origin iframe restrictionForms inside iframes from different domains cannot be accessed by the tracker (browser security policy). Use the provider's native webhook integration or TruIntel's API endpoint to submit lead data directly.
Form tracked but fields are emptyForm uses a non-standard submission pattern (e.g., FormData API with no DOM elements)The tracker reads values from form input elements at submit time. If your form uses virtual/controlled inputs without DOM form elements, consider using TruIntel's API endpoint to submit lead data directly.
Lead score seems inaccurateInsufficient behavioral data or disposable email usedEnsure the tracker script loads early (in <head>) so it captures the full session behavior. Test with a real business email — disposable email providers (mailinator, guerrillamail) receive low email scores.

Privacy & Sensitive Data

  • Allowlist capture: only email, name, company, phone, subject, and message are ever read. Passwords, payment fields, SSN fields, hidden inputs, and files are never accessed — there is no exclusion list to maintain and no credit-card pattern-matching/redaction code (those fields are simply never read).
  • File inputs are never read — no contents, no filename, no file size are captured.
  • Do Not Track is honored: if navigator.doNotTrack === "1" the tracker no-ops entirely (no traffic beacon, no form capture).
  • Cookies ARE set: a persistent visitor cookie _ti_vid (365 days) and a session cookie _ti_sid (about 30 minutes), plus localStorage/sessionStorage for de-duplication. Account for these in your cookie/privacy notice.
  • All data is transmitted over HTTPS. (TLS-version and at-rest-encryption specifics are infrastructure guarantees, not enforced in product code — confirm with your DPA rather than treating them as a product setting.)
  • Retention: lead rows are kept indefinitely (until the brand is deleted, which cascade-deletes them). There is no automatic 90-day purge and no Settings -> Data Retention control. LeadStats daily rollups are kept forever. (Only separate traffic logs are purged after 30 days.)
  • No deduplication: every submission creates a new lead. The API response field is_duplicate is always false.
  • GDPR: lead data contains PII (email, name, phone). The lawful basis (e.g. legitimate interest) is a legal stance for your team to set — TruIntel does not assert one in code.

Payment & checkout forms

The tracker never reads payment fields (it only reads the six allowlisted contact fields), so card data cannot be captured. As defence-in-depth, you can still add data-ti-ignore to checkout/payment forms — though if a payment form has no email input it is never hooked in the first place.

Lead Scoring Formula

Every form submission receives a human score (0-100) — a deterministic weighted average of five dimensions, computed in pure Python with no LLM and no external API call. Final score = round(email x 0.25 + behavior x 0.40 + identity x 0.15 + source x 0.10 + device x 0.10). A filled honeypot overrides everything and forces score 0.

Human Score

40%
25%
15%
10%
10%
Behavior (40%)
Email (25%)
Identity (15%)
Source (10%)
Device (10%)
DimensionWeightWhat is actually analyzed
Behavior40%Mouse movements, scroll events, keystrokes, touch events, form-fill time; plus a +20 / -30 adjustment from linked traffic classification. (time_on_page and click_events are captured but not scored.)
Email25%Regex format check + static lists: disposable-domain, suspicious-TLD, and free-provider sets. No MX/DNS lookup, no live reputation service.
Identity15%Name present / full name, company present, phone digit count. No name-consistency, company-domain match, or social-presence lookups.
Source10%Referrer/source string matched to AI / organic / social / direct / unknown buckets. No UTM parsing, landing-page relevance, or session history.
Device10%User-Agent string only: headless / bot / standard-browser detection. No canvas fingerprint, screen resolution, or timezone in the lead device score.

Deterministic and free

Lead scoring is synchronous text-parsing — it returns the score in the API response immediately and costs $0 per verification. The database write is queued asynchronously via Celery, so submissions survive page navigation.

Email dimension bands (25%)

ConditionScore
Invalid format (regex fails)0 (high risk)
Disposable domain (static list, ~34 domains)0 (critical)
Suspicious TLD (static list, 20 TLDs)30 (medium)
Free provider (Gmail/Yahoo/etc., ~26 domains)65
Business email (custom domain)100
Unknown (none of the above)50

Behavior dimension bands (40%)

SignalBands -> score
Mouse movements>20 -> 100; 5-20 -> 60; <5 -> 20
Scroll events>5 -> 100; 1-5 -> 60; 0 -> 30
Key events (typing)>10 -> 100; 1-10 -> 50; 0 -> 20
Form-fill time (sec)>30 -> 100; 10-30 -> 70; 3-10 -> 40; <3 -> 10
Touch events>0 adds a 100 to the average (mobile bonus)
Traffic cross-referenceLinked session HUMAN -> +20 (cap 100); BAD_BOT/SYNTHETIC -> -30 (floor 0)

Identity, Source & Device bands

DimensionRule
IdentityBase 50; full name (space, length >=5) +25, else any name +10, no name -10; company (length >=2) +15; phone (>=10 digits) +10; clamped 0-100.
SourceAI platform 95; organic search 85; social 80; direct/empty 60; unknown 50 (first match wins). Note: google.com/search & bing.com/search fall in the AI-platform set, so an organic search referrer can score 95.
DeviceHeadless indicators (selenium/puppeteer/webdriver/etc.) 0; bot indicators (bot/crawler/curl/python-requests/etc.) 10; standard browser 80; empty/unknown UA 50.

Status Thresholds

Leads are automatically categorized into three status levels based on their score:

API statusScoreDashboard labelAction recommended
VERIFIED80-100VerifiedHigh confidence — route directly to sales
REVIEW50-79SuspiciousModerate confidence — manual review recommended
REJECTED0-49SpamLow confidence — likely fake or bot submission

Honeypot overrides the bands

A filled honeypot field forces human_score 0 and status REJECTED regardless of the dimension scores. The thresholds above only apply when the honeypot is empty.

Note the wording difference: the API enum is VERIFIED / REVIEW / REJECTED, while the in-app dashboard relabels them Verified / Suspicious / Spam. They are the same three statuses. verified_at is stamped when a lead becomes VERIFIED.

Leads Dashboard

The in-app Lead Verification dashboard lives at /leads and is a paid feature (Starter and above). Free orgs get a 403 (PAID_PLAN_REQUIRED) — the public scoring endpoint and tracker script still work for any brand. The dashboard has 7 / 30 / 90-day period tabs.

Overview stats

Five metrics: Total Leads, Verified, Suspicious (REVIEW), Spam (REJECTED), and Avg Score, with period-over-period change.

Score distribution

Histogram bucketed 0-20, 21-40, 41-60, 61-80, 81-100, plus a Verified / Review / Rejected status donut.

Trends & sources

Daily verified/review/rejected area chart and a Source Performance table (source, leads, verified, avg score, share).

Lead list & detail

Search by name/email/company, status + min/max score + date filters, 20 per page. Row click opens /leads/:id with the full dimension breakdown, signals, risk factors, and recommendation.

Manual override & bulk

Override a single lead status, or bulk Mark as Verified / Mark as Spam (up to 100 IDs).

CSV export

Export filtered leads to CSV (up to 10,000 rows) for CRM import.

Daily stat recomputation

LeadStats are updated incrementally on every write and fully recomputed each day. The lead.run_daily_aggregation cron runs at 03:30 IST (Asia/Kolkata) and recomputes yesterday's stats for all brands from raw lead rows, so totals stay correct even if an incremental update was missed.

API Integration

You can score a submission directly without the tracker by POSTing to the public verify endpoint. It requires no JWT (it validates that brand_id exists), is CORS-open, and is rate-limited to 20 requests/minute per client IP (a 429 with Retry-After is returned when exceeded). The request field for the page is page, not page_url.

API Endpoint
POST https://api.truintel.ai/api/v1/leads/verify

# Rate limit: 20 requests/minute per IP
# No authentication required (validates brand_id exists)

# Request body:
{
  "brand_id": "your-brand-id",
  "email": "[email protected]",
  "name": "John Doe",
  "company": "Acme Inc",
  "phone": "+1234567890",
  "message": "Interested in a demo",
  "subject": "Demo request",
  "page": "/contact",
  "referrer": "https://google.com",
  "source": "Organic",
  "user_agent": "Mozilla/5.0 ...",
  "session_id": "abc-123",
  "behavior": {
    "mouse_movements": 42,
    "scroll_events": 8,
    "key_events": 25,
    "click_events": 3,
    "touch_events": 0,
    "time_on_page": 35,
    "form_submit_time": 22
  },
  "honeypot_value": ""
}

Passing a session_id that matches a prior traffic beacon links the lead to its traffic classification and applies the behavior +20 / -30 adjustment automatically — a free accuracy boost for raw API callers. honeypot_value left empty scores normally; any non-empty value instant-rejects.

Response
{
  "success": true,
  "data": {
    "human_score": 85,
    "status": "VERIFIED",
    "scores": { "email": 100, "behavior": 80, "identity": 75, "source": 85, "device": 80 },
    "signals": ["..."],
    "risk_factors": ["..."],
    "recommendation": "High-quality lead. Contact immediately.",
    "lead_id": "generated-uuid",
    "is_duplicate": false
  },
  "message": "..."
}

No dedup, async write

Every call creates a new lead — is_duplicate is always false (there is no server-side deduplication). The lead_id is generated and returned immediately; the database row is written asynchronously via Celery, so the response is never blocked on the DB write.

No enforced monthly cap

A per-plan lead_verifications_monthly value exists in config (Free 0, Starter 200, Lite 1000, Pro 2000, Enterprise 5000) but it is NOT enforced anywhere in code. The only live throttle on the verify endpoint is 20 requests/minute per IP. Do not rely on a hard monthly verification ceiling.

Authenticated dashboard endpoints

These power the in-app dashboard. All require a JWT and a paid plan, and all verify the brand belongs to the caller's org. Prefix /api/v1.

Verify (public)

POST /leads/verify

Score a submission. Public, no auth, 20/min/IP. OPTIONS preflight supported.

Tracker script

GET /traffic/tracker.js

Serves the shared tracking.js (cached public, max-age 3600). Same script handles traffic + leads.

Overview

GET /leads/{brand_id}/overview

Totals, percentages, avg score, period change, top sources (cached ~2 min).

List

GET /leads/{brand_id}

Paginated, filterable by status, min/max score, date range, and search.

Detail

GET /leads/{brand_id}/detail/{lead_id}

Full dimension breakdown, signals, risk factors, recommendation, metadata.

Status override

PATCH /leads/{brand_id}/status/{lead_id}

Manually override a single lead status.

Bulk status

POST /leads/{brand_id}/bulk-status

Bulk update up to 100 lead IDs.

Score distribution

GET /leads/{brand_id}/score-distribution

Global bucket counts for the histogram.

Trends

GET /leads/{brand_id}/trends

Daily series (up to 90 days), zero-filled (cached ~5 min).

Sources

GET /leads/{brand_id}/sources

Source-level breakdown.

CSV export

GET /leads/{brand_id}/export

Export filtered leads as CSV (up to 10,000 rows).

The API returns a score, status, and detailed signal breakdown. Use the public endpoint to pre-filter submissions before they reach your CRM, and the authenticated endpoints to read, override, and export leads.

SERP Simulator

Overview

The SERP Simulator is a 100% client-side Google search-snippet preview and SEO snippet scorer. You type (or auto-fetch) a page title, meta description, URL, and keywords, and watch a pixel-accurate Google search result update live — alongside a 0-100 snippet score, a position-based click-through estimate, rich-snippet mockups, and one-click exports. There is no AI model, no backend call, no credit cost, and no plan limit.

Free for everyone, no credits, no backend

The simulator runs entirely in your browser. It does not call the TruIntel API, does not spend AI credits, and is available on every plan including Free. The public, no-login version lives at truintel.ai/serp-preview-tool.

Live Google Preview

A pixel-accurate Google search result (desktop and mobile) updates as you type your title, description, and URL.

10-Factor SEO Score

A 0-100 snippet score across 10 weighted content and keyword factors, with a per-factor breakdown.

CTR & Clicks Estimate

A separate position-based estimate of organic click-through rate and projected monthly clicks.

Rich Snippets

Preview FAQ, Product, Recipe, Event, How-To, Video, and Sitelink rich-snippet treatments live.

Competitor Comparison

Add up to 10 sites and drag them across SERP positions 1-10 to model the full results page.

Meta Fetcher & Export

Auto-populate fields from any URL, then export Copy HTML (meta + JSON-LD), Copy JSON, or a PNG screenshot.

Google only

The on-screen preview renders Google search results exclusively. Earlier descriptions of Bing and on-screen social previews are no longer accurate — those code paths are not rendered. Open Graph and Twitter Card tags are still produced, but only inside the Copy HTML export.

Where to Find It & Access

The exact same tool ships in two places: an in-app tool for logged-in users and a fully public marketing tool. Both share the same component, so the editing experience is identical.

DeploymentWhereAccessNotes
In-app toolLaunched from the Tools landing page; route /tools/serp-simulatorAny logged-in user, every plan including FreeOpens fullscreen with no app sidebar or header
Public tooltruintel.ai/serp-preview-toolFully public, no login requiredAdds marketing copy and a lead-capture promo modal that appears after 10 seconds

SERP Simulator (in-app)

/tools/serp-simulator

Fullscreen tool for logged-in users; launched from the /tools landing page.

SERP Preview Tool (public)

/serp-preview-tool

Public, no-login marketing version of the identical simulator.

No plan gating

The in-app tool is protected only by login — there is no feature gate, no credit cost, and no per-org budget. Free, Starter, Lite, Pro, and Enterprise users all get the full tool. If you are not logged in, use the public /serp-preview-tool instead.

The 7 Editor Tabs

The editor panel is organized into seven tabs. (There is no separate "Keywords" or "Advanced settings" tab — keywords live inside Basic Info, and multi-site positioning lives in the Ranking tab.)

#TabWhat it does
1Basic InfoPage URL + meta Fetch, Site Name, Favicon URL, SEO Title, Meta Description, and Bold Keywords
2SERP FeaturesSeven toggles for SERP feature blocks and badges (AI Overview, Ads, PAA, Map Pack, PASF, Verified Badge, Heatmap)
3Rich SnippetSix schema rich-snippet types plus four "extras" decorations, each with its own enable toggle
4MediaA video snippet OR thumbnail images (the two are mutually exclusive)
5RankingDrag-reorder your and competitor sites across SERP positions 1-10
6SEO ScoreThe 0-100 snippet score, a 10-factor breakdown, and the CTR / clicks estimate
7LibrarySave, load, and delete snippets from your browser (localStorage)

Basic Info

  • Page URL + Fetch button — runs the 3-layer meta fetcher to auto-populate fields.
  • Site Name and Favicon URL — with a live favicon preview; leave Favicon blank to auto-detect via the Google favicon service.
  • SEO Title — a live character count and a pixel-width meter that warns when the title may truncate. Guidance: under 50 chars "Aim for 50-60", 50-60 "Ideal length", over 60 "May truncate".
  • Meta Description — the same live count and pixel meter, targeting 150-160 characters.
  • Bold Keywords — add keyword chips (Enter or +); they are bolded inside the preview snippet and feed the SEO score.

SERP Features (7 toggles)

Toggle which SERP feature blocks appear in the simulated results page: AI Overview, Ads Block, People Also Ask, Map Pack, People Also Search For, Verified Badge, and Attention Heatmap (an F-pattern overlay on the top three results). The first five render as static reference screenshots injected into the result list; the heatmap renders as a graduated overlay on positions 1-3.

Rich Snippet

Pill sub-tabs offer six schema snippet types — FAQ, Product, Recipe, Event, How-To, and Sitelinks ("Standard" means none; Video lives in the Media tab) — plus four "extras" decorations you can layer on:

  • Rating — a 1-5 star slider with review count and a store/seller label.
  • Price — a price range plus comma-separated green benefit labels.
  • Extensions — sitelink-extension text links beneath the result.
  • Date — a date-prefix string such as "3 days ago".

Sitelinks are capped at 6 entries; FAQ and How-To items are add/remove lists.

Media

Choose a Video snippet (duration, upload date, thumbnail URL, channel name, view count, follower count, and a Standard YouTube or Grid layout) or Thumbnail images (Single or 3-Strip layout, with 1 or 3 image-URL inputs). Video and Thumbnail are mutually exclusive — enabling Video sets the rich-snippet type to video.

Ranking

A drag-to-reorder list of 10 SERP slots. Your tracked sites occupy their chosen ranks while the remaining slots fill with greyed competitor placeholders, so you can model where your snippet sits within the full results page.

Library

Save the active site's snippet to your browser with a name, then list, load (it adds as a new site), or delete saved snippets. Everything is stored in localStorage — there is no server-side persistence.

SEO Snippet Score (10 Factors)

The SEO Score tab computes a deterministic 0-100 snippet score from your title, description, URL, keywords, and rich-snippet type. It is a content and keyword score — not a CTR score — calculated entirely in the browser with no AI. Ten factors sum to 100.

FactorMax pointsKey rule
Keyword in Title18Keyword present as a substring of the title -> 18, else 0
Title Length1350-60 chars = 13; 40-70 = 9; under 40 or over 70 = 4; empty = 0
Keyword in Description13Keyword present in the description -> 13, else 0
Description Length13150-160 chars = 13; 120-170 = 9; under 120 or over 170 = 4; empty = 0
Power Words105 points per power word found across title + description, capped at 10 (27-word list)
Call-to-Action10Any CTA word in the description -> 10, else 0 (19-word list)
Readability8Avg word length <=5.5 and >=15 words = 8; <=6.5 = 5; otherwise 2
URL Quality5Clean URL (no query string, <=4 segments) + keyword = 5; clean only = 3; else 1
Schema Markup5A rich-snippet type other than Standard -> 5, else 0
Title Front-Load5Keyword in the first 30 chars = 5; present but later = 2; absent = 0

SEO Snippet Score (top-weighted factors)

18
13
13
13
10
33
Keyword in Title (18)
Title Length (13)
Keyword in Description (13)
Description Length (13)
Power Words (10)
Other (CTA, Readability, URL, Schema, Front-Load) (33)

The total renders as a score ring with a tone and label, and the breakdown shows each factor as a bar: good when it earns 80%+ of its points, partial, or fail. Each factor carries a single-line detail string explaining the result — there is no separate "optimization suggestions" engine beyond those per-factor notes.

Quickest wins

Keyword-in-Title (18 pts) is the single heaviest factor, followed by title length, keyword-in-description, and description length (13 pts each). Getting your primary keyword into the title and keeping length in the ideal bands captures the bulk of the score.

CTR & Monthly Clicks Estimate

Shown alongside the SEO Score, this estimate is entirely separate from the 100-point content score. It projects organic click-through rate and monthly clicks from the position you set and a search-volume input — changing them does NOT change your content score.

PositionCTRPositionCTR
127.6%64.9%
215.8%73.9%
311.0%83.3%
48.4%92.7%
56.3%102.4%

Any position beyond 10 uses a flat 1.0% CTR. Monthly clicks = round(CTR / 100 x search volume). The defaults are position 1 and a search volume of 1,000. The CTR curve is based on the Backlinko organic click-through-rate study.

Two independent numbers

Keep them mentally separate: the 0-100 score grades how well-optimized your snippet copy is; the CTR / clicks figure estimates traffic for a given ranking position. A perfect snippet at position 9 will still show modest projected clicks.

Preview, Devices & Locales

The preview pane renders a full 10-slot Google results page: your sites sit at their chosen positions, skeleton competitor placeholders fill the rest, and enabled feature blocks and the heatmap are injected in place.

  • Device toggle — switch between a desktop browser frame and a mobile phone frame (max ~420px wide).
  • Pixel-width truncation meters — desktop title max 600px and description max 920px; mobile title 600px and description 680px. These drive the truncation warnings in Basic Info.
  • Rich-snippet rendering — FAQ, Product, Recipe, Event, Video, How-To, and Sitelink treatments render inline, plus a Verified Badge.
  • Bolded keywords — your Bold Keyword chips are emphasized inside the snippet text exactly as Google bolds query matches.

15 Google country locales

A shared locale field switches the Google country variant (TLD + flag) across all sites in the comparison. Available locales: US, GB, CA, AU, IN, DE, FR, ES, IT, BR, JP, NL, SE, MX, and SG.

Multi-Site Competitor Comparison

Beyond previewing a single page, you can model the whole results page by adding competitor sites — up to 10 in total — each with its own snippet, keywords, position, features, and rich snippet.

1

Add a site

Use the left-panel site selector to add a new site; it is auto-named "Competitor N" and seeded with sample data and a staggered position.

2

Edit each site independently

Switch the active site in the selector; the seven editor tabs apply to whichever site is selected.

3

Position them

Open the Ranking tab and drag sites across SERP positions 1-10 to set who ranks where.

4

Compare in the preview

The Google preview renders all your sites at their chosen ranks, with greyed placeholders filling any empty slots.

Device, search volume, and locale are shared across all sites; everything else is per-site.

Meta Fetcher (Auto-Populate)

The Fetch button in Basic Info auto-populates the title, description, Open Graph image, favicon, suggested keywords, and the detected schema type from any URL. It uses a 3-layer fallback strategy and caches results in memory for 5 minutes.

1

Server route (public tool only)

A Next.js /api/fetch-meta route fetches server-side with no CORS issues — 8s timeout, 2MB body cap, HTML-only, and an SSRF guard that blocks localhost and private IPs. This route exists only in the public tool; in the in-app tool this layer is skipped.

2

CORS proxies

Client-side fetch through public CORS proxies (corsproxy.io, then allorigins.win, then codetabs.com), with the returned HTML parsed in the browser.

3

Minimal fallback

If both fail, it derives the site name from the hostname and pulls the favicon from the Google favicon service.

After a successful fetch, Basic Info shows a status line such as "Fetched + Product schema - via proxy" so you can see which layer responded and what schema was detected.

Public sites only

The fetcher can only read publicly reachable HTML pages. Pages behind authentication, heavy JavaScript rendering, or strict CORS may not auto-populate — type those fields manually.

Export, Save & Reset

Once your snippet looks right, export it in whichever form you need. All actions are available from the desktop footer and the mobile actions menu.

Copy HTML

A full <head> block: title, description, canonical, favicon, keywords, robots, complete Open Graph + Twitter Card tags, optional product/rating/date comments, and a JSON-LD script.

Copy JSON

A full structured export of the snippet, SEO, rich-snippet, extras, active features, and parsed JSON-LD, tagged as a TruIntel SERP Simulator export.

Export PNG

A high-resolution (scale 2) screenshot of the preview frame, rendered client-side via html2canvas.

Reset All

Clears every field back to the default sample snippet.

Auto JSON-LD generation

The Copy HTML and Copy JSON exports include valid structured data generated from your rich-snippet choice: FAQPage, Product (with Offer + AggregateRating), Recipe, Event, VideoObject (ISO-8601 duration), HowTo, WebSite with SearchAction for sitelinks, or WebPage otherwise.

Persistence

  • Saved snippets and your resizable panel widths are stored in browser localStorage — nothing is sent to the TruIntel backend.
  • A base64 ?s= deep link will still load a shared snippet state if you have one, but there is no in-UI button to generate share links in the current tool.

Layout & Interface

The simulator adapts between a resizable desktop workspace and a streamlined mobile layout.

ModeLayout
DesktopA resizable 3-panel workspace: a left tab rail (collapses to icon-only), a draggable content editor panel (drag its width to 0 to hide it), and the preview filling the remaining space
Mobile (small screens)A single column with a header (logo, device toggle, actions menu), an Editor/Preview segmented toggle, and a horizontally scrolling tab strip

Public-tool extras

The public /serp-preview-tool wraps the same simulator with SEO marketing sections and a lead-capture promo modal that auto-opens after about 10 seconds. The in-app tool shows neither — just the fullscreen workspace.


Because the entire tool is client-side, it needs no backend endpoints. The only network calls are the optional meta Fetch (the public /api/fetch-meta route or CORS proxies) and loading the static SERP feature screenshots — no TruIntel API endpoint is involved.

Notifications & Alerts

How Alerts Work

TruIntel runs a lightweight, brand-scoped alert system. Every time a full AI-visibility check finishes, a generator inspects the results and writes alert rows for a fixed set of conditions — score drops, milestones, competitor overtakes, negative mentions, and transient platform failures. A separate path writes an alert when your Google Search Console connection is revoked. Alerts surface in two places: the bell dropdown in the top bar and the Notifications tab under Settings.

Top-bar bell

A live unread-count badge plus a dropdown of your latest 10 alerts, refreshed automatically while you work.

Settings -> Notifications

The full, paginated alert history with All / Unread / Read / Critical tabs and bulk mark-all-read.

Email (HIGH only)

HIGH-severity visibility alerts are emailed immediately to every member of your organization via Resend.

Per-brand scope

Alerts belong to a brand, not a user. Everyone in the org sees the same alerts, and switching the active brand changes what you see.

Alerts are per-brand, shared across your team

There is no per-user notification feed. The bell and the Notifications page always show alerts for the brand you currently have selected, and every member of your organization sees the same set.

No preference toggles yet

You cannot currently turn individual alert types on or off, or change email cadence. The Settings -> Notifications tab shows your alert list, not a configuration panel. See the Limitations subsection for the full list of what is and is not available today.

Alert Types & Triggers

Five alert kinds are produced from the visibility-check path, plus a Google Search Console disconnect alert and an email-only deindexation alert. Each rule has an exact threshold — most compare the current check against the previous one, so a brand needs at least two checks before comparison-based alerts can fire.

AlertExact triggerSeveritySurfaces
Visibility DropPrevious overall score minus current >= 5.0 points (needs a previous check)HIGH if drop >= 10, otherwise MEDIUMIn-app + email when HIGH
Score MilestoneScore crosses 50, 75, or 90 upward (current >= milestone > previous)LOWIn-app only
Competitor OvertakeAn active competitor logs more AI mentions than your brand this check, and your brand has at least 1 mentionMEDIUMIn-app only
Negative MentionMore new NEGATIVE-sentiment mentions than the previous window (only an increase fires)HIGH if 3+ new, otherwise MEDIUMIn-app + email when HIGH
Retry Available (platform failure)One or more AEO responses failed with a retryable error (429, credit exhaustion, timeout, 503), grouped by platformMEDIUMIn-app only
GSC DisconnectedA Google Search Console token refresh returns invalid_grant (revoked)HIGHIn-app only (no email)
DeindexationA tracked page transitions from indexed to not-indexed (Indexation Monitoring)n/a (email)Email only, Pro+

Two flavours of the same type

Both the GSC-disconnect alert (HIGH) and the transient platform-failure alert (MEDIUM, "N responses failed temporarily — retry available") use the same underlying integration_error type. They are distinct in practice: the retry alert sends you to Prompt Tracking -> Query Details -> Retry, while the GSC alert sends you to reconnect in Settings.

Reading the thresholds

  • Visibility Drop fires at a 5-point fall; a fall of 10 or more is escalated to HIGH (and therefore emailed).
  • Score Milestone fires only on an upward crossing of 50, 75, or 90 — never when the score falls back through a milestone.
  • Competitor Overtake only considers competitors that are both active and have status active, and requires your brand to have at least one mention so you are never told you have been "overtaken" from zero.
  • Negative Mention diffs the count of negative mentions against the prior check window — only an increase triggers it, and 3 or more new negatives escalate to HIGH.
  • Retry Available groups failures by platform, so you get one MEDIUM alert per affected AI engine with a direct path to retry.

When alerts are generated

The visibility-check generator runs after every full brand visibility check, manual or scheduled. That means the weekly Monday 02:00 IST check (all paid brands), the Tue-Sun 02:00 IST daily priority check (Pro 5/brand, Enterprise 10/brand), and any manual check you trigger all produce alerts on completion.

Severity & Read State

Each alert carries a severity and two independent state flags. Severity drives colour, the Critical filter, and whether an email is sent; read and resolve are separate actions you take on each alert.

SeverityUsed byEmailed?
LOWScore MilestoneNo
MEDIUMCompetitor Overtake, Negative Mention (1-2 new), Retry AvailableNo
HIGHVisibility Drop (>= 10pt), Negative Mention (3+ new), GSC DisconnectedVisibility-path HIGH alerts only
CRITICALDefined in the model but never produced by any codeWould email, but never occurs

CRITICAL is always empty

No code path ever produces a CRITICAL alert. The Critical filter tab and critical styling exist, but in practice the Critical tab shows HIGH-severity alerts via the severity filter and the literal CRITICAL bucket stays empty.

Read vs Resolve

  • Read marks an alert as seen and clears it from the unread count and the bell badge. It does not remove the alert.
  • Resolve marks the alert as handled or dismissed and also marks it read. Resolved alerts stay in the list with a "Resolved" label so you keep the history.
  • Mark all as read clears the unread badge for the current brand in one action (shown only when there are unread alerts).

In-App Notification Surfaces

Alerts appear in two synchronized places: the top-bar bell for a quick glance and the Settings -> Notifications page for the full history. Both read from the same per-brand alert store.

Top-bar bell dropdown

  • Shows a red unread-count badge, capped at "99+".
  • The unread count is refetched every 60 seconds in the background.
  • Opening the dropdown lists your latest 10 alerts, refreshed every 30 seconds while open.
  • Each row shows a severity pill, type label, title, a 2-line message clamp, relative time, and per-row mark-read and resolve buttons.
  • A "View all notifications" footer link takes you to Settings -> Notifications.

Settings -> Notifications page

  • Filter tabs: All, Unread (with a count), Read, and Critical.
  • Paginated at 20 alerts per page with prev/next controls and a "Showing X-Y of N" indicator.
  • "Mark all as read" appears whenever there are unread alerts.
  • Per-row mark-read and resolve actions; resolved rows display a "Resolved" tag.
  • Tab-specific empty states ("All caught up!", "No critical alerts", "No notifications yet").

The /notifications route redirects

The live page lives at /settings/notifications. The bare /notifications route simply redirects there, so both links land on the same Settings tab.

Email Notifications

A subset of alerts is also emailed. Right after a visibility check generates its alerts, TruIntel loads the brand organization and every member, then emails each HIGH-severity alert from that check to all org members. Emails go out immediately via Resend — there is no batching or digest.

1

A visibility check completes

The alert generator writes any alert rows that match its rules for the brand.

2

HIGH-severity alerts are selected

Only alerts at HIGH (or CRITICAL, which never occurs) from the visibility-check path qualify for email.

3

Every org member is emailed

For each qualifying alert, an email is enqueued to each organization member with subject "{icon} Alert: {title}" (a per-type emoji prefix) and a "View Details" button linking to your visibility dashboard.

Which alerts actually email

In practice only two kinds email: Visibility Drop of 10+ points and Negative Mention with 3+ new negatives. The HIGH GSC-disconnect alert is created outside the visibility-check path, so despite being HIGH it is in-app only and never emails. MEDIUM and LOW alerts never email.

Deindexation email (Pro+)

Indexation Monitoring sends a separate "N page(s) deindexed" email when a tracked page drops out of the index. This is email-only — it never creates an in-app alert and never shows in the bell or Notifications page. It requires Indexation Monitoring, which is a Pro and Enterprise feature with a connected GSC.

Plan Gating

The alert system itself has no explicit plan gate — the alert center and all five alert endpoints are available on every plan, including Free. Gating is indirect, determined by what produces the alerts.

CapabilityAvailabilityWhy
Alert center (bell + Settings tab) and all alert endpointsAll plans incl. FreeNo plan check on the alert routes or service
Alert generation from visibility checksAny brand that gets a checkFree can run manual checks; weekly scheduled checks are paid plans only
HIGH-severity alert emailsAll plansTied to the check that produced the alert; no plan gate on emailing
GSC-disconnect alertRequires a connected GSCSEO/GSC features are Starter and up
Deindexation emailPro / Enterprise onlyIndexation Monitoring is a Pro+ feature (Pro 1000/day, Enterprise 2000/day pages)

No retention or count caps

There is no per-plan limit on how many alerts a brand can accumulate or how long they are retained. All alerts persist until you resolve or stop tracking the brand.

API & Routes Reference

The alerts router is mounted under /api/v1. Every endpoint verifies that the target brand belongs to the caller current organization before returning data.

MethodPathPurpose
GET/api/v1/alerts/{brand_id}List alerts (paginated; filter by is_read, severity, alert_type; limit 1-100, default 20)
GET/api/v1/alerts/{brand_id}/countUnread count for the brand
PATCH/api/v1/alerts/{alert_id}/readMark a single alert as read
POST/api/v1/alerts/{brand_id}/read-allMark all unread alerts read (returns updated_count)
POST/api/v1/alerts/{alert_id}/resolveMark an alert resolved (also marks it read)

The alert_type filter rejects integration_error

The alert_type query filter only accepts visibility_drop, competitor_overtake, negative_mention, new_competitor, and score_milestone. Filtering by integration_error returns a 400 validation error even though such alerts exist. In the UI, filtering is by severity and read-state, not by type.

Notifications (redirect)

/notifications

Redirects to the live Settings -> Notifications tab.

Settings -> Notifications

/settings/notifications

The full paginated alert center with All / Unread / Read / Critical tabs.

Limitations & Roadmap

Notification preferences are not yet available. The Settings -> Notifications tab renders your alert list, not a configuration panel — there is no working toggle UI and no backend preferences endpoint today.

  • No per-type opt-in/out: you cannot mute or enable individual alert kinds.
  • No email-frequency or digest control: HIGH visibility alerts always email immediately, and there is no Instant / Daily / Weekly digest setting.
  • No SMS, Slack, or webhook delivery for end users — alerts are in-app plus email only.
  • CRITICAL severity is never produced, so the Critical bucket relies on HIGH alerts.
  • The new_competitor alert type is defined but never generated — treat it as not implemented.
  • Deindexation alerts are email-only (Pro+) and never appear in the in-app center.

What "Configuration" would have been

A preferences panel (alert toggles plus an Instant / Daily Digest / Weekly Digest selector) exists only as unreleased, non-rendered code with no backend support. Do not rely on it. Email cadence is fixed at immediate, for HIGH-severity visibility alerts only.

Settings & Account

Settings Overview

Settings is a single page in the TruIntel app, split into seven tabs driven by the URL path. Some tabs act on your user account, some on the current organization, and some on the currently-selected brand. Every Settings route is protected by login only — there is no plan-gating at the tab level, though individual capabilities inside a tab (such as Google Search Console) may require a paid plan.

TabRouteScopeWhat it controls
Profile/settingsPer-user + orgName, password, organization rename, sign out
Brand Voice/settings/brand-voicePer-brand + per-userAI writing voice profile + outreach sender identity
Team/settings/teamPer-organizationMembers, roles, invitations
Billing/settings/billingPer-organizationPlan, usage meters, credits, payment history
Notifications/settings/notificationsPer-brandIn-app alerts inbox
Integrations/settings/integrationPer-brandGoogle Search Console, Traffic, Lead Verification
Support/settings/supportPer-userCreate and track support tickets

No customer API keys

TruIntel does not offer a public or programmatic customer API. There is no API Keys tab in the live product — any /settings/api-keys URL simply falls through to the Profile tab. Do not expect to generate API tokens here.

Profile & Account

The Profile tab manages your personal account details and the name of your current organization. It has three cards: Profile info, Change Password, and a combined Organization rename + Sign Out card.

Full name

Editable and saved to your user account. The Save button stays disabled until you change something.

Email (read-only)

Your email is shown with a Verified badge but is a disabled field. Email cannot be changed from Settings.

Organization name

Rename the current organization inline. Owners and admins only — members cannot rename the org.

Avatar upload is coming soon

The avatar shows your initials (or a stored avatar URL). The camera overlay button is labeled "Upload avatar (coming soon)" and is not yet functional.

Change Password

Changing your password requires your current password plus the new password entered twice. The UI enforces a minimum of 8 characters and that both new-password fields match.

Google sign-in accounts cannot set a password here

Password change only works for email/password accounts. If you signed up with Google, the backend returns "Password change not available for Google OAuth users." Manage that login through Google.

Sign Out

The Logout button signs you out on this device only. It revokes just the one refresh token presented and clears the single sign-on cookie. This is a single-device logout — it is not a "sign out from all devices" action, and the current access token remains valid until its 30-minute expiry.

Switching organizations is separate

The Profile tab only renames the current organization. Switching between organizations you belong to is done from the organization/brand switcher elsewhere in the app, not on this page.

Brand Voice & Sender Identity

The Brand Voice tab defines how AI writes for the currently-selected brand. The voice profile is saved per-brand and is woven into every AI content generation prompt — CMS article drafts, content briefs, and AI outreach emails. If no brand is selected, the tab shows an empty state.

SettingOptions / typePurpose
ToneEducational / Conversational / AuthoritativeOverall writing voice
Reading levelSimple / General / Professional / ExpertTarget audience sophistication
Allow em dashesToggleWhether em-dash punctuation is permitted
Allow bullet listsToggleWhether bulleted lists may be used
Allow calls to actionToggleWhether CTAs may be added
AudienceFree text (up to 500 chars)Describes who the content is for
Do'sList editorPhrases, themes, or rules to always follow
Don'tsList editorPhrases, themes, or rules to always avoid

How the voice is applied

The saved profile is rendered into a "Writing style & voice" block that is spliced into the research, outline, draft, and quality stages of content generation. When no profile is set, it falls back to a sensible default keyed off the brand's scanned tone.

Editable on any plan, realized in CMS

Editing the voice profile is available on every plan because it is just a brand field. The content generation it influences (CMS drafts and briefs) requires Starter or above.

Outreach Sender Identity

The same tab includes an Outreach Sender Identity card. This is a per-user, account-wide identity used to fully sign AI-drafted outreach emails, removing placeholder fields like [Name] and [Title]. You enter it once and it auto-fills every draft across all of your brands. Your display name comes from the Full Name field in Profile.

  • Job title — up to 120 characters
  • Phone — optional, up to 40 characters
  • Email signature — optional, up to 2000 characters
  • Leaving a field empty explicitly clears it; saving the identity never wipes your display name

Team Management

The Team tab manages members of the current organization. You can view members with their roles and join dates, invite new people by email, change roles, and manage pending invitations. Permissions are strictly enforced by the backend based on your role.

Roles

RoleInvite membersChange rolesRemove membersRename org
OwnerYesYes (only owners)AnyoneYes
AdminYesNoMembers onlyYes
MemberNoNoNoNo

The last owner is protected

Only owners can change roles, and the UI only assigns admin or member. The last remaining owner cannot be demoted or removed, so an organization always keeps at least one owner.

Inviting members

1

Enter the email

An owner or admin enters the invitee's email address.

2

Existing accounts join immediately

If the email already has a TruIntel account, the person is added directly as a member and emailed a "you've been added" notice.

3

New people get an invite link

Otherwise a pending invitation with a unique secure token is created and an invite email is sent. They join the org when they register or accept.

4

Manage pending invites

Owners and admins can view pending invitations, resend (re-inviting reuses the same token), or cancel them.

Invitations expire after 7 days

Each invitation token is valid for 7 days. After that the invitee must be re-invited.

Team size by plan

PlanTeam members
Free1
Starter1
Lite2
Pro3
Enterprise10

Billing & Subscription

The Billing tab shows your current plan, live usage meters, your credit balance, and payment history. Billing is per-organization and processed through Razorpay. All plans are billed monthly — there is no annual billing in the product.

Current Plan

Plan name, a Monthly badge, price, and next-charge date (or "Access until" / "Cancels at period end" when cancelled). Includes Upgrade and Cancel buttons.

Usage & Credits

Four live meters computed across all brands: Brands, Queries, Competitors, and Plan Credits (shown under the legacy "Plus Credits" label).

Buy Extra Credits

Fixed top-up packs with a Buy Now Razorpay flow. Top-up credits never expire. India orders show a GST line.

Payment History

Plan and top-up charges with date, amount, GST line where applicable, status, and a downloadable invoice.

Corrections to older docs

There is no "checks performed" usage meter — the meters are Brands, Queries, Competitors, and Plan Credits. Top-ups are fixed packs, not custom amounts. Billing is monthly only; any "annual / save 20%" toggle in marketing is display-only.

Plans and prices

Free

$0

  • Permanent, one-time-per-org tier
  • 1 brand, 5 queries
  • All 5 AEO platforms
  • 0 monthly credits

Starter

$59/mo

  • 1 brand, 10 queries
  • 1 competitor, 1 member
  • 50 monthly credits
  • CMS, Insights, Reports

Lite

$139/mo

  • 2 brands, 25 queries each
  • 3 competitors, 2 members
  • 150 monthly credits
  • Everything in Starter

Pro

$479/mo

  • 3 brands, 40 queries each
  • 5 competitors, 3 members
  • 500 monthly credits
  • Rank Tracking, Outreach, daily checks

Enterprise pricing is custom (contact sales): up to 4 brands, 50 queries per brand, 5 competitors, 10 team members, and 1000 monthly credits. India organizations pay 18% GST on top of the USD price.

Credits and top-up packs

Credits live in two pools. Plan credits are your monthly allowance and reset on the 1st of each month. Extra credits come from top-up packs and never expire. When you spend, plan credits are used first, then extra credits.

Top-up packCreditsPriceExpiry
Starter Pack50$10Never expire
Growth Pack150$25Never expire
Pro Pack400$50Never expire

The old "TruIntel Plus" subscription is discontinued

A separate sellable Plus credit subscription no longer exists — that pool is always 0 and unspendable. The Billing UI still labels your monthly plan-credit allowance as "Plus Credits" for legacy reasons, but it is your regular plan credits.

Cancelling

Cancelling an active subscription stops it at the end of the current billing cycle — you keep access until the period end, after which the card shows "Cancels at period end." India payments also generate a self-served GST invoice in addition to the Razorpay invoice.

Notifications (Alerts Inbox)

The Notifications tab is your in-app alerts inbox, not a preferences screen. It is per-brand and surfaces important changes TruIntel detects for the currently-selected brand. The legacy /notifications route redirects here.

It is an inbox, not toggles

There are no notification preference switches here. This tab lists, filters, and lets you act on brand alerts. There is no notification-preferences backend route in the product.

Alert types

Visibility drop

Your AEO visibility score has fallen.

Competitor overtake

A tracked competitor has moved ahead of you.

Negative mention

A negative-sentiment brand mention was detected.

Score milestone

You hit a notable visibility-score milestone.

New competitor

A new competitor surfaced in AI answers.

Filters and actions

  • Filter tabs: All, Unread (with count), Read, Critical
  • Severities: critical, high, medium, low
  • Mark a single alert as read, or mark all as read
  • Resolve an alert to clear it from active view
  • Paginated list for browsing alert history

Integrations

The Integrations tab connects external data sources to the currently-selected brand. There are three per-brand integrations: Google Search Console, Traffic Intelligence, and Lead Verification.

Google Search Console

Connect Google Search Console (GSC) to feed real search performance and indexation data into TruIntel's SEO features. Connection uses a Google OAuth popup with read-only Search Console scope. After authorizing, you pick which verified property to link to the brand and TruIntel queues an immediate data sync.

GSC requires a paid plan

The entire Integrations GSC flow requires a paid plan — the Free tier is excluded. Starter and above can connect GSC.

  • OAuth tokens are Fernet-encrypted at rest (AES-128-CBC + HMAC-SHA256)
  • Access tokens are proactively refreshed when under 5 minutes of validity remain
  • If Google access is revoked, the integration is marked inactive with a "Please reconnect" prompt
  • You can list verified properties, connect one, view connection status and last sync, and disconnect

Traffic Intelligence & Lead Verification

These two integrations are snippet-based: you install a small script on your site. Each card shows an Active badge and a 30-day count (visits for Traffic, leads for Lead Verification) once data flows in, plus a Setup / View Snippet button that opens an install modal.

Traffic Intelligence

Snippet-based visit tracking with bot-vs-human classification. Shows an Active badge and 30-day visit count. To disconnect, remove the snippet from your site.

Lead Verification

Snippet-based lead capture and scoring. Shows an Active badge and 30-day lead count. To disconnect, remove the snippet from your site.

Support

The Support tab lets you create support tickets and track their status. Tickets are reviewed by the TruIntel team and updated in-app — there is no separate email thread for status changes.

Creating a ticket

1

Pick a category

Choose one of four categories: Bug Report, Question, Feature Request, or Refund Request.

2

Add a subject and description

Subject up to 255 characters and a description up to 5000 characters.

3

Attach a payment for refunds

Refund tickets can optionally reference a specific payment, which is validated to belong to your organization.

4

Submit and track

Your ticket appears in the ticket history with its current status. Expand a row to see status and subject.

Ticket statusMeaning
OpenSubmitted and awaiting review
In progressBeing worked on by the team
ResolvedA resolution has been applied
ClosedTicket has been closed out

Status is in-app only

TruIntel does not send an email when a ticket's status changes. Check the Support tab in-app to see updates. A Help & resources panel with quick links is also shown alongside the Settings page.

Routes & Plan Gating

All Settings tabs are reachable by any logged-in user — the routes themselves are protected by login only. Plan gating happens inside specific capabilities (notably GSC) and through team-size and credit limits.

Profile

/settings

Name, password, org rename, sign out

Brand Voice

/settings/brand-voice

AI voice profile + outreach sender identity

Team

/settings/team

Members, roles, invitations

Billing

/settings/billing

Plan, usage, credits, payment history

Notifications

/settings/notifications

Per-brand alerts inbox

Integrations

/settings/integration

GSC, Traffic, Lead Verification

Support

/settings/support

Create and track tickets

CapabilityFreeStarterLiteProEnterprise
Profile / password / org renameYesYesYesYesYes
Brand Voice + sender identityYesYesYesYesYes
Team members (cap)112310
Billing & creditsYesYesYesYesYes
Notifications inboxYesYesYesYesYes
Google Search ConsoleNoYesYesYesYes
Traffic / Lead snippetYesYesYesYesYes
Support ticketsYesYesYesYesYes

Security notes

OAuth integration tokens are encrypted at rest with Fernet. Access tokens (JWT) last 30 minutes; refresh tokens are database-stored with rotation. Logout is single-device and does not revoke other sessions.

Plans & Pricing

Plans Overview

TruIntel is sold as monthly subscriptions in five tiers: a permanent Free tier plus four paid plans — Starter, Lite, Pro, and Enterprise. Every plan includes all five AI Visibility platforms (ChatGPT, Claude, Gemini, Perplexity, and Google AI Overview); the tiers differ in brand count, query volume, monitoring cadence, AI credits, and access to advanced SEO and growth tooling.

Free

$0 / forever

  • Permanent free tier (not a trial)
  • 1 Brand, 5 queries
  • All 5 AI platforms
  • 1 Competitor tracked
  • 500 Site Audit pages
  • Weekly AI Visibility check
  • No AI credits / no SEO keywords
  • No credit card required

Starter

$59/mo

  • 1 Brand, 10 queries
  • All 5 AI platforms
  • 1 Competitor tracked
  • 50 AI Credits / month
  • 750 GSC Keywords
  • 10K Site Audit pages
  • 200 Lead Verifications / month
  • Weekly insights + email reports

Lite

$139/mo

  • Everything in Starter, plus:
  • 2 Brands, 25 queries / brand
  • 3 Competitors tracked
  • 150 AI Credits / month
  • 2,000 GSC Keywords
  • 50K Site Audit pages
  • 1,000 Lead Verifications / month
  • 2 Team members

Pro

$479/mo

  • Everything in Lite, plus:
  • 3 Brands, 40 queries / brand
  • 5 Competitors tracked
  • 500 AI Credits / month
  • Daily priority AEO (5 / brand)
  • Rank Tracking + Indexation Monitoring
  • Weekly SEO + backlink checks
  • 3 Team members, priority support

Enterprise — contact sales

Enterprise is custom-priced (shown as "Custom"). It extends Pro to 4 brands, 50 queries / brand (200 total), 10 daily-priority AEO checks per brand, 1,000 AI credits / month, 10 team members, and a dedicated account manager. Reach out to sales to activate it.

All AI platforms on every plan

There is no platform paywall. ChatGPT, Claude, Gemini, Perplexity, and Google AI Overview are tracked on all five tiers including Free — plans only change how many brands and queries you can monitor and how often.

The Free Tier

TruIntel does not run a time-based free trial. The Free offering is a permanent, hard-limited tier that you activate once per organization without a credit card. It is meant for evaluating the platform and tracking a single brand at a small scale.

Not a 7-day trial

Some marketing copy references a "free trial," but there is no trial timer in the product. Free is a permanent $0 tier with fixed caps — it never expires and never auto-converts to a paid plan. (The only time-boxed window in billing is a 3-day grace period after a failed paid renewal, which is unrelated to Free.)

What Free includes

  • 1 brand and 5 tracked queries
  • All 5 AI Visibility platforms
  • 1 competitor tracked
  • Weekly AI Visibility check (no daily-priority monitoring)
  • AI Crawlability / site audit up to 500 pages
  • 1 PageSpeed check per month
  • Core AEO surfaces: Overview, AI Visibility, Prompt Tracking, Prompt Research, Sources, Competitors, Internal Linking, Indexation view, SEO Dashboard, OnPage Checker, Visualization, Settings

What Free does NOT include

  • No AI credits (CMS / Plus content generation is unavailable)
  • No GSC keyword tracking, keyword suggestions, or backlink tracking
  • No Prompt Volumes lookups
  • No Insights, Tasks, Reports, Traffic, or Leads pages
  • No CMS / Content Studio publishing
  • No team members beyond the owner (team size 1)

Feature Limits by Plan

The table below is the authoritative per-plan limit matrix. A dash (—) means the feature is locked on that tier. All prices are monthly in USD.

FeatureFreeStarter ($59)Lite ($139)Pro ($479)Enterprise
Brands11234
Queries / Brand510254050
Total Tracked Queries51050120200
AI Platforms55555
Competitors Tracked11355
Team Members112310
AEO Check CadenceWeeklyWeeklyWeeklyWeeklyWeekly
Daily Priority AEO / Brand510
AI Credits / month0501505001,000
GSC Keywords7502,0005,00010,000
Keyword Suggestions / mo2050200500
Keyword Rank History1 mo3 mo12 mo12 mo
Site Audit Pages50010K50K100K200K
Top Organic Keywords5050100200500
SEO Competitors11355
Backlink TrackingMonthlyMonthlyWeeklyWeekly
PageSpeed Checks / mo1551530
CTR Suggestions / mo51550200
Internal Link Scans / mo51550200
Indexation Monitoring1,000 / day2,000 / day
Rank Tracking Keywords25100
Traffic Log Retention1K5K25K50K
Lead Verifications / mo2001,0002,0005,000
Prompt Volumes Page2 / mo5 / mo25 / day200 / day
Onboarding AI Volume5 / day6 / day30 / day60 / day
Topics Perf. AI Volume20 / day100 / day
Credit Redemption (5 = 1 PV)

How limits resolve

For an unknown plan the system falls back to Starter limits, and an unrecognized limit key resolves to 0. The weekly AEO check covers every paid plan; daily-priority AEO is the additive Pro/Enterprise feature on top of it.

Pro & Enterprise-Only Features

A handful of higher-cost, metered features are gated to Pro and Enterprise because they carry per-call SERP or LLM spend or run on a daily cadence. These are locked (limit 0) on Free, Starter, and Lite.

Rank Tracking

Track SERP positions for tracked keywords via DataForSEO. Pro: 25 keywords with a $10/brand/month spend cap; Enterprise: 100 keywords at $40/brand/month. Manual-run, metered, and budget-guarded per brand.

Indexation Monitoring

Daily GSC URL Inspection index-status tracking. Pro inspects up to 1,000 URLs/day, Enterprise up to 2,000/day. Requires a connected Google Search Console property.

Daily-Cadence Prompt Volumes

The Prompt Volumes page runs on a daily cadence on Pro (25/day) and Enterprise (200/day). Starter and Lite only get a small monthly allotment (2/mo and 5/mo).

Topics Performance "AI Volume"

The AI search-volume column on Topics Performance is Pro+ only: Pro 20 batches/day, Enterprise 100 batches/day.

Daily-Priority AEO Checks

Beyond the weekly full check, Pro and Enterprise re-run your highest-priority prompts daily (Tue–Sun): 5 per brand on Pro, 10 per brand on Enterprise.

Gap & Outreach Tooling

Keyword Gap, Backlink Gap, Outreach, and Directory pages are Pro+ growth features for competitive and link-building workflows.

AI Credits

AI credits power generative actions — primarily CMS / Plus content drafting and repurposing. Each paid plan includes a monthly credit allowance, and you can top up with one-time packs that never expire.

Two credit pools

  • Plan credits — your monthly allowance (Starter 50, Lite 150, Pro 500, Enterprise 1,000; Free 0). Granted on plan activation and reset to the plan allowance on the 1st of each month. Upgrading or downgrading immediately re-syncs this pool to the new plan.
  • Extra credits — bought via top-up packs. These never expire and are never reset on the monthly rollover.

Deduction order

Spending always draws from your monthly plan credits first, then from your never-expiring extra credits. If your combined balance is below the action cost, the action is blocked and nothing is deducted.

What credits cost

ActionCredit cost
CMS / Plus content draft (standard tier)1 credit
CMS / Plus content draft (premium tier)3 credits
Content brief generationFree (0 credits)
Repurpose existing content1 credit
Prompt Volumes page lookup (after cap)5 credits = 1 lookup

Prompt Volumes redemption

On paid plans, once your daily/monthly Prompt Volumes cap is exhausted you can keep going by redeeming 5 credits per page lookup. Redemption applies to Prompt Volumes page lookups only (not onboarding lookups) and requires at least 5 available credits.

"TruIntel Plus $99/mo" is discontinued

An older "TruIntel Plus" subscription credit pool has been retired and is unspendable. There is no sellable Plus subscription — credits come only from your monthly plan allowance and one-time top-up packs.

Credit Top-Up Packs

When you need more credits than your monthly allowance, buy a one-time top-up pack. Packs are charged as a single payment (not a subscription), land in your extra-credits pool, and never expire. Pricing is flat regardless of your plan.

PackCreditsPricePer credit
Starter Pack50$10$0.20
Growth Pack150$25~$0.17
Pro Pack400$50$0.125

Buying more is cheaper

Larger packs lower the per-credit price. Extra credits never expire and are never wiped on the monthly reset, so it is safe to stock up.

Billing & Payments

Subscriptions are billed monthly through Razorpay. Recurring plans use the Razorpay Subscriptions API; credit top-ups use the one-time Orders API.

  • Billing is monthly only — there is no annual billing in the product.
  • Plans renew automatically each month until cancelled.
  • Upgrade or downgrade at any time; the change takes effect immediately and re-syncs your credit allowance to the new plan.
  • A failed renewal charge enters a 3-day grace period before the plan is deactivated, with an email notification.
  • Credit top-ups are one-time, non-refundable purchases that never expire.
  • Payment history and downloadable receipts are available in Settings → Billing.

Annual "Save 20%" is display-only

The marketing site shows an Annual toggle with "Save 20%" pricing and struck-through regular prices ($79 / $189 / $599). Both are visual only — there is no backend annual billing and no separate annual plan. Every checkout subscribes you on the monthly cycle at the launch price ($59 / $139 / $479).

India GST

For organizations billed in India (billing country IN), 18% GST is added on top of the USD price. The charge currency stays USD; GST is computed on top under SAC code 998314 (seller: Marqait AI LLP, Bengaluru).

Plan Gating by Feature Area

Beyond numeric limits, some product areas only unlock at higher tiers. This is the practical map of which sections each tier can reach.

Feature areaMinimum plan
Overview, AI Visibility, Prompt Tracking / ResearchFree
Sources, Competitors, AI Crawlability / Site AuditFree
Internal Linking, Indexation view, OnPage CheckerFree
SEO Dashboard, PageSpeed, Visualization, SettingsFree
Prompt Volumes, Insights, Tasks, ReportsStarter
CTR Optimization, Plus, Content Studio, CMSStarter
Traffic, LeadsStarter
SEO Backlinks, Keywords, Keyword Suggestions, ImagesStarter
Keyword Gap, Backlink GapPro
Outreach, DirectoryPro
Rank TrackingPro

Manage your subscription

Change plans, buy credit packs, view invoices, and update payment details from Settings → Billing inside the app.

AI Models & Platform Schedule

How TruIntel Uses AI

TruIntel calls several different AI models, each for a specific job. Five of them power the AI Visibility scoreboard (the "platforms" you see your brand ranked across); the rest quietly run content generation, insights, scoring, and source classification behind the scenes. This section is the single source of truth for which model runs where, and on what schedule the automated jobs fire.

Model ids change — capabilities do not

The specific model versions below are the production defaults verified on 2026-06-27. The three foundation AEO models (ChatGPT, Claude, Gemini) are environment-overridable, so TruIntel can swap to a newer snapshot without a code change. Treat the ids as "current", not permanent.

AI Visibility (5 platforms)

ChatGPT, Claude, Gemini, Perplexity, and Google AI Overview answer your tracking queries so TruIntel can measure how each AI engine sees your brand.

Response enrichment

A non-blocking Kimi K2.5 pass refines rank position, mention type, and brand attributes — it never changes the numeric visibility score.

Content & insights

CMS content generation, AI SEO scoring, the Insights pipeline, and brand-report summaries run on Gemini 3.1 Flash-Lite.

Utility fallback chain

Onboarding suggestions, competitor discovery, and CMS drafts use a provider-agnostic chain (Anthropic-first) that self-heals if one provider is down.

The same models on every plan

Model selection is global, never plan-tiered. A Free brand is checked with the exact same gpt-5.4-mini / claude-haiku-4-5 / gemini-3.1-flash-lite / perplexity-sonar / SearchAPI AIO stack as Enterprise. Plans gate how many queries, brands, and features you get — not which AI runs.

The 5 AI Visibility Platforms

Every AI Visibility check runs each active tracking query against all five platforms concurrently. Each one is a different real AI engine (or, for Google AI Overview, Google's own AIO surfaced through a SERP vendor). All five are available on every plan, including Free.

ChatGPT

ChatGPT

OpenAI gpt-5.4-mini via the Responses API with the web_search tool (default search context depth: low). Env-overridable via OPENAI_MODEL.

Claude

Claude

Anthropic claude-haiku-4-5 (Haiku 4.5) via the Messages API with the web_search_20250305 server tool (max 5 searches per query). Env-overridable via ANTHROPIC_MODEL.

Gemini

Gemini

Google gemini-3.1-flash-lite via the google-genai SDK with Google Search grounding; falls back to non-grounded mode if grounding is blocked. Env-overridable via GEMINI_MODEL.

Perplexity

Perplexity

perplexity/sonar routed through OpenRouter (not Perplexity's own API). Sonar performs real-time web search and returns citations.

Google AI Overview

Google AI Overview

Google's own AI Overview, scraped live from the SERP via SearchAPI.io in a two-step flow. Not a model TruIntel runs — many queries simply have no AI Overview.

PlatformModel idRoute / APIWeb searchClient timeout
ChatGPTgpt-5.4-miniOpenAI Responses API (/v1/responses)web_search tool, context = low150s
Claudeclaude-haiku-4-5Anthropic Messages API (SDK)web_search_20250305, max_uses 560s
Geminigemini-3.1-flash-litegoogle-genai SDKGoogle Search grounding (+ fallback)60s
Perplexityperplexity/sonarOpenRouter (/api/v1/chat/completions)Sonar built-in, returns citations30s
Google AI Overviewn/a (Google's AIO)SearchAPI.io two-step searchlive SERP scrape30s

Perplexity runs through OpenRouter

TruIntel does not call Perplexity's own API. The Perplexity platform is the perplexity/sonar model accessed via OpenRouter using OPENROUTER_API_KEY. The standalone Perplexity API key in config is dead/unused.

"No AI Overview" is normal, not a failure

Google AI Overview does not exist for every query. When SearchAPI.io returns no AIO for a query, TruIntel flags it aio_available = false, treats it as a legitimate non-result, and excludes that query/platform pair from the visibility-score denominator so your brand is never penalised for it.

Per-Platform Query Mechanics

Each platform client is tuned to its provider's quirks. The ChatGPT and Claude clients make a single attempt, while the Gemini and Perplexity clients do a few short in-call retries on transient errors; all persistent, cross-time retrying is owned by the retry pipeline (see AI Visibility docs). Here is what is special about each one.

ChatGPT — search depth controls cost

Uses the Responses API with web_search at context depth low by default (env OPENAI_SEARCH_CONTEXT_SIZE). Low is the cheapest tier; medium and high cost more per call. Country and date are injected via the top-level instructions field.

Claude — capped web searches

The Messages API web-search server tool is capped at max_uses 5 per query. A hard 400 "credit balance is too low" is treated as fatal and non-retryable so doomed retries never burn the backoff window.

Gemini — grounding with a safety net

Uses Google Search grounding; if grounding hits a billing/permission/quota error it automatically falls back to a non-grounded answer so the brand still gets a Gemini response. After a quota/429 error it opens a 1-hour module-level cooldown and skips Gemini calls.

Perplexity — fresh citations

Sends return_citations = true with no recency filter, so Sonar returns real-time web results with source links. Routed through OpenRouter; retries up to 3 times on 429/503/timeout.

Google AI Overview — two-step scrape

Step 1 runs a normal google search to obtain a page_token; step 2 calls the google_ai_overview engine with that token (which expires in under a minute) to fetch the AIO content. Concurrency is capped at 2 with a 1.5-2.5s stagger to avoid 429 bursts.

Deterministic scoring (no LLM)

Once each AI response is returned, brand-mention parsing is pure text/regex (sub-50ms, no AI call). The visibility score is computed deterministically from that parse — no model sees the scoring step.

Brand-name alias gap (known limitation)

Mention matching only covers name and domain morphologies (lowercased, CamelCase split, hyphenated, no-spaces, domain, domain-without-TLD). It does not match custom aliases or the bare first word of a multi-word name. A brand surfaced under a short product name (e.g. "River Mobility" appearing as "River Indie") can be under-counted as not mentioned even when it was recommended.

Prompt Localization & Response Cache

Two behaviours explain "why do I see local brands instead of global ones?" and "why does a manual re-run differ from the weekly snapshot?" — prompt localization and the 24-hour response cache.

Country + date anchoring

A user_location hint alone only biases the search backend — the model still tends to answer globally. So TruIntel injects the brand's country, the current local date, and a "prefer local brands/retailers/sources, only fall back to international when no strong local option exists" directive into both the system prompt and the user query, mirroring what a real in-country user would see.

  • The original query text is always preserved for storage, display, and the cache key — only the model-facing copy is localized.
  • Date is the local "now" for the brand's country (e.g. Asia/Kolkata for India), so answers reflect current information as of the right month.
  • Queries that already name the country are sent untouched (no double-anchoring).
  • 20 supported countries: IN, US, GB, CA, AU, DE, FR, AE, SG, JP, BR, SA, ID, MY, PH, NG, KE, ZA, MX, TR (default IN). Unmapped countries fall back to a US/English search profile.
  • Kill switch AEO_LOCALIZE_PROMPTS (default true) reverts to the bare persona prompt with no code change.

24-hour response cache

Check typeReads cache?Writes cache?Why
Scheduled / weeklyYes (24h TTL)YesReuses recent AI answers to control provider cost.
Manual / on-demandNo (force fresh)YesAlways hits the provider live, but stores the result for later scheduled checks.
RetriesNo (force fresh)YesA stale success must never masquerade as a recovery.

Why a manual re-run can differ

The cache key is the original query text plus country (md5), so localization changes never bust it. Only successful, non-empty responses are cached; errors never are. Because manual checks skip the read cache, a fresh "run now" can return different results than the cached weekly snapshot.

Content, Insights & Utility Models

Beyond the five visibility platforms, TruIntel uses a small set of models for content generation, scoring, insights, and classification. Many of these route through a shared, provider-agnostic fallback chain so a single provider outage never breaks the feature.

Utility LLM fallback chain

Onboarding topic/query/competitor suggestions, CMS content steps, and the insights fallback all flow through a shared chain that tries providers in order until one returns valid output. Default order is anthropic, gemini, openai, openrouter (Anthropic-first, because it is the most reliably funded provider). Any exception, timeout, or unparseable/non-JSON output advances to the next key, then the next provider.

Chain slotModel usedRoute
anthropicclaude-haiku-4-5Anthropic Messages API
geminigemini-3.1-flash-litegoogle-genai SDK
openaigpt-5.4-miniOpenAI (JSON mode)
openroutermoonshotai/kimi-k2.5 (Kimi K2.5)OpenRouter

Self-healing — no redeploy needed

When a blocked provider's billing is restored, the chain picks it up automatically on the next call. Keeping the healthy provider first means the happy path never wastes an attempt on a dead provider.

Where each model runs

SurfaceModelNotes
ChatGPT visibilitygpt-5.4-miniOpenAI Responses API + web_search
Claude visibilityclaude-haiku-4-5Anthropic Messages API + web search
Gemini visibilitygemini-3.1-flash-liteGoogle Search grounding
Perplexity visibilityperplexity/sonarvia OpenRouter
Google AI OverviewGoogle's own AIOvia SearchAPI.io (two-step)
Response analyzer (enrichment)moonshotai/kimi-k2.5Non-blocking; refines rank/type/attributes only
Source-domain classifiermoonshotai/kimi-k2.5Classifies cited-source domain types
CMS content generationgemini-3.1-flash-liteVia utility chain; premium tier costs 3 credits
CMS AI SEO scoringgemini-3.1-flash-lite5-dimension LLM rubric, JSON mode
AI Insights pipelinegemini-3.1-flash-liteFalls back to utility chain on failure
Brand-report summariesgemini-3.1-flash-liteWeekly/monthly executive summaries
Prompt Volumes generatorgemini-3.1-flash-liteDirect Gemini only (no fallback)
Onboarding / competitor suggestionsUtility chain (Anthropic-first)topic/query/competitor discovery
SEO data (DA, backlinks, keywords)DataForSEO APIsNot an LLM — third-party SEO data

Kimi K2.5 never changes your score

The response analyzer (Kimi K2.5) only enriches mentioned rows with a refined rank position, mention type, and brand attributes. It is non-blocking and, if it fails, the deterministic defaults stand. The numeric visibility score always comes from the pure-text parser.

Automated Schedule (IST)

TruIntel's background jobs run on a fixed Celery beat schedule of 27 tasks. All times are genuinely Indian Standard Time (Asia/Kolkata, UTC+5:30) — the scheduler evaluates crontab hours in IST, so do not mentally convert these to UTC.

Reading these times

To express any time below in UTC, subtract 5:30 (e.g. 02:00 IST = 20:30 UTC the previous day). The timezone is hard-coded and not environment-overridable.

Time (IST)CadenceTaskPlans
Every minuteAlwaysCMS scheduled-publish pollerAll
Every minuteAlwaysAEO failure auto-retry sweeperAll paid
Every 10 minAlwaysClean up stuck CMS generations (>15 min)All
12:00 AM1st of monthMonthly AI credit resetAll
12:30 AMDailyExpired-trials / grace-period lockAll
01:00 AMDailyExpired-subscriptions checkAll
02:00 AMMondayWeekly full AEO visibility checkAll paid
02:00 AMTue–SunDaily priority AEO checkPro, Enterprise
02:30 AMDailyStale-subscription (abandoned checkout) cleanupAll
03:00 AMDailyDaily traffic aggregationAll
03:00 AM1st of monthMonthly CMS content refreshAll
03:30 AMDailyDaily lead aggregationAll
04:00 AM1st of monthMonthly SEO checks (free + paid)All paid
04:00 AMMondayWeekly SEO checks (DA, backlinks, on-page, competitors)Pro, Enterprise
04:00 AMWednesdayBacklink verification (still live + linking)All paid
04:00 AMSundayWeekly traffic-log cleanup (>30 days)All
05:00 AMDailyGSC keyword sync (clicks/impressions/CTR/position)All paid (if connected)
05:00 AMSundayExpired-invitation cleanup (>30 days)All
05:30 AMDailyGSC indexation checkPro+ with GSC
06:00 AMMondayWeekly AI insight generationAll paid
06:00 AM2nd of monthMonthly brand report (+ outcome attribution)All paid
08:00 AMMondayWeekly visibility email report (Resend)All paid
09:00 AMSundayWeekly content-opportunity refreshAll paid
10:00 AMMondayWeekly brand reportAll paid
Hourly :30AlwaysClean up stuck scan jobs (>30 min)All
QuarterlyJan/Apr/Jul/OctInsight-report cleanup (>90 days)All
QuarterlyJan/Apr/Jul/OctSEO-report cleanup (>180 days)All

Schedule corrections vs older docs

Weekly SEO checks run at 04:00 IST Monday (not 03:00) and are Pro + Enterprise only (not all paid). Weekly brand reports run at 10:00 IST Monday (not 09:00). The monthly brand report is on the 2nd (intentionally, so it lands after the 1st-of-month SEO data).

Schedule Plan-Gating & Cadence

Most scheduled jobs check a brand's plan before doing work. Housekeeping tasks (credit reset, subscription/trial cleanup, traffic/lead aggregation, CMS cleanup) run across all rows regardless of plan.

JobCadencePlan gate
Weekly full AEO visibility checkMon 02:00All paid (plan != Free)
Daily priority AEO checkTue–Sun 02:00Pro (5/brand) + Enterprise (10/brand) with a priority query
Monthly SEO checks1st 04:00All paid
Weekly SEO checksMon 04:00Pro + Enterprise only
Daily GSC syncDaily 05:00All paid with GSC connected
Daily indexation checkDaily 05:30Pro+ with GSC (2k URLs/day/property budget)
Weekly AI insightsMon 06:00All paid with recent data
Weekly + monthly brand reportsMon 10:00 / 2nd 06:00All paid
Weekly content-opportunity refreshSun 09:00All paid

Daily priority checks need a priority query

The Tue–Sun daily priority sweep only runs for paid brands that have at least one query marked priority. Daily-priority AEO capacity is 0 on Free/Starter/Lite, 5 per brand on Pro, and 10 per brand on Enterprise. Brands with no priority queries are covered by the Monday full sweep.

On-demand checks are independent of the schedule

You can always run a manual "check now" on the dashboard. Manual checks skip the 24h cache and are capped at 10 immediate runs per organization per IST day; weekly and priority schedules are separate from that cap.

Workers, Queues & Reliability

Scheduled and on-demand jobs are processed by four background workers, each consuming a dedicated set of queues so a long site crawl never blocks a fast AEO retry. This is reference-level detail — you do not need it to use the product, but it explains throughput and isolation.

WorkerQueuesConcurrencyHandles
worker-aeovisibility, visibility_priority, insights3AEO checks, retries, insights, brand reports
worker-seoseo, crawl3SEO checks, GSC sync, indexation, site crawls
worker-generalcelery, email, traffic2Email reports, traffic + lead aggregation
plus-workerplus2CMS generation/publish/scan, credit + subscription tasks

Every-minute retry sweeper

A beat task sweeps failed AI-platform calls whose backoff has elapsed and re-runs them (exponential backoff 30s to 1h, max 6 attempts). It is a no-op when nothing is due.

Every-minute publish poller

CMS content scheduled for a future time is published by an every-minute poller — a reliable replacement for fire-and-forget delayed tasks that could be silently dropped.

Resilient broker

Connection pooling is disabled and each dispatch opens a fresh broker connection with an explicit queue, fixing a Railway stale-connection issue that silently dropped messages.

Task time limits

Tasks have a 16-minute hard / 15-minute soft default limit; report and opportunity jobs raise this to ~61 minutes. Workers auto-restart after 200 tasks or 512 MB to stay healthy.

Platform Reference

App Map & Route Counts

The TruIntel product app lives at app.truintel.ai. This reference is a complete map of every page, its URL path, what it does, and which plan unlocks it. Use it to find a feature fast or to confirm exactly what a given plan can reach.

The app router declares 99 route entries. Of those, roughly 90 render an actual page component, 7 are redirect aliases (e.g. /ai-mentions to /prompt-volumes), 1 is the 404 catch-all, and 1 is a dev-only preview. Every product page is lazy-loaded and wrapped in an auth guard; paid features add a plan gate on top.

LayerCountNotes
Route entries declared9980 product routes + 16 CMS routes + 3 literal paths
Page-rendering routes~90The rest are redirects, the 404, and a dev preview
CMS pages16All under /cms/*, gated behind the cms feature
Visible nav sections8A 9th (Tools) is hidden but its routes still resolve
Backend routers registered37Across 28 v1 router files plus the v2 package
Backend HTTP endpoints379205 GET, 128 POST, 21 PATCH, 21 DELETE, 4 PUT

How access works

ProtectedRoute requires a logged-in user. PlanGatedRoute additionally checks your plan against the feature minimum (order: Free < Starter < Lite < Pro < Enterprise). CMS pages add CMSProtectedRoute, which also loads your credit balance.

AI Visibility Pages

The AI Visibility section is the AEO core: it monitors how the five AI engines answer buyer questions about your brand. Most pages here are available on every plan, including Free.

Overview

/overview

Single home dashboard: visibility score, recognition rate, mentions, average position, citation rate, sentiment, plus platform breakdown, competitor ranking, top sources, latest insight, tasks, traffic and lead summaries. Free.

AI Visibility

/visibility

Core AEO dashboard with the 0-100 visibility score gauge, per-platform performance, query mentions, brand attributes, and source tracking. Free.

Prompt Tracking

/queries

Manage your tracked queries: search, filter, assign topics, toggle priority, and run bulk operations. Nav label is "Prompt Tracking". Free.

Query Detail

/queries/:queryId

Deep dive on one query: each platform's AI response, whether your brand was mentioned, rank position, competitor mentions, and citation URLs. Free.

Prompt Research

/prompt-research

Discover what the AI engines say about your industry and competitors, and surface new query ideas worth tracking. Free.

Prompt Volumes

/prompt-volumes

Per-keyword AI prompt-volume lookup across all five platforms. Starter and up; page-level lookups are daily on Pro and up. Extra lookups cost 5 credits each after the cap.

Sources & Citations

/sources

Domains the AI engines cite when answering, with type breakdown, a donut chart, citation gap analysis, and URL-level detail. Free.

AI Crawlability

/visibility/site-audit

Audit whether AI crawlers can reach your site (robots rules, bot access). Free.

AI Competitors

/competitors

Track competitors that surface in AI answers, with ranking, sentiment distribution, and score comparison. Free.

Where the data comes from

AI Visibility runs against ChatGPT (gpt-5.4-mini), Claude (claude-haiku-4-5), Gemini (gemini-3.1-flash-lite), Perplexity (sonar via OpenRouter), and Google AI Overview (via SearchAPI.io). All five platforms are included on every plan, including Free.

SEO Pages

The SEO section spans about 17 nav items grouped into Site Crawl, On-Page & Indexing, Keywords & Rankings, Backlinks & Authority, and Competitors. The dashboard, crawl, and on-page checks are Free; the data-heavy keyword, backlink, and ranking pages step up to Starter or Pro.

SEO Dashboard

/seo

Site Health overview: pagespeed (mobile and desktop), Domain Authority, SSL status, technical checks, keyword and backlink summaries. Free.

PageSpeed

/seo/pagespeed

Lighthouse scores with Core Web Vitals and optimization tips. Free.

Site Audit

/seo/audit

On-page audit results grouped by severity, with readability and technical recommendations. Free.

Page Audit

/seo/audit/page

Single-page breakdown: meta tags, headings, content, links, and technical checks. Free.

OnPage Checker

/seo/onpage-checker

Weighted 10-category on-page score with an A-F grade and actionable fixes per page. Free.

Visualization

/seo/visualization

Interactive crawl graph showing page relationships, link structure, and orphan pages. Free.

Internal Linking

/internal-links

Internal-link opportunities and orphan detection from the site crawl. Page is reachable on Free; richer data depends on crawl coverage.

Indexation

/indexation

Google index-status tracking via the GSC URL Inspection API. Page is reachable, but daily indexation monitoring is a Pro feature and needs GSC connected.

CTR Optimization

/ctr-optimization

GSC impressions-vs-CTR analysis with AI title and meta rewrites. Starter and up.

Search Performance

/seo/keywords

Keyword rankings and Search Console performance with position changes, filters, and history. Nav label is "Search Performance". Starter and up.

Keyword Suggestions

/seo/keyword-suggestions

AI keyword discovery with volume, difficulty, and relevance scoring. Starter and up.

Keyword Gap

/seo/keyword-gap

Keywords competitors rank for that you do not. Pro and up.

Rank Tracking

/rank-tracking

SERP position tracking via DataForSEO, run on demand. Pro and up, with a per-brand budget guard.

Backlinks & DA

/seo/backlinks

Backlink profile with referring domains, toxic detection, and opportunities. Starter and up.

Backlink Gap

/seo/backlink-gap

Domains that link to competitors but not to you. Pro and up.

Competitor Analysis

/seo/competitors

SEO comparison vs competitors: DA, keyword overlap, top keywords. Starter and up.

Image Optimization

/seo/images

Image audit for file size, format, alt text, and compression. Starter and up.

No single SEO score

TruIntel does not roll SEO up into one number. Site Health (an unweighted average of mobile/desktop pagespeed, Domain Authority, and SSL status) and the weighted OnPage Checker grade are separate scores, alongside per-page crawl penalties and content-quality buckets.

Insights, Content Studio & Off-Page Pages

The Insights section turns monitoring into action: weekly AI findings, a content opportunity pipeline with a publishing calendar, on-page fixes, and off-page outreach. Insights, Tasks, and Content Studio are Starter and up; Outreach and Directory are Pro and up.

Insights

/insights

Weekly AI insight reports with a findings tab and a tasks tab (split view plus kanban), each with impact scoring. Starter and up.

Finding Detail

/insights/:findingId

One finding with its evidence, impact score, and the tasks it generated. Starter and up.

Tasks

/tasks

Standalone task board (kanban plus split view) with filtering by status and category. Starter and up.

Opportunities

/content-studio/opportunities

Content opportunity pipeline that feeds the staged generation flow. Starter and up.

Create (Staged Generation)

/content-studio/create

Brief-to-draft staged content generation, also reachable at /content-studio/create/:briefId. Starter and up.

Calendar

/content-studio/calendar

Publishing calendar over CMS content: schedule, reschedule by drag, and auto-publish. Starter and up.

Accountability

/content-studio/accountability

Tracks who owns and follows through on content work. Starter and up.

Library

/content-studio/library

All generated content with filter and search. Starter and up.

Page Fixes

/cms/optimization

AI on-page issue detection with fix preview and batch apply. Nav-homed under Insights even though the route is CMS-backed. Starter and up.

Off-Page Outreach

/outreach

Backlink prospect CRM; opening a prospect at /outreach/:prospectId drafts one finished, signed email. Pro and up.

Directory & Citations

/directory

Business-directory and citation submission tracking. Pro and up.


TruIntel Plus generators

The Plus hub creates AEO/SEO-ready content artifacts. There are 8 live routes; five older generators (Website Copy, OG Tags, Directory Listing, Outreach Templates, Citation Plan) have been retired and their links now 404.

Plus Hub

/plus

Template categories, credit balance, and launch into generation. Starter and up.

Generate

/plus/generate

Step-based generation wizard with template selection, config, and preview. Starter and up.

History

/plus/history

Generated content history with filter, search, and publish/archive. Starter and up.

Blog Post

/plus/blog-post

AI blog posts optimized for AI visibility and SEO. Starter and up.

FAQ Page

/plus/faq-page

FAQ content with FAQPage schema markup. Starter and up.

Structured Answer

/plus/structured-answer

Answer blocks tuned for AI citation and featured snippets. Starter and up.

Schema Markup

/plus/schema-markup

JSON-LD structured data (Article, FAQPage, HowTo, Product, etc.). Starter and up.

Meta Tags

/plus/meta-tags

Title tags and meta descriptions with character counting and preview. Starter and up.

Credit costs

A standard content draft costs 1 credit; the premium quality tier costs 3 credits. Brief generation is free, and a repurpose costs 1 credit. Credits are spent from your monthly plan allowance first, then from never-expiring top-up credits.

CMS Module (16 Pages)

The CMS module is integrated under the /cms/* prefix. Every CMS page is wrapped in CMSProtectedRoute (auth plus the credit context) and plan-gated behind the cms feature, so it requires Starter or higher.

Dashboard

/cms/dashboard

Overview of generated content, recent scans, and optimization activity.

Content Library

/cms/content

All generated content, filterable by type and status.

Create Content

/cms/content/new

Start a new generation from a template or custom prompt (deep-link).

Content Editor

/cms/content/:id/edit

TipTap rich-text editor with an AI SEO sidebar, AI assist, and auto-save (deep-link).

Page Fixes

/cms/optimization

AI page-issue detection with fix preview and batch apply. Surfaced in the Insights nav as "Page Fixes".

Edit Pages

/cms/edit-pages

List of published pages with quick edit actions.

Visual Page Editor

/cms/edit-page

Full-screen editor for changing specific elements on a published page (deep-link).

Domain Onboarding

/cms/onboarding

Connect a custom domain, verify DNS via CNAME, and extract the brand template (deep-link).

Domain (Settings)

/cms/settings

Brand template management, re-extraction, SEO files, and domain config. Nav label is "Domain".

CMS Competitors

/cms/competitors

Monitor competitor content and publishing activity (routed; not in the current nav).

CMS Tasks

/cms/tasks

CMS-specific tasks. Distinct from the standalone /tasks page the nav points to.

Backlink Fixes

/cms/backlink-fixes

Backlink optimization tasks with fixes and progress tracking.

Robots.txt

/cms/robots-txt

View and manage robots.txt crawler directives.

Sitemap

/cms/sitemap

View and manage the XML sitemap of published pages.

Upgrade Plus

/cms/upgrade

Upgrade prompt for premium CMS capacity (deep-link).

Credit History

/cms/credits

Credit usage log across the plan and top-up credit pools (deep-link).

AI SEO scoring in the editor

The content editor scores each draft with an LLM (gemini-3.1-flash-lite) across five dimensions: Content Quality (25), Readability & Structure (20), SEO Optimization (20), AI Engine Readiness/AEO (20), and Engagement & Hook (15). Bands: excellent at 85+, good at 65+, needs work at 40+, otherwise poor.

Grow, Reports, Settings & Tools Pages

The remaining sections cover audience analytics, brand reporting, account configuration, and the hidden Tools utilities.

Grow (Traffic & Leads)

Traffic Analysis

/traffic

Bot-vs-human traffic classification: live feed, agent breakdown, trends, threat analysis, and a rules manager. Starter and up.

Lead Verification

/leads

Lead scoring and verification with a funnel, status management, and export. Starter and up.

Lead Detail

/leads/:leadId

One lead: score breakdown, behavior signals, email analysis, and verification status. Starter and up.

Reports

Reports

/reports

Weekly, monthly, and one-time onboarding brand reports with multi-section executive summaries across AEO, SEO, traffic, and leads. Starter and up.

Report Detail

/reports/:reportId

Full report with visualizations, competitor benchmarking, and PDF export. Starter and up.

Settings (8 tabs, one page)

All Settings routes render the same Settings page, switching tab by URL. Every tab is available to logged-in users on any plan.

Profile

/settings

Account profile and personal details.

Brand Voice

/settings/brand-voice

Brand voice profile used by content generation.

Team

/settings/team

Team members and invitations (seats vary by plan).

Billing

/settings/billing

Plan, invoices, credits, and top-up packs.

Notifications

/settings/notifications

Alert center and notification preferences. /notifications redirects here.

API Keys

/settings/api-keys

Programmatic access keys.

Integrations

/settings/integration

Connect Google Search Console and other integrations.

Support

/settings/support

Support and bug reporting (the IconRail Bug button deep-links here).

Tools (hidden from nav, reachable by URL)

Tools Landing

/tools

Tools hub. Routed and Free, but currently hidden from the sidebar.

SERP Simulator

/tools/serp-simulator

Preview how pages appear in Google, Bing, and social search results with live scoring.

Plan-Gating Reference

Every route falls into one of three access tiers. Free pages need only a logged-in user; Starter+ and Pro+ pages add a plan check. The tables below list exactly which features unlock at each tier.

TierWhat it unlocks
Free (auth only)Overview, AI Visibility, AI Crawlability, Prompt Tracking + Query Detail, Prompt Research, Sources, Competitors, Internal Linking, Indexation page, SEO Dashboard, PageSpeed, Site Audit + Page Audit, OnPage Checker, Visualization, all Settings tabs, Tools
Starter and upPrompt Volumes, Insights + Tasks, Content Studio + Plus, Reports, CTR Optimization, Traffic, Leads, CMS (all 16), SEO Backlinks, Search Performance, Keyword Suggestions, SEO Competitors, Image Optimization
Pro and upKeyword Gap, Backlink Gap, Rank Tracking, Off-Page Outreach, Directory & Citations, daily Indexation monitoring, daily-priority AEO checks

Per-plan limits

LimitFreeStarterLiteProEnterprise
Price (USD/mo)$0$59$139$479Custom
Brands11234
Queries per brand510254050
Total tracked queries51050120200
Competitors11355
Team members112310
Daily-priority AEO queries000510
AI credits per month0501505001000

Free is permanent, not a trial

The Free plan is a permanent, hard-limited tier (not a 7-day trial). All five AEO platforms are available on every plan, including Free. The marketing site shows struck-through prices and an annual "Save 20%" toggle for display only; backend billing is monthly. In India, 18% GST is added on top of the USD price.

Credits and top-ups

Monthly plan credits reset on the 1st; one-time top-up credits never expire. Top-up packs: Starter Pack 50 credits for $10, Growth Pack 150 credits for $25, Pro Pack 400 credits for $50. The old TruIntel Plus $99/mo credit pool is discontinued and unspendable.

Backend API Surface

The TruIntel backend exposes 379 HTTP endpoints across 37 registered routers. Version 1 routers mount under /api/v1; the v2 package serves insights under /api/v2. Interactive API docs are available at /docs (Swagger) and /redoc, with the raw schema at /openapi.json.

MethodCount
GET205
POST128
PATCH21
DELETE21
PUT4

Largest routers

RouterPrefixEndpoints
seo.py/api/v1/seo78
cms.py/api/v1/cms60
backlinks.pymixed under /api/v126
admin.py/api/v1/admin19
queries.py/api/v1/queries16
payments.py/api/v1/payments16
v2/insights.py/api/v2/insights14
competitors.py/api/v1/competitors14

Health checks

Outside the versioned routers, the service exposes GET /health, GET /health/deep, and a GET / root probe for uptime monitoring.