Skip to content

Cloud API

SnakeFlow Cloud is served by the snakeflow-api Cloudflare Worker (api/ in the monorepo). All routes live under /api.

Base URLs

ClientURLNotes
VS Code / Cursor extensiondevManager.cloud.apiUrl (default https://snakeflow-api.pro-connect.workers.dev)Direct Worker URL; sends Authorization: Bearer <JWT>.
Web dashboard (Pages)https://snakeflow-cloud.pages.dev/api/*Proxied to the Worker; browser uses HttpOnly sf_token cookie.
Docs site (Scalar UI)snakeflow.pages.dev/api-reference/Interactive OpenAPI browser (core sync endpoints only).

The extension and dashboard hit the same route handlers; only transport (header vs cookie) differs.

Authentication

Extension / CI — JWT via GitHub token

POST /api/auth/verify
Content-Type: application/json
{ "github_token": "<GitHub PAT or OAuth token>" }

Response 200: { "token": "<JWT>", "login": "...", "avatar_url": "..." } — JWT valid 30 days (HS256).

Send on protected calls:

Authorization: Bearer <token>
MethodPathDescription
GET/api/auth/githubRedirect to GitHub OAuth (read:user). Sets CSRF state cookie.
GET/api/auth/callbackOAuth callback; sets HttpOnly sf_token JWT cookie.
POST/api/auth/logoutClears session cookies. { "ok": true }

Callback URLs use SITE_URL (dashboard origin) when set.

Settings access model

Repository settings are gated by workspace membership (there is no /permissions endpoint):

  • A repo must match at least one workspace repo pattern (owner/*, exact owner/repo, etc.).
  • Admin of a matching workspace → push, pull, delete settings.
  • Member of a matching workspace → pull only.
  • First push to a personal repo (owner === your GitHub login) with no workspace → API auto-creates a personal workspace {login} with pattern {login}/*.
  • Org repos with no matching workspace → 409 workspace_required with a suggested pattern.

X-GitHub-Token is required for PUT /api/settings/:owner/:repo (GitHub repo access check). It is not stored on the server. GET and DELETE use JWT + workspace role only.

Main routes (/api/*)

MethodPathAuthDescription
POST/auth/verifyExchange GitHub token for JWT.
GET/meJWTProfile: id, login, plan, status. Effective plan is pro while billing is dormant.
GET/projectsJWTRepositories visible via workspace patterns.
GET/settings/:owner/:repoJWTPull settings snapshot. 404 if never synced.
PUT/settings/:owner/:repoJWT + X-GitHub-TokenPush { "settings": { "devManager.*": … } }.
DELETE/settings/:owner/:repoJWTRemove synced row for repo.
POST/billing/checkoutJWTPaddle checkout URL (billing dormant).
POST/billing/portalJWTPaddle subscription management URL.
POST/paddle/webhookPaddle signatureSubscription lifecycle (server-to-server).
GET/claude-models?apiKey=JWTProxy Anthropic model list (caller-supplied key).
GET/gemini-models?apiKey=JWTProxy Google Gemini model list (caller-supplied key).
POST/eventsJWTActivation funnel event { "event", "source" }.
GET/admin/funnelAdmin keyActivation metrics (?key= or X-Snakeflow-Admin-Key).

Team routes (/api/team/*)

All team routes require JWT. POST /workspaces/join skips the Pro gate; other routes pass through requirePro (currently always allowed while billing is dormant).

Profile & activity

MethodPathRoleDescription
GET/meanyWorkspaces for caller.
GET/dashboard?workspace=&from=&to=adminTeam dashboard aggregates. Dates YYYY-MM-DD.
GET/active-minutes?day=memberInternal minutes per workspace for a UTC day.
POST/active-minutesmemberFlush { "entries": [...], "timezone"?: "IANA" }. Max 200 entries.
POST/commitsadminDaily commit counts by member/repo.
POST/closed-issuesadminDaily closed-issue counts by member/repo.
GET/effective-config?repo=owner/repomemberMerged workspace + project overrides for plugin auto-pull.

Workspaces

MethodPathRoleDescription
POST/workspaces/createPro gateCreate workspace + initial invite.
POST/workspaces/joinJWTJoin via invite code.
DELETE/workspaces/:idadminDelete workspace and related data.
GET/workspaces/:id/membersmemberMember list.
DELETE/workspaces/:id/members?login=adminRemove member.
PATCH/workspaces/:id/membersadminChange member role.
GET/workspaces/:id/invitesadminActive invites.
POST/workspaces/:id/invitesadminCreate invite.
GET/workspaces/:id/patternsmemberList repo patterns.
PUT/workspaces/:id/patternsadminReplace repo patterns.
GET/workspaces/:id/settingsmemberWorkspace idle_window_minutes + settings blob.
PATCH/workspaces/:id/settingsadminUpdate idle window and/or merge settings keys.
GET/workspaces/:id/project-settingsmemberPer-repo overrides in workspace.
PUT/workspaces/:id/project-settings/:owner/:repoadminSet project-level overrides.
DELETE/workspaces/:id/project-settings/:owner/:repoadminRemove project override.

Limits (server-enforced)

AreaLimit
Repo patterns per workspace50 patterns, 200 chars each
Workspace name1–100 chars
Active-minutes flush200 entries/request; 1440 min/day; 60 min/hour (heatmap)
Commit / closed-issue sync500 members; 200 repos/member; count 0–10 000
Workspace settings JSON256 KB max
idle_window_minutes1–15 (server); client clamps effective idle to 5–10 min

CORS

/api/* allows known dashboard origins with credentials; other origins get *. Allowed headers: Authorization, Content-Type, X-GitHub-Token, Paddle-Signature.

Local development

Terminal window
cd api
cp .dev.vars.example .dev.vars
npm run dev

Deploy: npm run deploy (D1 migrations + wrangler deploy).

See also: Cloud settings sync →, Team Tracker →, Scalar API reference →.