Skip to content

HTTP routes

All routes registered by the Opslane API (packages/ingestion/handler/routes.go). Auth column legend: none (public), poll token (X-Opslane-Poll-Token for one automated repository setup), SDK (X-API-Key project-scoped public ingest key; rate-limited per project, and origin-gated on browser requests), and session (signed-in dashboard session).

These are curated tables, not a stability contract. The API is early-stage and may change. The drift check fails the repository test gate (pnpm test, which CI runs) if this page and routes.go disagree.

MethodPathAuthPurpose
GET/healthnoneLiveness + dependency checks
GET/metricsnoneInternal metrics
POST/auth/refreshnoneRotate session tokens
GET/auth/confignoneDiscover embedded sign-in, sign-up, and password-reset capabilities
POST/auth/passwordnoneSign in with provider-managed email and password; issues local session cookies
POST/auth/signupnoneCreate a provider account and begin required email verification
POST/auth/verify-emailnoneComplete email verification and issue local session cookies
POST/auth/oauth/verify-emailflow cookie + same originComplete a hosted OAuth email challenge and resume sign-in
POST/auth/password/forgotnoneSend a password-reset email with an enumeration-safe response
POST/auth/password/resetnoneSet a new password from a reset token and revoke local refresh sessions
GET/auth/loginnoneBegin the configured identity-provider sign-in
GET/auth/githubnoneCompatibility redirect to /auth/login
GET/auth/callbacknoneConfigured identity-provider callback
GET/auth/github/callbacknoneCompatibility callback alias for existing GitHub App configurations
GET+POST/oauth/authorizenoneBegin an authorization request using PKCE
POST/oauth/tokennoneExchange a PKCE authorization code for a session token
POST/api/v1/agent/setupnoneStart automated repository setup
GET/api/v1/agent/poll/{sessionID}poll token (X-Opslane-Poll-Token)Check automated repository setup status
GET/agent/auth/{sessionID}noneBrowser authentication for automated repository setup
GET/agent/auth/callbacknoneAuthentication callback for automated repository setup
POST/api/v1/github/webhookHMACReceive GitHub pull-request and default-branch push events; requires X-GitHub-Delivery (400 without it). Push events refresh Opslane’s understanding of your pages and user actions.
POST/mcpMCP key in Authorization: Bearer ...Call the remote MCP tools for one project

The automated-setup callback requires code, installation_id, and UUID state. It returns final failures to the setup client as machine-readable reasons when the client checks status. /auth/callback sends GitHub App installs with a UUID state to automated setup and handles other states through the existing browser login and installation process.

