Funnelkeeper for AI agents
You build the product; Funnelkeeper is the money layer you read from and propose into. Everything on this page is also in /llms.txt — the short version an agent should fetch first.
How do you install Funnelkeeper?
https://funnelkeeper.com/llms.txt https://funnelkeeper.fly.dev https://funnelkeeper.com/openapi.json npx -y funnelkeeper funnelkeeper-mcp https://funnelkeeper.com/docs/quickstart-agents.md
Auth: Authorization: Bearer fk_live_… — an
account API key your user mints in the dashboard or with fk login.
What can you do through the MCP endpoint?
funnel.read read GET /products/{slug}/funnel · MCP get_funnel payback.read read GET /products/{slug}/payback · MCP get_payback spend.read read GET /products/{slug}/spend · MCP get_spend events.log write POST /distribution · MCP log_distribution budget.propose proposal POST /products/{slug}/proposals · MCP propose_budget_change What guarantees can you make to your user?
You cannot spend money
budget.propose is the only write that touches an ad network, and it returns pending_human. Approval happens in the app, by a person — backed by a database constraint, not a prompt.
Every action is on the record
Each call is logged with the acting account, arguments and outcome. The user can read the log and revoke your key from the dashboard.
Policy caps are not advisory
Caps are enforced at the API boundary. A proposal above the cap is rejected with policy_code: policy_refused rather than escalated to a human.
What does a proposal look like?
The only write that can lead to an ad-network change. It queues; a person decides. This is the live contract — the 202 and 422 below are real responses from the production API.
POST /products/ledgerly/proposals
{
"network": "meta",
"campaign_id": "prospecting-us",
"from_cents": 400,
"to_cents": 800,
"rationale": "Cohort from Jul 12 reached payback on day 19 at $58 CAC. Cap binding 6 of last 7 days.",
"rollback_if": { "cac_usd_above": 80, "window_days": 5 }
}
→ 202 Accepted
{ "proposal_id": "53825372-…", "status": "pending_human", "expires_in_hours": 72 }
→ 422 when over a policy cap
{ "error": "Exceeds product daily cap ($4.00/day for current stage).", "policy_code": "policy_refused" }