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.
Base URL and authentication
Everything is served from https://mcp.flowproof.dev. Authenticate with your API key (from Setup) as a bearer token:
Authorization: Bearer fp_...To use the curl commands on this site, load the key into your shell first, without it landing in your history:
read -rs FLOWPROOF_API_KEY # paste your fp_ key, press Enter (nothing is shown)
export FLOWPROOF_API_KEYErrors 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:
| Tool | What it does |
|---|---|
whats_next | Where a project stands and what to do next: open runs, cleanup, what is left to test and how. Call it first. |
start_session | Open a run before creating any user. Refuses while another run is open or cleanup is not connected, until the user says otherwise. |
new_address | Make a test address, optionally with a made-up person. |
mark_step | Timestamp an action that should send an email. |
handoff_steps | When a person does the clicks: list their steps on the run page (start_session’s run_page_url). |
wait_for_email | Wait for an email on a test address (answers within ~25 s; call again on pending). |
assert_no_email | Pass if no email arrives within a window. |
extract | Pull a verify, magic or reset link, unsubscribe link, or code out of an email. |
record_outcome | Record what the app did when the agent used a link or code. |
get_message | Read one email in full. |
list_sessions | List runs; finds ones left open. |
get_report | The graded report (provisional while the run is open). |
end_session | Clean up and build the final report. dry_run: true previews the cleanup. |
retry_teardown | Re-run a finished run’s failed cleanup once the cause is fixed. |
share_report | Only when the user asks: make a finished run’s score card public and return its link. |
unshare_report | Turn a run’s public link off (it stops working at once). |
save_email_map | Save the list of every email the app can send, read from its code, each planned or built. |
get_email_map | The email map: which emails are planned, built, and tested. |
list_test_hooks | What the app lets Flowproof trigger now instead of on a schedule. |
run_test_hook | Trigger a scheduled email (trial ending, digest, check-in) for one test user. |
check_sender_domain | Check a sending domain’s SPF, DKIM, DMARC and return path in DNS, with the records to add. |
get_email_templates | Launch-ready drafts of every email kind, as email HTML and text or React Email. |
plan_emails | Recommend the emails an app needs, from what it does, each with what it must have. Can save them as planned. |
suggest_emails | With the developer’s yes, suggest emails that help people get started and come back, each with its guardrails. Suggestions, not measured results. |
answer_suggestions_offer | Record the developer’s answer to the one-time suggestions question, so it is never asked again. |
accept_suggestions | Move suggested emails to planned, or dismiss them for good. |
get_agent_rules | A short rules block for CLAUDE.md, AGENTS.md or editor rules: build and test every email with Flowproof. |
create_watch | Turn a passing flow into a Flow Watch. |
list_watches | Watches and their recent runs. |
run_watch | Run a watch now. |
pause_watch | Pause or resume a watch. |
run_recipe_once | Let 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_run | Follow 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 path | Does |
|---|---|
GET /api/projects/:project/adapters | List connections and their state. |
POST /api/projects/:project/adapters | Create one: { "label": "...", "config": {...} }. Starts switched off. |
POST …/adapters/:id/test | Check the connection and permissions. Changes nothing. |
POST …/adapters/:id/preview | Dry-run a cleanup. Changes nothing. |
POST …/adapters/:id/arm | Allow it to delete. Needs a passing test and preview in the last hour. |
POST …/adapters/:id/disable | Stop it deleting. Keeps its settings. |
DELETE …/adapters/:id | Remove it and its stored credentials. |
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):
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"}}'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\"}]}}"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\"}}"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"}}'| System | config 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 path | Does |
|---|---|
GET /api/projects/:project/verify-tokens | List tokens, with their prefix and last use. |
POST /api/projects/:project/verify-tokens | Create one: { "label": "production" }. The token is returned once. |
DELETE /api/projects/:project/verify-tokens/:id | Revoke it, immediately and for good. |
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 path | Does |
|---|---|
POST /api/ci/runs | Run 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/:id | The run: status, done, grade, score, headline, fixes, emails, cleanup and report_url. |
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 path | Does |
|---|---|
GET /api/projects/:project/test-hook | The project’s hook: endpoint, actions and state. Never its secret. |
POST /api/projects/:project/test-hook | Add one: { "endpointUrl": "https://...", "actions": [{ "name": "send_trial_ending", "description": "..." }] }. The signing secret is returned once. |
POST /api/projects/:project/test-hook/actions | Replace the declared actions: { "actions": [...] }. |
POST /api/projects/:project/test-hook/test | The three-check connection test. Calls your app. |
POST /api/projects/:project/test-hook/arm | Allow runs; needs a test that passed in the last hour. |
POST /api/projects/:project/test-hook/disable | Stop runs. |
DELETE /api/projects/:project/test-hook | Remove it. |
Your agent triggers an action with the run_test_hook tool. See Testing scheduled emails.