{"openapi":"3.1.0","info":{"title":"BuilderGraph API","version":"0.3.0","description":"Crypto developer activity, indexed for decisions. Repos, contributors, and ecosystems seeded from Electric Capital Open Dev Data and continuously enriched with GitHub metadata. Public endpoints are rate-limited per IP (100 req/min); authenticated endpoints accept a `bg_live_*` subscriber key via the `X-API-Key` header. The same dataset is exposed over MCP (JSON-RPC 2.0) at POST /api/mcp.","contact":{"url":"https://buildergraph.dev/docs"}},"servers":[{"url":"https://api.buildergraph.dev"}],"tags":[{"name":"public","description":"Free, rate-limited per IP"},{"name":"signals","description":"Pre-aggregated, stable-shape snapshots"},{"name":"subscriber","description":"Requires an active Pro/Team API key (X-API-Key)"},{"name":"talent","description":"Session-cookie authenticated Builder Maps for paid BuilderGraph accounts"},{"name":"account","description":"Session-cookie authenticated (web app)"},{"name":"meta","description":"Service metadata"}],"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Subscriber key (`bg_live_…`) issued on subscription."}}},"paths":{"/api/health":{"get":{"tags":["meta"],"summary":"Service health","responses":{"200":{"description":"Worker and D1 reachable","content":{"application/json":{"schema":{"type":"object"}}}},"503":{"description":"D1 unreachable"}}}},"/api/v1/stats":{"get":{"tags":["public"],"summary":"Corpus-wide coverage stats","responses":{"200":{"description":"Repo/contributor/ecosystem counts and scraper freshness","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/ecosystems":{"get":{"tags":["public"],"summary":"List ecosystems","parameters":[{"name":"q","in":"query","required":false,"description":"Full-text search over name/slug","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Max rows to return","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","required":false,"description":"Rows to skip","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Ecosystem list with enriched repo counts","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/ecosystems/{slug}":{"get":{"tags":["public"],"summary":"Ecosystem detail","parameters":[{"name":"slug","in":"path","required":true,"description":"Ecosystem slug, e.g. `ethereum`","schema":{"type":"string"}}],"responses":{"200":{"description":"Ecosystem with top repos and contributors","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/ecosystems/{slug}/trends":{"get":{"tags":["public"],"summary":"Weekly metric history for an ecosystem","parameters":[{"name":"slug","in":"path","required":true,"description":"Ecosystem slug","schema":{"type":"string"}},{"name":"window","in":"query","required":false,"description":"Number of weeks of history","schema":{"type":"integer"}}],"responses":{"200":{"description":"Week-by-week aggregates","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/ecosystems/compare":{"get":{"tags":["subscriber"],"summary":"Side-by-side ecosystem comparison","security":[{"apiKey":[]}],"parameters":[{"name":"slugs","in":"query","required":false,"description":"Comma-separated ecosystem slugs","schema":{"type":"string"}},{"name":"window","in":"query","required":false,"description":"Number of weeks of history","schema":{"type":"integer"}}],"responses":{"200":{"description":"Comparison across the requested ecosystems","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing or inactive API key"}}}},"/api/v1/repos":{"get":{"tags":["public"],"summary":"Search/list repositories","parameters":[{"name":"q","in":"query","required":false,"description":"Full-text search over name/description/topics","schema":{"type":"string"}},{"name":"ecosystem","in":"query","required":false,"description":"Filter by ecosystem slug","schema":{"type":"string"}},{"name":"language","in":"query","required":false,"description":"Filter by primary language","schema":{"type":"string"}},{"name":"stars_min","in":"query","required":false,"description":"Minimum stars","schema":{"type":"integer"}},{"name":"stars_max","in":"query","required":false,"description":"Maximum stars","schema":{"type":"integer"}},{"name":"sort","in":"query","required":false,"description":"Sort order","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Max rows to return","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","required":false,"description":"Rows to skip","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Repository list","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/repos/{id}":{"get":{"tags":["public"],"summary":"Repository detail","parameters":[{"name":"id","in":"path","required":true,"description":"Repository id","schema":{"type":"string"}}],"responses":{"200":{"description":"Repository with contributors, tags, ecosystem","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/repo/{owner}/{name}/signal":{"get":{"tags":["signals"],"summary":"Opinionated repo signal (stable shape, additive only)","parameters":[{"name":"owner","in":"path","required":true,"description":"GitHub owner","schema":{"type":"string"}},{"name":"name","in":"path","required":true,"description":"Repo name","schema":{"type":"string"}}],"responses":{"200":{"description":"Pre-joined snapshot with categorical `pulse` (hot/steady/quiet/dormant)","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/ecosystem/{slug}/snapshot":{"get":{"tags":["signals"],"summary":"Opinionated ecosystem snapshot (stable shape)","parameters":[{"name":"slug","in":"path","required":true,"description":"Ecosystem slug","schema":{"type":"string"}}],"responses":{"200":{"description":"Pre-aggregated ecosystem snapshot","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/contributors":{"get":{"tags":["public"],"summary":"Search/list contributors","parameters":[{"name":"q","in":"query","required":false,"description":"Full-text search over login/name/company/bio","schema":{"type":"string"}},{"name":"ecosystem","in":"query","required":false,"description":"Filter by ecosystem slug","schema":{"type":"string"}},{"name":"language","in":"query","required":false,"description":"Filter by language","schema":{"type":"string"}},{"name":"min_followers","in":"query","required":false,"description":"Minimum followers","schema":{"type":"integer"}},{"name":"min_repos","in":"query","required":false,"description":"Minimum public repos","schema":{"type":"integer"}},{"name":"min_contributions","in":"query","required":false,"description":"Minimum contribution count","schema":{"type":"integer"}},{"name":"sort","in":"query","required":false,"description":"followers | contributions | repos","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Max rows to return","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","required":false,"description":"Rows to skip","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Contributor list","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/contributors/{login}":{"get":{"tags":["public"],"summary":"Contributor profile","parameters":[{"name":"login","in":"path","required":true,"description":"GitHub login","schema":{"type":"string"}}],"responses":{"200":{"description":"Contributor with top repos and ecosystems","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/orgs":{"get":{"tags":["public"],"summary":"List GitHub organizations","parameters":[{"name":"limit","in":"query","required":false,"description":"Max rows to return","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","required":false,"description":"Rows to skip","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Organization list","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/orgs/{login}":{"get":{"tags":["public"],"summary":"Organization profile","parameters":[{"name":"login","in":"path","required":true,"description":"GitHub org login","schema":{"type":"string"}}],"responses":{"200":{"description":"Organization with repos and members","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/languages":{"get":{"tags":["public"],"summary":"Language index","responses":{"200":{"description":"Languages with repo counts","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/tags":{"get":{"tags":["public"],"summary":"Repository tag index","responses":{"200":{"description":"Tags with repo counts","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/categories":{"get":{"tags":["public"],"summary":"Ecosystem category index","responses":{"200":{"description":"Categories from the EC taxonomy","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/spotlights":{"get":{"tags":["public"],"summary":"Editorial spotlights","parameters":[{"name":"limit","in":"query","required":false,"description":"Max rows","schema":{"type":"integer"}}],"responses":{"200":{"description":"Published spotlights","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/exports/repos":{"get":{"tags":["subscriber"],"summary":"Bulk repo export (CSV or JSON)","security":[{"apiKey":[]}],"parameters":[{"name":"format","in":"query","required":false,"description":"csv | json","schema":{"type":"string"}},{"name":"ecosystem","in":"query","required":false,"description":"Filter by ecosystem slug","schema":{"type":"string"}}],"responses":{"200":{"description":"Bulk export. Row caps by tier: Pro 10K, Team 100K."},"401":{"description":"Missing or inactive API key"}}}},"/api/v1/exports/contributors":{"get":{"tags":["subscriber"],"summary":"Bulk contributor export (CSV or JSON)","security":[{"apiKey":[]}],"parameters":[{"name":"format","in":"query","required":false,"description":"csv | json","schema":{"type":"string"}}],"responses":{"200":{"description":"Bulk export. Row caps by tier: Pro 5K, Team 50K."},"401":{"description":"Missing or inactive API key"}}}},"/api/v1/me/access":{"get":{"tags":["account"],"summary":"Session access probe (web app)","responses":{"200":{"description":"Signed-in state and subscription plan","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/talent/projects":{"get":{"tags":["talent"],"summary":"List Builder Maps for the signed-in paid account","responses":{"200":{"description":"Saved Builder Maps with candidate counts","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Missing session"},"403":{"description":"Email verification or paid access required"}}},"post":{"tags":["talent"],"summary":"Create a Builder Map","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"filters":{"type":"object"}},"required":["name"]}}}},"responses":{"201":{"description":"Builder Map created"},"401":{"description":"Missing fresh session"},"403":{"description":"Paid access required"}}}},"/api/v1/talent/projects/{id}":{"get":{"tags":["talent"],"summary":"Get a Builder Map","parameters":[{"name":"id","in":"path","required":true,"description":"Builder Map id","schema":{"type":"string"}}],"responses":{"200":{"description":"Builder Map metadata","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Project not found for this account"}}},"patch":{"tags":["talent"],"summary":"Update a Builder Map","parameters":[{"name":"id","in":"path","required":true,"description":"Builder Map id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Updated Builder Map metadata","content":{"application/json":{"schema":{"type":"object"}}}}}},"delete":{"tags":["talent"],"summary":"Archive a Builder Map","parameters":[{"name":"id","in":"path","required":true,"description":"Builder Map id","schema":{"type":"string"}}],"responses":{"200":{"description":"Archive confirmation","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/talent/projects/{id}/candidates":{"get":{"tags":["talent"],"summary":"List saved candidates for a Builder Map","parameters":[{"name":"id","in":"path","required":true,"description":"Builder Map id","schema":{"type":"string"}}],"responses":{"200":{"description":"Candidates with public contribution evidence, notes, tags, and stage","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"tags":["talent"],"summary":"Save a contributor to a Builder Map","parameters":[{"name":"id","in":"path","required":true,"description":"Builder Map id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"contributor_id":{"type":"integer"},"github_login":{"type":"string"},"stage":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"fit_note":{"type":"string"}}}}}},"responses":{"201":{"description":"Candidate saved"},"404":{"description":"Project or contributor not found"}}}},"/api/v1/talent/projects/{id}/candidates/{contributor_id}":{"patch":{"tags":["talent"],"summary":"Update saved candidate stage, tags, or fit note","parameters":[{"name":"id","in":"path","required":true,"description":"Builder Map id","schema":{"type":"string"}},{"name":"contributor_id","in":"path","required":true,"description":"Contributor id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Candidate update confirmation","content":{"application/json":{"schema":{"type":"object"}}}}}},"delete":{"tags":["talent"],"summary":"Remove a saved candidate from a Builder Map","parameters":[{"name":"id","in":"path","required":true,"description":"Builder Map id","schema":{"type":"string"}},{"name":"contributor_id","in":"path","required":true,"description":"Contributor id","schema":{"type":"string"}}],"responses":{"200":{"description":"Candidate removal confirmation","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/talent/projects/{id}/notes":{"post":{"tags":["talent"],"summary":"Add an internal note to a saved candidate","parameters":[{"name":"id","in":"path","required":true,"description":"Builder Map id","schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"contributor_id":{"type":"integer"},"note":{"type":"string"}},"required":["contributor_id","note"]}}}},"responses":{"201":{"description":"Note created"},"404":{"description":"Candidate not found in project"}}}},"/api/v1/talent/projects/{id}/export":{"get":{"tags":["talent"],"summary":"Export a Builder Map as JSON or CSV","parameters":[{"name":"id","in":"path","required":true,"description":"Builder Map id","schema":{"type":"string"}},{"name":"format","in":"query","required":false,"description":"json | csv","schema":{"type":"string","default":"json"}}],"responses":{"200":{"description":"Builder Map export","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/me/keys":{"get":{"tags":["account"],"summary":"List API keys (masked)","responses":{"200":{"description":"Masked keys with tier/status/last-used","content":{"application/json":{"schema":{"type":"object"}}}},"403":{"description":"Email not verified"}}}},"/api/v1/me/keys/regenerate":{"post":{"tags":["account"],"summary":"Rotate an API key (returned once)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer"}},"required":["id"]}}}},"responses":{"200":{"description":"New raw key — shown once","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Key not found for this account"}}}},"/api/v1/me/keys/revoke":{"post":{"tags":["account"],"summary":"Revoke an API key","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer"}},"required":["id"]}}}},"responses":{"200":{"description":"Revocation confirmed","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Key not found for this account"}}}},"/api/v1/me/usage":{"get":{"tags":["account"],"summary":"Current-month API usage by endpoint","responses":{"200":{"description":"Per-endpoint call counts for the month","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/me":{"delete":{"tags":["account"],"summary":"Delete account (GDPR erasure)","description":"Cancels active Stripe subscriptions, revokes API keys, and deletes sessions, OAuth links, claims, and the user row. Financial records are retained as required by law.","responses":{"200":{"description":"Account deleted","content":{"application/json":{"schema":{"type":"object"}}}},"502":{"description":"A live subscription could not be canceled — nothing was deleted"}}}},"/api/agent":{"get":{"tags":["public"],"summary":"Agent surface discovery","responses":{"200":{"description":"Service descriptor. Authenticated calls use subscriber API keys.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/mcp":{"post":{"tags":["subscriber"],"summary":"MCP endpoint (JSON-RPC 2.0)","security":[{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","description":"JSON-RPC 2.0 envelope. Methods: initialize, tools/list, tools/call."}}}},"responses":{"200":{"description":"JSON-RPC 2.0 response","content":{"application/json":{"schema":{"type":"object"}}}}}}}}}