# iterateTo — full documentation > Generated from https://iterateto.com/docs. Each section corresponds to one docs page; the > per-page Markdown is also available at https://iterateto.com/docs/.md. # Documentation Install the iterateTo feedback widget, keep captures private, and work the queue over REST or MCP — by hand or with an AI agent. **iterateTo** takes user feedback from an embeddable widget, to a triage inbox, to your agents. These docs cover installing the widget, configuring it, and working the queue programmatically. ## Start here - [Install the widget](/docs/install) — one script tag, the React component, or `npx iterateto init`. - [Install with AI](/docs/install-with-ai) — point your coding agent at our Agent Skill and let it wire everything up. - [Widget configuration](/docs/widget) — position, accent, screenshots, and stable element targeting. - [Privacy & masking](/docs/privacy) — how screenshots stay private. - [REST API](/docs/rest-api) and the [MCP server](/docs/mcp) — read and work the queue programmatically. - [Recipes](/docs/recipes) — copy-paste agent workflows for triage and follow-up. ## Two keys iterateTo uses two kinds of key. Know which is which before you paste one anywhere. | Key | Prefix | Used for | Secret? | | --- | --- | --- | --- | | Public key | `pk_` | Identifies a project to the widget; embeds in your website | No — safe to ship in HTML | | API key | `itr_` | Authenticates REST and MCP requests for your whole org | Yes — treat it like a password | > **Note:** Find your public key (with a ready-made snippet) under [Dashboard → Projects](/dashboard/projects). Create and revoke API keys under [Dashboard → Settings → API keys](/dashboard/settings/api-keys). --- # Install the widget Add the feedback launcher to any page — a script tag, the React component, or `npx iterateto init`. ## Quickstart Add one script tag to any page. It can go in `` or at the end of `` — it does not matter, because the loader is tiny and async and pulls the widget UI on demand. The widget renders in a shadow root, so your page styles are never affected. ```html ``` Replace `pk_...` with your project's public key from [the dashboard](/dashboard/projects). A launcher pill appears in the corner; that is the whole install. ## Install with the CLI `npx iterateto init` detects your framework, writes the embed in the right place, and wires env for you. Pass `--key` to skip the prompt, and `--yes` for non-interactive use (CI, or an AI agent running it for you). ```bash npx iterateto init --key pk_... --yes ``` Want to see what it will do first? Run `iterateto info --json` to print the detected framework and current install state, or run `init` without `--yes` to review each change before it is written. ## React / Next.js component `@iterateto/react` wraps the loader as a component. Install it, then mount it once near the root of your app. ```bash npm install @iterateto/react ``` ```tsx import { IterateTo } from "@iterateto/react"; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( {children} ); } ``` In a plain Next.js app without the package, use `next/script` with `strategy="afterInteractive"` in your root layout's `` and pass `data-key` as a prop. Avoid `worker` (Partytown) and `type="module"` — use the config object below for those. ## Runtime API The widget exposes a global `iterateTo` function: `iterateTo("open" | "close")`, `iterateTo("identify", { ... })`, and `iterateTo("metadata", { ... })`. Use `identify` to attach who is reporting and `metadata` for app state (both take a flat object, max 20 keys). Because the loader is async, `window.iterateTo` does not exist until it runs. Install the one-line queue stub **before** the script tag so calls made early are buffered and replayed once the widget is ready. ```html ``` ## Configuration attributes - `data-key` (required) — your project's public key (starts with `pk_`). Safe to embed publicly. - `data-position` (optional) — `bottom-right` (default) or `bottom-left`. Overrides the position set in project settings. See [Widget configuration](/docs/widget) for the full set of settings and targeting attributes. ## Frameworks & tag managers The plain ` ``` --- # Install with AI Point your AI coding agent at iterateTo's Agent Skill and let it install and configure the widget for you. iterateTo ships an **Agent Skill** — a single `SKILL.md` that any modern coding assistant can read (Claude Code, Codex / ChatGPT, Cursor, VS Code / Copilot, Gemini CLI, Windsurf, and more). Give your agent the skill and it detects your framework, drops in the embed, wires env, and records the setup in your `AGENTS.md` so future sessions know the widget is there. ## Point your agent at the skill The install skill is hosted at `https://iterateto.com/skill.md`. Fetch it and follow the procedure, or add it to your repo with: ```bash npx skills add https://iterateto.com/skill.md ``` ## Or just run the CLI The skill shells out to the same CLI you can run yourself — skills provide the context, the CLI does the work. `iterateto info --json` reads your project's real state so the agent doesn't guess; `init` writes the embed. ```bash npx iterateto init --key pk_... --yes ``` ## What the agent does 1. Runs `iterateto info --json` to read your actual framework and install state. 2. Confirms your project public key (`pk_...`) from the dashboard — it never hard-codes a key. 3. Runs `npx iterateto init --key --yes` (or the manual embed it prints). 4. Wires the necessary env and verifies the widget config responds. 5. Appends a short iterateTo block to your `AGENTS.md` / `CLAUDE.md` recording where the keys live and how to reach the MCP queue. ## Machine-readable docs Every docs page is available as raw Markdown — append `.md` to any docs URL, or use the copy button at the top of the page. Two site-wide indexes help agents discover the rest: - [`/llms.txt`](/llms.txt) — a link map of the docs (the emerging convention). - [`/llms-full.txt`](/llms-full.txt) — the full docs as a single Markdown file. - [`/skill.md`](/skill.md) — the hosted install skill, served verbatim. --- # Widget configuration Position, accent, screenshots, privacy-policy link, and stable element targeting — from project settings or per-page attributes. Most widget settings live server-side in [project settings](/dashboard/projects), so you can change them without redeploying. Per-page `data-*` attributes and runtime calls override them. Precedence, lowest to highest: **server config → `data-*` attributes → runtime `iterateTo(...)` calls**. ## Server settings | Setting | Values | Notes | | --- | --- | --- | | Position | `bottom-right` · `bottom-left` | Where the launcher sits | | Accent color | hex | Tints the launcher and panel | | Title | string | Heading shown at the top of the panel | | Screenshots | on · off | Enables the capture + annotation flow | | Privacy policy URL | URL | Linked from the panel when set | ## Data attributes | Attribute | Purpose | | --- | --- | | `data-key` | Required. Your project public key (`pk_...`). | | `data-position` | Override the launcher position for this page only. | ## Element targeting The widget's element picker lets users point at exactly what broke. Each selected element is reported with several selector candidates so reports stay actionable even after markup changes. Make those selectors far more stable by annotating your own markup: ```html ``` - `data-feedback-id` — a stable, unique id. The highest-confidence selector in reports; survives refactors that break CSS selectors. - `data-feedback-label` — a human-readable name shown in the report instead of a raw selector. - `data-feedback-component` — the owning component name, useful for routing reports to the right team or agent. ## Masking & ignoring elements Two attributes control what the capture can see. See [Privacy & masking](/docs/privacy) for the full pipeline. - `data-feedback-mask` — force an opaque mask over an element in screenshots (account numbers, avatars, anything sensitive). - `data-feedback-ignore` — exclude an element from captures and from the element picker entirely. --- # Privacy & masking Screenshots are captured and scrubbed entirely client-side before anything is sent. Screenshots are captured and processed entirely in the browser — pixels never leave the page until the user reviews the capture and hits send. Before anything is drawn, the widget scrubs the frame automatically: - All ``, `