MethodPathOrigin-gatedPurpose
POST/api/v1/eventsbrowser callers onlyStore an error event and queue source-map processing. Receiving an error does not immediately create an issue, investigation, or alert.
POST/api/v1/replays/inityesBegin a replay upload
POST/api/v1/replays/{replayID}/completeyesFinish a replay upload
POST/api/v1/replays/{replayID}/failyesRecord a replay upload failure
POST/api/v1/sessions/inityesRegister a tenant-owned session with optional payload environment; returns whether the project allows session recording
POST/api/v1/sessions/{sessionID}/chunks/{seq}yesStore and commit one gzipped replay chunk (max 5MiB)
POST/api/v1/ingest/pingnoVerify that a public ingest key still authenticates; returns 204 without project data
MethodPathAuthPurpose
PUT/api/v1/sourcemaps/{debugID}secret source-map keyUpload one immutable source map after the server verifies its build identifier, which matches the map to a built file
MethodPathPurpose
GET/api/v1/auth/meCurrent user
GET/api/v1/auth/verifyValidate session
POST/api/v1/auth/logoutEnd session
POST/auth/switch-orgCloud only: rotate the current session into another member organization
GET/api/v1/invitationsCloud org admin: list active-org invitations
POST/api/v1/invitationsCloud org admin: create an active-org invitation
DELETE/api/v1/invitations/{invitationID}Cloud org admin: revoke an outstanding invitation
POST/api/v1/invitations/acceptCloud: accept a single-use, verified-email-bound invitation
GET/api/v1/admin/overviewOperator-only cross-tenant monitoring overview, including best-effort progress through automated repository setup (404 unless allowlisted)
GET/api/v1/admin/jobsOperator-only recent jobs (404 unless allowlisted)
POST/api/v1/onboard/provisionCreate an organization and project for a repository, then store the one-time API key for the setup client to retrieve
POST/api/v1/onboarding/setupCreate or resume the first project and return a fresh ingest key
GET/api/v1/onboarding/stateRead server-derived onboarding facts and the next step
POST/api/v1/onboarding/completeMark onboarding complete after the project receives its first event; GitHub and Slack are optional (admin on cloud)
GET/api/v1/projectsList projects
POST/api/v1/projectsCreate project
PATCH/api/v1/projects/{projectID}Update project settings. friction_autonomy controls automatic fixes for session-recording issues; pr_posture controls whether unverified fixes may open as drafts. A same-project default_environment_id must be an explicit UUID string when present.
GET/api/v1/projects/{projectID}/fix-statsFix-attempt and pull-request outcome counts by issue type
GET/api/v1/projects/{projectID}/environmentsList all environments, or only environments that contain issues with used_by=incidents or sessions with used_by=sessions
GET/api/v1/projects/{projectID}/event-countReturn has_events and the nullable latest_error_group_id
GET/api/v1/projects/{projectID}/digest/latestLatest delivered daily summary, or an empty summary when none has been delivered
POST/api/v1/projects/{projectID}/api-keysCreate an MCP key or, with scope: "ingest", a browser ingest key; the secret is returned once (admin)
GET/api/v1/projects/{projectID}/api-keysList the project’s MCP and ingest keys without showing their secrets (admin)
DELETE/api/v1/projects/{projectID}/api-keys/{keyID}Revoke an MCP or ingest key (admin)
GET/api/v1/projects/{projectID}/incidentsList issues
GET/api/v1/projects/{projectID}/incidents/{incidentID}Issue detail
GET/api/v1/projects/{projectID}/incidents/{incidentID}/evidenceSaved stack frames, failed requests, links to recordings, and available supporting data for the current issue
GET/api/v1/projects/{projectID}/notification-destinationsList project notification destinations and recent delivery state
POST/api/v1/projects/{projectID}/notification-destinationsCreate a Slack notification destination
PATCH/api/v1/projects/{projectID}/notification-destinations/{destID}Update a notification destination
DELETE/api/v1/projects/{projectID}/notification-destinations/{destID}Delete a notification destination
POST/api/v1/projects/{projectID}/notification-destinations/{destID}/testSend a test notification
GET/api/v1/projects/{projectID}/replays/{replayID}Fetch a replay
GET/api/v1/projects/{projectID}/sessionsList sessions with filters and keyset pagination
GET/api/v1/projects/{projectID}/sessions/{sessionID}Session detail and recording metadata with sensitive values removed
GET/api/v1/projects/{projectID}/sessions/{sessionID}/chunks/{seq}Fetch one decoded, redacted part of the recording
GET/api/v1/projects/{projectID}/incidents/{incidentID}/affected-usersAffected users
GET/api/v1/projects/{projectID}/incidents/{incidentID}/sample-eventFetch the redacted representative error event for traceback, breadcrumbs, and request context
POST/api/v1/projects/{projectID}/incidents/{incidentID}/fixStart a fix for an issue that is ready to fix, whether it came from an error or a session recording
POST/api/v1/projects/{projectID}/incidents/{incidentID}/reviewRequest another short repository review for the current issue; reuses an investigation already in progress
POST/api/v1/projects/{projectID}/incidents/{incidentID}/link-prRecord a same-repository GitHub pull request without marking the issue resolved
POST/api/v1/projects/{projectID}/incidents/{incidentID}/resolveResolve issue
POST/api/v1/projects/{projectID}/incidents/{incidentID}/archiveArchive issue
POST/api/v1/projects/{projectID}/incidents/{incidentID}/snoozeSnooze an actionable issue for up to 30 days; a null or past until clears the snooze
POST/api/v1/projects/{projectID}/incidents/{incidentID}/unarchiveRestore archived issue
GET/api/v1/projects/{projectID}/accountsList B2B accounts
GET/api/v1/projects/{projectID}/accounts/{accountID}Account detail
GET/api/v1/projects/{projectID}/accounts/{accountID}/incidentsIssues for one account
GET/api/v1/github/setupGitHub App install callback
GET/api/v1/github/statusGitHub App status
GET/api/v1/github/reposList installable repos
PUT/api/v1/projects/{projectID}/githubSet project repo config
GET/api/v1/projects/{projectID}/githubGet project repo config
DELETE/api/v1/projects/{projectID}/githubRemove project repo config
MethodPathAuthPurpose
GET/internal/v1/projects/{projectID}/sessions/{sessionID}/chunks/{seq}X-Internal-TokenWorker fetch of one decoded, redacted part of the recording
GET/internal/v1/projects/{projectID}/incidents/{incidentID}/statusX-Internal-TokenRead one issue’s status for the deployment smoke test

A request whose path is registered but whose method is not returns a JSON 404, not a 405. The router sets one MethodNotAllowed handler, so this holds for every route above; an unregistered method is indistinguishable from an unregistered path. Handlers that write 405 themselves (password-reset flows) are unaffected.

Any other path serves the dashboard SPA from DASHBOARD_DIR (missing static assets 404 rather than falling back to index.html).