Docs
Documentation
Everything on one page: what Probie does, how to install it, what it captures, how a fix is made, and how agents can use it.
What Probie does
Probie watches real user sessions in your web, Expo, or Swift app and notices the friction people never report: a button clicked five times with nothing happening, a form retried and abandoned, a request that fails quietly. When enough sessions hit the same problem, Probie groups them into one issue with the evidence attached.
For projects connected to a GitHub repository, Probie then reads the codebase, writes the fix with a regression test, and opens a pull request. A person on your team reviews and merges it. After the merge, the behavior baseline for that route flags the friction if it comes back.
Probie also inspects any public website on request. The public form creates a private browser guest identity on first submission; API and MCP callers register email-bound dispatch access first. The inspection runs in a real browser and produces a graded report. Start one at https://probie.dev/dispatch, by HTTP API, or over MCP.
Install
Sign in at /get-started with GitHub, Google, or a magic link, create a project, and copy its widget token from the Integration page. A coding agent can instead register a provisional project after asking its human for an email address and a separate follow-up-consent choice. The token is public by design: it ships to every client that loads the SDK, so it is safe to commit. Projects without a repository are allowed; they get session capture and triage without pull requests.
Web
Add one script tag before the closing body tag on every page you want watched:
<script src="https://probie.dev/assets/probie-widget.js" data-token="YOUR_WIDGET_TOKEN"></script>This bundle renders a small "Report an issue" button and loads the passive collector. For capture with no visible UI, load the collector on its own:
<script src="https://probie.dev/assets/probie-widget-events.js" data-token="YOUR_WIDGET_TOKEN"></script>Client-rendered apps (React, Next.js, Vue) inject the same tag once on the client; there is no npm package for the web SDK. After load, attribute sessions to a signed-in user with window.probie('identify', userId) and to their company or team with window.probie('group', groupId). Pass null to either one to clear it, and call window.probie('reset') at logout to clear both. The ids are kept in sessionStorage next to the session id, so they last for the browser session and survive a reload.
Optionally, record the outcomes you care about. Automatic capture works without them; with them, Probie can tell which fixes moved a signup or a purchase:
window.probie('group', account.id);
window.probie('track', 'signup_completed', { plan: 'pro' });Event names are 1 to 100 characters of letters, digits, spaces and _ . : / -. Props are a flat object with at most 25 keys, and each value is a string (up to 200 characters), a number, a boolean, or null. A numeric value prop is read as the outcome value, such as revenue or seats. Probie drops an event that breaks these rules. Track events are sampled with the session, so when data-sample is below 1, conversion counts are sampled too. Outcomes that happen on your server, such as a payment, are more reliable sent from there as server events.
Expo and React Native
The SDK targets the Expo managed workflow, SDK 50 and later, and has no runtime dependencies.
npx expo install @probie-dev/react-nativeimport { ProbieProvider } from '@probie-dev/react-native';
export default function RootLayout() {
return (
<ProbieProvider config={{ token: 'YOUR_WIDGET_TOKEN', apiBase: 'https://probie.dev' }}>
{/* your app */}
</ProbieProvider>
);
}The provider captures JavaScript errors, unhandled promise rejections, network failures, and app lifecycle on its own. Screens, taps, and form friction are opt-in hooks documented in the package README on npm.
Swift (macOS and iOS)
The Swift package supports macOS 12 and iOS 15 and later. Instrumentation is explicit; there is no method swizzling.
.package(url: "https://github.com/ProbieAI/probie-swift", from: "0.1.0")import Probie
Probie.start(.init(token: "YOUR_WIDGET_TOKEN", apiBase: "https://probie.dev"))Then mark what matters: .probieScreen("Checkout") and .probieTap("buy") on SwiftUI views, Probie.form("signup") for form friction, Probie.captureError(error) in catch blocks, and URLSession(configuration: Probie.instrumented(.default)) for failing requests.
Server events
Optional. Send outcomes such as signups, purchases and upgrades from your backend, where they actually happen. Send the events your app already records; you do not need to invent new ones.
Server events use a per-project secret key. Generate it in the Server events card on the Integration page. The key starts with pbs_ and is shown once, because Probie stores only a hash of it. Keep it on your server and never ship it to a browser or app. Rotating the key stops the old one immediately.
curl -X POST https://probie.dev/api/events \
-H "Authorization: Bearer $PROBIE_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"events":[{"event":"subscription_started","user_id":"user_123","group_id":"acme","properties":{"plan":"pro","value":49}}]}'From Node 18 or later, the @probie-dev/node package batches and retries for you:
import { Probie } from '@probie-dev/node';
const probie = new Probie({ secretKey: process.env.PROBIE_SECRET_KEY });
probie.track({ event: 'subscription_started', userId: user.id, groupId: org.id, properties: { plan: 'pro', value: 49 } });
await probie.shutdown(); // before the process exitsevent- Required. Same rules as a browser event name.
user_id,group_id- At least one is required, up to 200 characters each. Use the same ids you pass to
identifyandgroupin the browser. properties- Optional. Same rules as browser props; a numeric
valueis the outcome value. timestamp- Optional. ISO-8601 or epoch milliseconds, from 30 days ago to 5 minutes ahead. Defaults to now.
event_id- Optional idempotency key, up to 128 characters. Probie ignores a repeat of the same id within an hour. The Node package always sends one.
A request carries at most 100 events and 256 KB. Probie answers 202 with the number received; 400 with the index and field of the first bad event, in which case nothing in the batch is stored; 401 for a missing or unknown key; 429 past the per-minute limit; and 503 when it cannot buffer events right now, which is safe to retry.
Install with a coding agent
The integration skill at https://probie.dev/skill is a SKILL.md file that walks a coding agent through registration and installation. The agent infers the project name, asks its human for an email and whether limited setup/product follow-up is allowed, provisions a token, installs it, verifies one passive event, and reports the emailed/browser claim flow. Point Claude Code, Cursor, or any agent that reads skills at it, or save it into the repository:
curl -fsSL https://probie.dev/skill -o .claude/skills/probie-integration/SKILL.mdThe registration endpoint is POST /api/agent/registrations; it requires email, boolean contact_consent, and a high-entropy Idempotency-Key header. Omit project_name for inspection access, or include it to provision an integration. Every response includes a dispatch token and signed seven-day claim URL; integration responses also include widget and skill credentials. The MCP tools are split by task: register_inspection_access for inspecting only and register_integration for installing Probie.
What the SDKs capture
Every SDK sends the same event types to POST /api/widget/events in small, bounded batches:
pageview, click, rage_click, dead_click, scroll_lock, stuck_overlay, stuck_loading, form_submit, form_retry, form_abandon, js_error, fetch_error, page_leaveYour code can add named outcome events of its own with track, from the browser or from your server. Those carry only the name and properties you send.
The collector is built to see friction without reading content:
- Input values
- Never read. Form events record that a field was retried or abandoned, not what was typed.
- Element labels
- Hashed before they leave the page, so a button is recognizable across sessions without its text being stored.
- URLs
- Query strings are dropped except
utm_*campaign tags. Fragments are dropped. - Cookies
- None set. Sessions are identified by an id generated in the client.
- Sampling
- Optional per project through the
data-sampleattribute. - User and group ids
- Sent only when your code calls
identifyorgroup, or includes them in a server event. Probie stores the id you pass and nothing else about the person, so prefer an internal id over an email address. - Event properties
- Sent only with
trackevents, and only the properties your code passes.
How the data is stored and for how long is in the privacy policy. Questions go to [email protected].
How a fix is made
When an issue is promoted to a fix, or a ticket is filed from the dashboard or Slack, Probie runs a pipeline of agent roles:
- Planner
- Reads the evidence and the codebase and writes the plan.
- Root-causer or architect
- The root-causer traces a bug to its cause; the architect shapes a feature-sized change.
- Coder
- Makes the change and writes a regression test.
- Reviewer
- Checks the diff against the acceptance criteria. Failing review sends it back to the coder, up to a configured number of rounds.
- Rebaser
- Brings the branch up to date with the default branch before the PR is opened.
Each role runs through a configurable agent harness, such as Claude Code, Codex, OpenCode, or Pi, in an isolated container. Commits are authored as Probie Bot on a probie/* branch, and the pull request description includes a Tests section that lists the regression tests added.
A person merges. Probie observes the merge or close from GitHub and records the outcome. Probie does not verify individual fixes after merge; what it keeps is a behavior baseline per route, and if the same friction returns on that route the regression is flagged.
Goals
A goal is the number a project is trying to move, such as paying teams or completed orders, broken into the metrics that drive it. Each metric counts or sums one tracked event. Open Goal in the dashboard sidebar to see the project's goal.
Probie proposes the goal after onboarding, or when you ask from the Goal page. It reads the code and the events the project already sends, then suggests a goal and its metrics. You can edit the objective, target, deadline and directions, remove metrics, or ask Probie to revise it with a note. Nothing is saved until you confirm it.
When a metric needs an event the project does not send yet, the proposal shows where the event belongs in the code and the tracking call to add. For a project with a connected repository, confirming can open a pull request that adds those calls.
After you confirm, Probie records a reading for each metric once a day. A day stays provisional for 30 days, because server events can be backdated that far.
Website inspection
Anyone can send Probie to a public website. The browser form grants guest access automatically; agents and scripts register dispatch access with an email and consent choice. Probie opens the website in a real Chromium browser, clicks through the pages a first-time visitor would, and writes a report graded A to D with the evidence for each finding.
- Public pages by default. With permission, supported sign-in or account-creation flows can give Probie broader access and produce a richer report.
- Probie reads robots.txt and stays out of what it disallows. Granting permission to sign in is the one exception: to act as a signed-in user Probie may open pages robots.txt asks crawlers to skip. It still avoids payments, publishing controls, and bot checks.
- Reports are public and listed. Each lives at
/report/<id>/<domain-slug>and appears in the gallery and the sitemap. - Usage limits apply across the website, API, and MCP. If a limit is reached, Probie tells you when to retry.
- Bot walls stop the inspection. When that happens, the report says the website was protected and explains how to allow the scanner.
HTTP API
Inspecting only: first register inspection access by omitting project_name. Installing Probie: include project_name in the same registration request. Keep the returned dispatch token secret.
curl -s -X POST https://probie.dev/api/agent/registrations \
-H 'content-type: application/json' \
-H 'Idempotency-Key: A_RETAINED_RANDOM_VALUE_AT_LEAST_32_CHARS' \
-d '{"email":"[email protected]","contact_consent":false}'Then start an inspection with the dispatch token as a bearer credential. The endpoint allows cross-origin requests.
curl -s -X POST https://probie.dev/api/dispatch \
-H 'content-type: application/json' \
-H 'Authorization: Bearer YOUR_DISPATCH_TOKEN' \
-d '{"url": "example.com"}'Add "signin_permission": true to let Probie sign in or create an account on the website during that one inspection. Send it only when the person you act for has agreed to it for that website. A signed-in inspection may open pages robots.txt asks crawlers to skip; it still avoids payments, publishing controls, and bot checks. The field must be a real boolean, and it defaults to false.
- 202
{"id": 123, "statusUrl": "...", "pageUrl": "..."}. A new inspection was queued.- 200
- The same fields plus
"reused": true. The website already had a live inspection and you were attached to it. - 400
{"error": "..."}. The body was not JSON, had nourl, or named a private or reserved address.- 401
{"error": "Unauthorized"}. The bearer token was missing, invalid, expired, or revoked.- 429
{"error": "...", "retryAfterSecs": n}with aRetry-Afterheader. The hourly limit was reached.
Poll statusUrl (GET /dispatch/{id}/status) every 5 seconds or so. The payload depends on the state:
- queued or running
{"status", "progress", "queuedAhead", "activity": [...], "chips": {...}}.activityis a short plain-language log.- ok
{"status": "ok", "reportUrl": "/report/<id>/<slug>"}. The report is ready.- error or skipped
{"status", "failureMessage", "allowUrl"}.skippedmeans a bot wall stopped Probie;allowUrlexplains how to let it through.
MCP server
The same surface is available to agents as a remote MCP server at https://probie.dev/mcp. It uses Streamable HTTP. Registration and status reads are public; starting an inspection requires the dispatch token returned by registration. Add it to a client:
{
"mcpServers": {
"probie": { "type": "http", "url": "https://probie.dev/mcp" }
}
}claude mcp add --transport http probie https://probie.dev/mcpregister_inspection_access- Inspecting only: register an email-bound dispatch identity without creating a project.
register_integration- Provision a widget token after collecting the human’s email and consent choice. Requires a retained idempotency key and returns a seven-day claim URL.
inspect_website- Start an inspection with a dispatch token. Returns the id and the URLs to poll and open; reuses live and recent inspections.
get_inspection- The state of an inspection by id, with absolute report and allow URLs when it has finished.
get_integration_skill- The integration skill, with the token filled in when a widget token is passed.
probie://skill- The generic integration skill as a text/markdown resource.
Usage limits apply to inspection and registration across both REST and MCP. A rate-limited response tells the caller when to retry.
Integrations
- GitHub
- A GitHub App installation gives Probie the repository access it needs to read code and open pull requests. Merge and close events come back through the same App.
- Sentry
- An inbound webhook turns Sentry issues into Probie tickets, and Sentry evidence is attached to the pull request.
- Slack
- Notifications when a PR opens, and a
/probieslash command that files a ticket from a channel. - Your MCP servers
- Per project, you can configure MCP servers that the coding agent is given while it works on your repository.
There is no first-party integration with Jira, Linear, Notion, PagerDuty, or Datadog.
Frequently asked questions
How much does Probie cost?
Website inspection is free and needs no account. Starter $99/month or $83/month billed annually; Team $249/month or $208/month billed annually; Scale $599/month or $500/month billed annually. Enterprise has custom annual pricing. All paid plans include unlimited collaborators and start with a 14-day free trial. See plans and subscribe online, or contact us about Enterprise.
How do I install Probie?
Sign in, create a project, and add the script tag, the Expo package, or the Swift package with your widget token. The install section has the exact snippets, and the agent skill does it for you.
Which frameworks and platforms does Probie support?
Any web app that can load a script tag (server-rendered, static, React, Next.js, Vue), Expo and React Native apps on Expo SDK 50 and later, and Swift apps on macOS 12 and iOS 15 and later. Pull requests work for repositories on GitHub.
What access does Probie need to my repository?
A GitHub App installation on the repositories you choose. The coding agent proposes changes on a probie/* branch, commits as Probie Bot, and opens a pull request. Nothing merges without a person approving it.
What user data does Probie collect?
Behavior events: page views, clicks, rage and dead clicks, stuck loading states, form retries and abandons, JavaScript and fetch errors. Input values are never read, element labels are hashed, query strings are dropped except campaign tags, and no cookies are set. If your code opts in, Probie also stores the user and group ids you pass to identify and group, and the outcome events and properties you send with track. See what the SDKs capture and the privacy policy.
What happens after Probie opens a pull request?
Your team reviews it like any other PR. Probie records whether it was merged or closed. Probie does not verify individual fixes after merge; it keeps a behavior baseline per route and flags the route if the same friction returns.
How is Probie different from Sentry Seer?
Seer starts from an error Sentry already captured. Probie starts from user behavior: rage clicks, dead clicks, abandoned forms, and stuck states that raise no exception. Probie can take Sentry issues as input too. The comparison page has the details.
Can my coding agent use Probie?
Yes. The integration skill installs the SDK, the MCP server at https://probie.dev/mcp runs inspections and fetches the skill, and /llms.txt indexes the documentation in markdown.
Does Probie work without a repository?
Yes. A project without a connected repository still gets session capture and triaged issues on the dashboard, without pull requests. Website inspection needs no account at all.
How do I let the Probie scanner through bot protection?
The scanner signs every request with Web Bot Auth (RFC 9421) and publishes its key. Allow verified bots in Cloudflare, or add an exception for the Signature-Agent header. The scanner page has the exact rules.