Docs menuAPI reference

API reference

Your agent talks to Flowproof over MCP. A few things (connecting cleanup systems, test checkout tokens) are plain HTTPS endpoints you call with your API key.

Reference

Base URL and authentication

Everything is served from https://mcp.flowproof.dev. Authenticate with your API key (from Setup) as a bearer token:

Header
Authorization: Bearer fp_...

To use the curl commands on this site, load the key into your shell first, without it landing in your history:

Terminal
read -rs FLOWPROOF_API_KEY   # paste your fp_ key, press Enter (nothing is shown)
export FLOWPROOF_API_KEY

Errors come back as { "error": { "code": "...", "message": "..." } } with a matching HTTP status. An unknown project and another account’s project both answer 404.

MCP

The MCP endpoint is https://mcp.flowproof.dev/mcp (streamable HTTP), with the same bearer header. See the Connect your agent for each tool’s config. It offers these tools:

ToolWhat it does
whats_nextWhere a project stands and what to do next: open runs, cleanup, what is left to test and how. Call it first.
start_sessionOpen a run before creating any user. Refuses while another run is open or cleanup is not connected, until the user says otherwise.
new_addressMake a test address, optionally with a made-up person.
mark_stepTimestamp an action that should send an email.
handoff_stepsWhen a person does the clicks: list their steps on the run page (start_session’s run_page_url).
wait_for_emailWait for an email on a test address (answers within ~25 s; call again on pending).
assert_no_emailPass if no email arrives within a window.
extractPull a verify, magic or reset link, unsubscribe link, or code out of an email.
record_outcomeRecord what the app did when the agent used a link or code.
get_messageRead one email in full.
list_sessionsList runs; finds ones left open.
get_reportThe graded report (provisional while the run is open).
end_sessionClean up and build the final report. dry_run: true previews the cleanup.
retry_teardownRe-run a finished run’s failed cleanup once the cause is fixed.
share_reportOnly when the user asks: make a finished run’s score card public and return its link.
unshare_reportTurn a run’s public link off (it stops working at once).
save_email_mapSave the list of every email the app can send, read from its code, each planned or built.
get_email_mapThe email map: which emails are planned, built, and tested.
list_test_hooksWhat the app lets Flowproof trigger now instead of on a schedule.
run_test_hookTrigger a scheduled email (trial ending, digest, check-in) for one test user.
check_sender_domainCheck a sending domain’s SPF, DKIM, DMARC and return path in DNS, with the records to add.
get_email_templatesLaunch-ready drafts of every email kind, as email HTML and text or React Email.
plan_emailsRecommend the emails an app needs, from what it does, each with what it must have. Can save them as planned.
suggest_emailsWith the developer’s yes, suggest emails that help people get started and come back, each with its guardrails. Suggestions, not measured results.
answer_suggestions_offerRecord the developer’s answer to the one-time suggestions question, so it is never asked again.
accept_suggestionsMove suggested emails to planned, or dismiss them for good.
get_agent_rulesA short rules block for CLAUDE.md, AGENTS.md or editor rules: build and test every email with Flowproof.
create_watchTurn a passing flow into a Flow Watch.
list_watchesWatches and their recent runs.
run_watchRun a watch now.
pause_watchPause or resume a watch.
run_recipe_onceLet Flowproof’s browser do a signup’s clicks once, in the current run, when the agent won’t create accounts on a live site. Only if the project allows it.
get_recipe_runFollow a run_recipe_once run: its status and each step’s result (answers within ~25 s; call again while running).

It also serves the testing rules as a resource, protocol://flow-testing, the inline result card as ui://flowproof/card.html, and four ready-made prompts: test-email-flows, set-up-emails, test-all-emails and check-emails-before-launch. How a test run works explains how they fit together.

Cleanup connections

A cleanup connection is called an adapter in the API. All routes are under /api/projects/<project>/adapters, and the project must already exist in your account.

Method and pathDoes
GET /api/projects/:project/adaptersList connections and their state.
POST /api/projects/:project/adaptersCreate one: { "label": "...", "config": {...} }. Starts switched off.
POST …/adapters/:id/testCheck the connection and permissions. Changes nothing.
POST …/adapters/:id/previewDry-run a cleanup. Changes nothing.
POST …/adapters/:id/armAllow it to delete. Needs a passing test and preview in the last hour.
POST …/adapters/:id/disableStop it deleting. Keeps its settings.
DELETE …/adapters/:idRemove it and its stored credentials.
List
curl -s https://mcp.flowproof.dev/api/projects/acme/adapters \
  -H "Authorization: Bearer $FLOWPROOF_API_KEY"

