API Reference
This page is a hand-written conceptual overview. The Mako API is a RESTful API built with Hono. All endpoints are prefixed with /api.
Authentication
Section titled “Authentication”Two authentication methods:
- Session cookies — For the web app (set automatically on login)
- API keys — For programmatic access (prefix:
revops_)
# API key authenticationAuthorization: Bearer revops_YOUR_API_KEYCreate API keys in Workspace settings → API Keys. The same page surfaces your Workspace ID (the value to substitute for :wid / :workspaceId / WORKSPACE_ID below) with a copy button.
Auth Endpoints
Section titled “Auth Endpoints”| Method | Endpoint | Description |
|---|---|---|
POST | /api/auth/register | Create account (email/password) |
POST | /api/auth/login | Login, returns session cookie |
GET | /api/auth/me | Get current user session |
POST | /api/auth/logout | End session |
GET | /api/auth/google | Google OAuth redirect |
GET | /api/auth/github | GitHub OAuth redirect |
Workspaces
Section titled “Workspaces”| Method | Endpoint | Description |
|---|---|---|
GET | /api/workspaces | List user’s workspaces |
POST | /api/workspaces | Create a workspace |
GET | /api/workspaces/:id | Get workspace details |
GET | /api/workspaces/:id/settings/limits | Get refresh concurrency limits (dashboardRefreshConcurrency, appBindingRefreshConcurrency; defaults 2, clamped to the per-workspace max) |
PUT | /api/workspaces/:id/settings/limits | Update refresh concurrency limits |
Database Connections
Section titled “Database Connections”These endpoints manage connections to user databases (PostgreSQL, MySQL, MongoDB, BigQuery, ClickHouse, Redshift, SQLite, Cloudflare D1/KV) that Mako queries on the user’s behalf. For SaaS connectors (Stripe, Close, PostHog, GraphQL, REST, BigQuery sync), see SaaS Connectors.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/workspaces/:wid/databases | List database connections |
POST | /api/workspaces/:wid/databases | Add a database connection |
GET | /api/workspaces/:wid/databases/:id | Get a single database connection (passwords masked) |
PUT | /api/workspaces/:wid/databases/:id | Update a database connection |
DELETE | /api/workspaces/:wid/databases/:id | Remove a database connection |
POST | /api/workspaces/:wid/databases/test-connection | Test a candidate connection without saving |
POST | /api/workspaces/:wid/databases/:id/test | Test an existing connection |
POST | /api/workspaces/:wid/databases/demo | Provision the demo Chinook database (onboarding) |
Create and update accept an optional verifyBeforeSave: true flag: the connection is tested before persisting, a failing test refuses the write with a structured connection_test_failed result, and a passing test stamps lastConnectedAt. Without the flag the legacy save-without-testing behavior is kept for programmatic callers. The app UI always sets it (with a “Save anyways” escape hatch).
MongoDB Collections & Views
Section titled “MongoDB Collections & Views”For MongoDB connections, collection and view management is exposed under the same workspace-scoped database routes. The legacy unauthenticated /api/database/* routes were removed in #408 — all callers must use the endpoints below.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/workspaces/:wid/databases/:id/collections | List collections |
POST | /api/workspaces/:wid/databases/:id/collections | Create a collection |
GET | /api/workspaces/:wid/databases/:id/collections/:name | Get collection stats and indexes |
GET | /api/workspaces/:wid/databases/:id/collections/:name/info | Get collection metadata only |
DELETE | /api/workspaces/:wid/databases/:id/collections/:name | Drop a collection |
GET | /api/workspaces/:wid/databases/:id/views | List views |
POST | /api/workspaces/:wid/databases/:id/views | Create a view (viewOn, pipeline) |
GET | /api/workspaces/:wid/databases/:id/views/:name/info | Get view metadata |
DELETE | /api/workspaces/:wid/databases/:id/views/:name | Drop a view |
Query Execution
Section titled “Query Execution”Session cookie or Authorization: Bearer revops_* API key required. Use the database connection ID from GET /api/workspaces/:wid/databases.
| Method | Endpoint | Description |
|---|---|---|
POST | /api/workspaces/:wid/databases/:databaseId/execute | Run a query against a specific connection (body.query) |
POST | /api/workspaces/:wid/execute | Execute with query or queryDefinition; supports pagination via body.pagination |
POST | /api/workspaces/:wid/execute/export | Stream results as format = arrow, parquet, ndjson, or csv |
POST | /api/workspaces/:wid/execute/cancel | Cancel an in-flight query by executionId |
Consoles
Section titled “Consoles”| Method | Endpoint | Description |
|---|---|---|
GET | /api/workspaces/:wid/consoles/list | List all consoles |
GET | /api/workspaces/:wid/consoles/:id/details | Get console details + code |
POST | /api/workspaces/:wid/consoles/:id/execute | Execute a saved console |
GET | /api/workspaces/:wid/consoles/:id/versions | List version history (paginated, newest first) |
GET | /api/workspaces/:wid/consoles/:id/versions/:version | Get a specific version snapshot |
POST | /api/workspaces/:wid/consoles/:id/versions/:version/restore | Restore the console to a past version |
PUT | /api/workspaces/:wid/consoles/:id/schedule | Create or update a saved console schedule (admin only) |
DELETE | /api/workspaces/:wid/consoles/:id/schedule | Remove a saved console schedule (admin only) |
POST | /api/workspaces/:wid/consoles/:id/schedule/run | Trigger a scheduled console immediately (admin only) |
GET | /api/workspaces/:wid/consoles/:id/schedule/runs | List scheduled run history (admin only) |
GET | /api/workspaces/:wid/consoles/:id/executions | List recent query executions with trigger source (?limit=, ~90-day retention) |
GET | /api/workspaces/:wid/scheduled-queries | List scheduled consoles in the workspace (admin only) |
GET | /api/workspaces/:wid/consoles/:id/collaborators | List per-user collaborators |
POST | /api/workspaces/:wid/consoles/:id/collaborators | Add/update a collaborator ({ userId, role }; owner/admin only) |
PATCH | /api/workspaces/:wid/consoles/:id/collaborators/:userId | Change a collaborator’s role (owner/admin only) |
DELETE | /api/workspaces/:wid/consoles/:id/collaborators/:userId | Remove a collaborator (owner/admin only) |
PATCH | /api/workspaces/:wid/consoles/:id/sharing | Update general access ({ access, workspaceRole }; owner/admin only) |
See Console for full API documentation with examples. Scheduled query endpoints require workspace admin access and use the same session/API-key authentication as other workspace endpoints. Version history is covered under Version History.
Source Connections
Section titled “Source Connections”A connector is code (Stripe, Close, PostHog, a workspace-authored ws: connector, …); a source connection is a credential configured with one — what a flow reads from. These routes manage source connections. The primary path is /connections/sources; /connectors is the pre-2026-09 alias and still works. Database connections are under Database Connections. See SaaS Connectors.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/workspaces/:wid/connections/sources | List source connections (credentials masked) |
POST | /api/workspaces/:wid/connections/sources | Add a source connection (secret fields encrypted per the connector’s schema) |
GET | /api/workspaces/:wid/connections/sources/:id | Get one source connection |
PUT | /api/workspaces/:wid/connections/sources/:id | Update a source connection |
DELETE | /api/workspaces/:wid/connections/sources/:id | Remove a source connection |
POST | /api/workspaces/:wid/connections/sources/:id/test | Test the credential |
POST | /api/workspaces/:wid/connections/sources/:id/probe | Probe live: test the credential and read one bounded page of an entity |
GET | /api/workspaces/:wid/connections/sources/:id/entities | Entities the connection’s connector offers |
PATCH | /api/workspaces/:wid/connections/sources/:id/enable | Enable or disable |
The same methods are also served at /api/workspaces/:wid/connectors (and /connectors/:id/…) as a deprecated alias.
Probe Request
Section titled “Probe Request”POST …/connections/sources/:id/probe (or the legacy POST …/connectors/:id/probe) takes an optional JSON body — entity (omit to test the credential only), limit (1–200, default 20), fields (top-level fields to keep), since (ISO 8601 instant, honoured where the connector can) — and answers { success, data: { connection, check, entity?, durationMs } }. entity carries records, schema, count, received, truncated, hasMore and logs. One API page is read and nothing is written; credential values are scrubbed from every string in the result. Errors carry a code (invalid_input, not_found, unknown_entity, timeout, connector_unavailable). Requires a browser session or a legacy (unscoped) API key: scoped MCP keys stay MCP-only, and reach the same probe through the probe_connection tool.
| Method | Endpoint | Description |
|---|---|---|
POST | /api/workspaces/:wid/flows | Create/trigger a flow |
GET | /api/workspaces/:wid/flows/:id | Get flow status |
GET | /api/workspaces/:wid/flows/:id/sync-cdc/status | Get CDC stream status |
GET | /api/workspaces/:wid/flows/:id/sync-cdc/schema-health | Compare live destination column types to the connector schema (BigQuery; detects drift) |
GET | /api/workspaces/:wid/flows/:id/sync-cdc/destination-counts | Batched row counts per entity in the destination |
Destination Counts Response
Section titled “Destination Counts Response”Returns a map of CDC entity name to destination row count. Mako batches BigQuery and PostgreSQL counts into one metadata query and may return 0 for configured entities whose destination table does not exist yet.
{ "success": true, "data": { "contacts": 125000, "organizations": 8421, "opportunities": 0 }}Schema Health Response
Section titled “Schema Health Response”{ "success": true, "data": { "hasDrift": true, "entities": [ { "entity": "customers", "hasDrift": true, "columns": [ { "column": "created_at", "liveType": "STRING", "expectedType": "TIMESTAMP", "status": "drift" }, { "column": "id", "liveType": "STRING", "expectedType": "STRING", "status": "match" } ] } ] }}Accepts an optional ?entity=<name> query parameter to scope the check to a single entity. Drift is auto-corrected on the next CDC merge — see Schema Evolution.
Notification Rules
Section titled “Notification Rules”Email, webhook, and Slack notifications for terminal scheduled-query and flow runs. See Notifications for the full guide and webhook payload shape.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/workspaces/:wid/notification-rules | List rules. Query: resourceType, resourceId. |
GET | /api/workspaces/:wid/notification-rules/deliveries | List recent deliveries. Query: resourceType, resourceId, optional limit. |
POST | /api/workspaces/:wid/notification-rules | Create a rule. Admin only. |
PATCH | /api/workspaces/:wid/notification-rules/:ruleId | Update triggers / channel / enabled flag. Admin only. |
DELETE | /api/workspaces/:wid/notification-rules/:ruleId | Delete a rule. Admin only. |
POST | /api/workspaces/:wid/notification-rules/test | Send a test notification (saved rule by ruleId or ad-hoc channel). |
Webhook deliveries include an X-Mako-Signature HMAC-SHA256 header. The signing secret is returned once as signingSecretOnce on create or rotation and is not retrievable later.
Chat API (AI Agent)
Section titled “Chat API (AI Agent)”The Chat API enables programmatic access to Mako’s AI agent with streaming responses.
| Method | Endpoint | Description |
|---|---|---|
POST | /api/agent/chat | Send messages, receive streaming AI response |
GET | /api/agent/models | List available AI models |
Chat Request
Section titled “Chat Request”curl -X POST https://app.mako.ai/api/agent/chat \ -H "Authorization: Bearer revops_YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "messages": [{"role": "user", "content": "Show me top 10 customers by revenue"}], "chatId": "optional-session-id", "workspaceId": "your-workspace-id", "model": "claude-sonnet-4-20250514" }'Streaming Response
Section titled “Streaming Response”The response is a Server-Sent Events (SSE) stream:
| Event Type | Description |
|---|---|
start | Stream started, contains messageId |
text-delta | Incremental text chunk from assistant |
tool-input-available | Tool call with full input (e.g., SQL query) |
tool-result | Tool execution result (e.g., query results) |
finish | Stream complete, contains finishReason |
Error Codes
Section titled “Error Codes”| Status | Description |
|---|---|
| 400 | Missing or invalid messages, chatId, or workspaceId |
| 401 | Unauthorized (missing or invalid API key) |
| 403 | API key not authorized for the workspace |
| 404 | Agent not found (invalid agentId) |
Chat History
Section titled “Chat History”| Method | Endpoint | Description |
|---|---|---|
GET | /api/workspaces/:wid/chats | List chat sessions |
POST | /api/workspaces/:wid/chats | Create a new chat |
GET | /api/workspaces/:wid/chats/:id | Get chat details |
PUT | /api/workspaces/:wid/chats/:id | Update chat title |
DELETE | /api/workspaces/:wid/chats/:id | Delete a chat |
GET | /api/workspaces/:wid/chat-images/:attachmentId | Fetch a stored chat image attachment (authenticated proxy) |
Skills
Section titled “Skills”Workspace skills — named playbooks the agent can author and load on demand. See Skills for the conceptual model.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/workspaces/:wid/skills | List every skill in the workspace |
GET | /api/workspaces/:wid/skills/:id | Get a single skill with full body |
PUT | /api/workspaces/:wid/skills/:id | Edit loadWhen, body, or entities |
POST | /api/workspaces/:wid/skills/:id/suppress | Toggle the suppressed flag |
DELETE | /api/workspaces/:wid/skills/:id | Permanently delete a skill |
All endpoints require authentication and workspace access. Agent-side CRUD is available through the save_skill, delete_skill, load_skill, and search_skills tools — see AI Agent.
Skill Response Shape
Section titled “Skill Response Shape”{ "success": true, "skill": { "id": "6620...", "name": "mrr_walkthrough_fr", "loadWhen": "Building a sales report or answering questions about MRR in France", "body": "...", "entities": ["mrr", "france", "subscriptions"], "suppressed": false, "useCount": 12, "createdBy": "6612...", "createdAt": "2026-04-23T12:36:00.000Z", "updatedAt": "2026-04-23T12:36:00.000Z" }}Dashboards
Section titled “Dashboards”| Method | Endpoint | Description |
|---|---|---|
GET | /api/workspaces/:wid/dashboards | List dashboards |
POST | /api/workspaces/:wid/dashboards | Create a dashboard |
GET | /api/workspaces/:wid/dashboards/:did | Get dashboard details |
PUT | /api/workspaces/:wid/dashboards/:did | Update dashboard |
DELETE | /api/workspaces/:wid/dashboards/:did | Delete dashboard |
POST | /api/workspaces/:wid/dashboards/:did/duplicate | Duplicate a dashboard |
GET | /api/workspaces/:wid/dashboards/:did/versions | List dashboard version history |
GET | /api/workspaces/:wid/dashboards/:did/versions/:version | Get a specific dashboard version |
POST | /api/workspaces/:wid/dashboards/:did/versions/:version/restore | Restore dashboard to a past version |
POST | /api/workspaces/:wid/dashboards/:did/version-comment | AI-suggested commit message for pending changes |
GET | /api/workspaces/:wid/dashboards/:did/collaborators | List per-user collaborators |
POST | /api/workspaces/:wid/dashboards/:did/collaborators | Add/update a collaborator ({ userId, role }, role viewer|editor; owner/admin only) |
PATCH | /api/workspaces/:wid/dashboards/:did/collaborators/:userId | Change a collaborator’s role (owner/admin only) |
DELETE | /api/workspaces/:wid/dashboards/:did/collaborators/:userId | Remove a collaborator (owner/admin only) |
PATCH | /api/workspaces/:wid/dashboards/:did/sharing | Update general access ({ access, workspaceRole }; owner/admin only) |
POST | /api/workspaces/:wid/dashboards/:did/public-share | Enable/create a public link ({ password? }; owner/admin only) |
GET | /api/workspaces/:wid/dashboards/:did/public-share/password | Reveal the public-link password (owner/admin only) |
PATCH | /api/workspaces/:wid/dashboards/:did/public-share | Update password / rotate token / rename slug (owner/admin only) |
DELETE | /api/workspaces/:wid/dashboards/:did/public-share | Disable the public link (owner/admin only) |
Dashboard Folders
Section titled “Dashboard Folders”| Method | Endpoint | Description |
|---|---|---|
GET | /api/workspaces/:wid/dashboard-folders | List dashboard folders |
POST | /api/workspaces/:wid/dashboard-folders | Create a folder |
PUT | /api/workspaces/:wid/dashboard-folders/:fid | Update a folder |
DELETE | /api/workspaces/:wid/dashboard-folders/:fid | Delete a folder |
Dashboard Materialization
Section titled “Dashboard Materialization”| Method | Endpoint | Description |
|---|---|---|
GET | /api/workspaces/:wid/dashboards/:did/materialization/status | Get materialization status for all data sources |
POST | /api/workspaces/:wid/dashboards/:did/materialization/trigger | Trigger materialization for a data source |
POST | /api/workspaces/:wid/dashboards/:did/materialization/trigger-all | Trigger materialization for all data sources |
GET | /api/workspaces/:wid/dashboards/:did/materialization/stream/:dataSourceId | Stream Parquet artifact (supports range requests) |
Git-backed React apps built inside the workspace (Apps). Private apps are owner-only — admins and API keys cannot access another member’s private app. The workspace repo itself is served over git HTTP at /api/apps-git/:workspaceId.git (scoped git token).
| Method | Endpoint | Description |
|---|---|---|
GET | /api/workspaces/:wid/apps | List app projects visible to the caller |
POST | /api/workspaces/:wid/apps | Create an app (scaffolds a Vite + React project) |
GET | /api/workspaces/:wid/apps/:id | Get an app project (metadata, branch, publish state) |
DELETE | /api/workspaces/:wid/apps/:id | Delete an app |
GET | /api/workspaces/:wid/apps/:id/files / …/file | List / read files on the working branch |
PUT | /api/workspaces/:wid/apps/:id/file | Write a file to the working branch |
POST | /api/workspaces/:wid/apps/:id/exec | Run a shell command in the app’s sandbox |
GET | /api/workspaces/:wid/apps/:id/status / …/history / …/branches | Working-tree status, commit history, branches |
POST | /api/workspaces/:wid/apps/:id/commit / …/merge / …/checkout / …/discard | Git operations on the working branch |
GET | /api/workspaces/:wid/apps/:id/bindings | List data bindings (bindings/*.sql) |
POST | /api/workspaces/:wid/apps/:id/bindings/:name/materialize | Build/rebuild a binding’s Parquet artifact |
GET | /api/workspaces/:wid/apps/:id/bindings/:name/artifact | Stream the materialized Parquet artifact |
POST | /api/workspaces/:wid/apps/:id/publish / …/rollback | Build & publish a main commit / repoint the deployment |
POST | /api/workspaces/:wid/apps/:id/preview / …/dev-preview | Published-build preview / live dev server preview |
POST | /api/workspaces/:wid/apps/:id/public-share | Manage the anonymous public link (also PATCH/DELETE) |
GET | /api/workspaces/:wid/apps/:id/sandbox | Sandbox status (also POST …/sandbox/recycle) |
Notebooks
Section titled “Notebooks”Notebook CRUD, kernel sessions, executions, versions, presence, and the kernel’s read-only data plane live under /api/workspaces/:workspaceId/notebooks and …/notebook/*. See Notebooks for the route table and the OpenAPI spec for full schemas.
Public Shares
Section titled “Public Shares”Token-gated, read-only endpoints for published dashboard/app links. These are intentionally unauthenticated (no session or API key) and serve only materialized snapshots.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/share/:token | Get public-share metadata (title, whether a password is required) |
POST | /api/share/:token/unlock | Exchange a password for access to a protected link |
GET | /api/share/:token/content | Get the shared resource’s materialized content |
GET | /api/share/:token/artifacts/:artifactId | Stream a materialized Parquet artifact (supports range requests) |
POST | /api/share/:token/refresh | Throttled anonymous re-materialization of the snapshot |
Inngest
Section titled “Inngest”| Method | Endpoint | Description |
|---|---|---|
POST | /api/inngest | Inngest webhook handler (internal) |
Billing
Section titled “Billing”Subscription management endpoints. All require workspace membership. When BILLING_ENABLED is false (self-hosted default), all endpoints return { "billingEnabled": false }.
| Method | Endpoint | Description |
|---|---|---|
GET | /api/workspaces/:wid/billing/status | Get plan, usage quota, and subscription status |
POST | /api/workspaces/:wid/billing/checkout | Create a Stripe Checkout session (returns { url }) |
POST | /api/workspaces/:wid/billing/portal | Create a Stripe Customer Portal session (returns { url }) |
Billing Status Response
Section titled “Billing Status Response”{ "billingEnabled": true, "plan": "free", "subscriptionStatus": null, "usageQuotaUsd": 5, "hardLimitUsd": 5, "currentUsageUsd": 1.23, "modelTier": "free", "maxDatabases": 3, "maxMembers": 3}Error Codes
Section titled “Error Codes”| Status | Description |
|---|---|
| 403 | Not a workspace owner or admin |
| 409 | Active subscription already exists (on checkout) |