Aannot8

How Annot8 is organised

Workspaces, projects, environments, and threads — and which settings live where.

Four objects, nested. Almost every "where do I change this?" question resolves by working out which level a setting belongs to.

Workspace  ── billing, members, integration credentials
  └── Project  ── project key, widget appearance, feature flags
        └── Environment  ── hostname patterns; which lane feedback lands in
              └── Thread  ── one pinned comment and its replies

Workspace

A workspace (an organization) is the billing and membership boundary. It owns:

  • The subscription and its seats
  • Members and their roles — see Team members
  • Integration credentials, which are stored once and reused by every project
  • Workspace-wide notification preferences

You can belong to several workspaces and switch between them from the sidebar. Seats, projects, and usage limits are counted per workspace, never across them.

Project

A project is one site or app. It holds:

  • Project key (pj_...) — the public identifier in your script tag
  • Widget appearance — colour, corner, launcher label, pin style
  • Feature flags — Analytics and Live chat on/off, and whether the widget is visible in production
  • AI model and the visitor audience classification
  • Its own inbox, labels, issue types, automations, and public links

One project per site. Two sites that need separate inboxes are two projects.

Environment

An environment is a named set of hostname patterns. On every page load the widget reports the hostname, and Annot8 matches it against the project's environments, most specific pattern first.

PatternMatches
app.example.comThat host exactly
*.example.comAny subdomain of example.com
*.vercel.appPreview deployments
localhostLocal development
pr-*.example.comA prefix wildcard

A single pattern field can hold several patterns separated by spaces or commas: localhost *.local 127.0.0.1.

Three things follow from the match:

  1. The widget loads at all. A hostname matching no environment gets nothing. This is what stops your script tag being lifted onto someone else's site.
  2. Which lane the thread is filed into. You can filter the inbox by environment, so a local experiment never pollutes your production triage.
  3. Whether production rules apply. The default environment — and any environment literally named "Production" — counts as production, where the annotation widget stays hidden unless you explicitly enable it.

A bare * is rejected. There is no way to make the widget embeddable from anywhere. See Environments.

Thread

A thread is one piece of feedback: the pinned element, the original comment, and every reply. It carries:

  • Anchor — the CSS selector plus a percentage offset inside that element, so the pin survives scrolling, resizing, and most re-deploys
  • Page context — URL path, full URL, page title, referrer
  • Device context — viewport, device type, user agent, pixel ratio, language, timezone, colour scheme
  • Element context — tag name, id, classes, inner text, href/src
  • Diagnostics — console errors, failed network requests, performance timings
  • Attachments — screenshot, screen recording, voice note
  • Triage state — status, priority, assignee, labels, issue type, sentiment

Threads created from a hosted feedback form are marked form; threads pinned through the widget are marked widget. Both land in the same inbox and you can filter on the difference.

Where a setting lives

I want to change…Go to
Plan, seats, invoicesWorkspace → Billing
Who's on the teamWorkspace → Team
Slack / Linear / Jira credentialsWorkspace → Integrations
Widget colour, corner, labelProject → Settings → Appearance
Which hosts the widget runs onProject → Settings → Environments
Analytics or Live chat on/offProject → Settings → Features
Show the widget on productionProject → Settings → Features
AI model, visitor audienceProject → Settings → Configuration
Which integrations fire for this projectProject → Integrations
Labels and issue typesProject → Labels

On this page