The config for each system (the credential commands read secrets without echoing them; see each system’s page):

WordPress
curl -s -X POST https://mcp.flowproof.dev/api/projects/acme/adapters \
  -H "Authorization: Bearer $FLOWPROOF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"label": "Shop (production)", "config": {"system": "wordpress", "siteUrl": "https://shop.example.com"}}'
Supabase / Postgres
curl -s -X POST https://mcp.flowproof.dev/api/projects/acme/adapters \
  -H "Authorization: Bearer $FLOWPROOF_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"label\": \"Production DB\", \"config\": {\"system\": \"supabase\", \"connectionString\": \"$SUPABASE_DB_URL\", \"tables\": [{\"schema\": \"public\", \"table\": \"profiles\", \"column\": \"email\"}]}}"
Stripe
curl -s -X POST https://mcp.flowproof.dev/api/projects/acme/adapters \
  -H "Authorization: Bearer $FLOWPROOF_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"label\": \"Stripe\", \"config\": {\"system\": \"stripe\", \"apiKey\": \"$STRIPE_KEY\"}}"
Webhook
curl -s -X POST https://mcp.flowproof.dev/api/projects/acme/adapters \
  -H "Authorization: Bearer $FLOWPROOF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"label": "My app", "config": {"system": "webhook", "endpointUrl": "https://app.example.com/flowproof/teardown"}}'
Systemconfig fields
wordpress{ "system": "wordpress", "siteUrl": "https://..." }
supabase{ "system": "supabase", "connectionString": "postgresql://...", "tables": [{ "schema": "public", "table": "profiles", "column": "email" }], "ownedTables": [{ "schema": "public", "table": "projects", "column": "gc_user_id" }], "includeAuthUsers": true }
stripe{ "system": "stripe", "apiKey": "rk_live_..." }
webhook{ "system": "webhook", "endpointUrl": "https://..." }

Creating a WordPress or webhook connection returns a secret once; store it on your side. Create, test and preview are limited to 30 requests per 10 minutes per account, because each one contacts your system.

Test checkout tokens

Method and pathDoes
GET /api/projects/:project/verify-tokensList tokens, with their prefix and last use.
POST /api/projects/:project/verify-tokensCreate one: { "label": "production" }. The token is returned once.
DELETE /api/projects/:project/verify-tokens/:idRevoke it, immediately and for good.
Create
curl -s -X POST https://mcp.flowproof.dev/api/projects/acme/verify-tokens \
  -H "Authorization: Bearer $FLOWPROOF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"label": "production"}'

Your app’s server then calls POST /api/test-users/verify with the fpv_ token, not your API key. See Testing paid signups.

Pull request checks

Method and pathDoes
POST /api/ci/runsRun a watch once against a preview deploy: { "watch", "preview_url", "project"?, "vercel_protection_bypass"?, "ci"? }. Answers 202 with the run id.
GET /api/ci/runs/:idThe run: status, done, grade, score, headline, fixes, emails, cleanup and report_url.
Start
curl -s -X POST https://mcp.flowproof.dev/api/ci/runs \
  -H "Authorization: Bearer $FLOWPROOF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"watch": "signup", "preview_url": "https://myapp-git-fix-yourteam.vercel.app"}'

The preview must match one of the project’s preview patterns. 20 starts and 600 polls per 10 minutes per account. See Pull request checks.

Test hooks

Method and pathDoes
GET /api/projects/:project/test-hookThe project’s hook: endpoint, actions and state. Never its secret.
POST /api/projects/:project/test-hookAdd one: { "endpointUrl": "https://...", "actions": [{ "name": "send_trial_ending", "description": "..." }] }. The signing secret is returned once.
POST /api/projects/:project/test-hook/actionsReplace the declared actions: { "actions": [...] }.
POST /api/projects/:project/test-hook/testThe three-check connection test. Calls your app.
POST /api/projects/:project/test-hook/armAllow runs; needs a test that passed in the last hour.
POST /api/projects/:project/test-hook/disableStop runs.
DELETE /api/projects/:project/test-hookRemove it.

Your agent triggers an action with the run_test_hook tool. See Testing scheduled emails.