Skip to content

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.

Two authentication methods:

  1. Session cookies — For the web app (set automatically on login)
  2. API keys — For programmatic access (prefix: revops_)
Terminal window
# API key authentication
Authorization: Bearer revops_YOUR_API_KEY

Create 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.

MethodEndpointDescription
POST/api/auth/registerCreate account (email/password)
POST/api/auth/loginLogin, returns session cookie
GET/api/auth/meGet current user session
POST/api/auth/logoutEnd session
GET/api/auth/googleGoogle OAuth redirect
GET/api/auth/githubGitHub OAuth redirect
MethodEndpointDescription
GET/api/workspacesList user’s workspaces
POST/api/workspacesCreate a workspace
GET/api/workspaces/:idGet workspace details

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 data-source connectors (Stripe, Close, PostHog, GraphQL, REST, BigQuery sync), see SaaS Connectors.

MethodEndpointDescription
GET/api/workspaces/:wid/databasesList database connections
POST/api/workspaces/:wid/databasesAdd a database connection
GET/api/workspaces/:wid/databases/:idGet a single database connection (passwords masked)
PUT/api/workspaces/:wid/databases/:idUpdate a database connection
DELETE/api/workspaces/:wid/databases/:idRemove a database connection
POST/api/workspaces/:wid/databases/test-connectionTest a candidate connection without saving
POST/api/workspaces/:wid/databases/:id/testTest an existing connection
POST/api/workspaces/:wid/databases/demoProvision 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).

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.

MethodEndpointDescription
GET/api/workspaces/:wid/databases/:id/collectionsList collections
POST/api/workspaces/:wid/databases/:id/collectionsCreate a collection
GET/api/workspaces/:wid/databases/:id/collections/:nameGet collection stats and indexes
GET/api/workspaces/:wid/databases/:id/collections/:name/infoGet collection metadata only
DELETE/api/workspaces/:wid/databases/:id/collections/:nameDrop a collection
GET/api/workspaces/:wid/databases/:id/viewsList views
POST/api/workspaces/:wid/databases/:id/viewsCreate a view (viewOn, pipeline)
GET/api/workspaces/:wid/databases/:id/views/:name/infoGet view metadata
DELETE/api/workspaces/:wid/databases/:id/views/:nameDrop a view

Session cookie or Authorization: Bearer revops_* API key required. Use the database connection ID from GET /api/workspaces/:wid/databases.

MethodEndpointDescription
POST/api/workspaces/:wid/databases/:databaseId/executeRun a query against a specific connection (body.query)
POST/api/workspaces/:wid/executeExecute with query or queryDefinition; supports pagination via body.pagination
POST/api/workspaces/:wid/execute/exportStream results as format = arrow, parquet, ndjson, or csv
POST/api/workspaces/:wid/execute/cancelCancel an in-flight query by executionId
MethodEndpointDescription
GET/api/workspaces/:wid/consoles/listList all consoles
GET/api/workspaces/:wid/consoles/:id/detailsGet console details + code
POST/api/workspaces/:wid/consoles/:id/executeExecute a saved console
GET/api/workspaces/:wid/consoles/:id/versionsList version history (paginated, newest first)
GET/api/workspaces/:wid/consoles/:id/versions/:versionGet a specific version snapshot
POST/api/workspaces/:wid/consoles/:id/versions/:version/restoreRestore the console to a past version
PUT/api/workspaces/:wid/consoles/:id/scheduleCreate or update a saved console schedule (admin only)
DELETE/api/workspaces/:wid/consoles/:id/scheduleRemove a saved console schedule (admin only)
POST/api/workspaces/:wid/consoles/:id/schedule/runTrigger a scheduled console immediately (admin only)
GET/api/workspaces/:wid/consoles/:id/schedule/runsList scheduled run history (admin only)
GET/api/workspaces/:wid/scheduled-queriesList scheduled consoles in the workspace (admin only)
GET/api/workspaces/:wid/consoles/:id/collaboratorsList per-user collaborators
POST/api/workspaces/:wid/consoles/:id/collaboratorsAdd/update a collaborator ({ userId, role }; owner/admin only)
PATCH/api/workspaces/:wid/consoles/:id/collaborators/:userIdChange a collaborator’s role (owner/admin only)
DELETE/api/workspaces/:wid/consoles/:id/collaborators/:userIdRemove a collaborator (owner/admin only)
PATCH/api/workspaces/:wid/consoles/:id/sharingUpdate 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.

MethodEndpointDescription
POST/api/workspaces/:wid/flowsCreate/trigger a flow
GET/api/workspaces/:wid/flows/:idGet flow status
GET/api/workspaces/:wid/flows/:id/sync-cdc/statusGet CDC stream status
GET/api/workspaces/:wid/flows/:id/sync-cdc/schema-healthCompare live destination column types to the connector schema (BigQuery; detects drift)
GET/api/workspaces/:wid/flows/:id/sync-cdc/destination-countsBatched row counts per entity in the destination

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
}
}
{
"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.

Email, webhook, and Slack notifications for terminal scheduled-query and flow runs. See Notifications for the full guide and webhook payload shape.

MethodEndpointDescription
GET/api/workspaces/:wid/notification-rulesList rules. Query: resourceType, resourceId.
GET/api/workspaces/:wid/notification-rules/deliveriesList recent deliveries. Query: resourceType, resourceId, optional limit.
POST/api/workspaces/:wid/notification-rulesCreate a rule. Admin only.
PATCH/api/workspaces/:wid/notification-rules/:ruleIdUpdate triggers / channel / enabled flag. Admin only.
DELETE/api/workspaces/:wid/notification-rules/:ruleIdDelete a rule. Admin only.
POST/api/workspaces/:wid/notification-rules/testSend 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.

The Chat API enables programmatic access to Mako’s AI agent with streaming responses.

MethodEndpointDescription
POST/api/agent/chatSend messages, receive streaming AI response
GET/api/agent/modelsList available AI models
Terminal window
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"
}'

The response is a Server-Sent Events (SSE) stream:

Event TypeDescription
startStream started, contains messageId
text-deltaIncremental text chunk from assistant
tool-input-availableTool call with full input (e.g., SQL query)
tool-resultTool execution result (e.g., query results)
finishStream complete, contains finishReason
StatusDescription
400Missing or invalid messages, chatId, or workspaceId
401Unauthorized (missing or invalid API key)
403API key not authorized for the workspace
404Agent not found (invalid agentId)
MethodEndpointDescription
GET/api/workspaces/:wid/chatsList chat sessions
POST/api/workspaces/:wid/chatsCreate a new chat
GET/api/workspaces/:wid/chats/:idGet chat details
PUT/api/workspaces/:wid/chats/:idUpdate chat title
DELETE/api/workspaces/:wid/chats/:idDelete a chat
GET/api/workspaces/:wid/chat-images/:attachmentIdFetch a stored chat image attachment (authenticated proxy)

Workspace skills — named playbooks the agent can author and load on demand. See Skills for the conceptual model.

MethodEndpointDescription
GET/api/workspaces/:wid/skillsList every skill in the workspace
GET/api/workspaces/:wid/skills/:idGet a single skill with full body
PUT/api/workspaces/:wid/skills/:idEdit loadWhen, body, or entities
POST/api/workspaces/:wid/skills/:id/suppressToggle the suppressed flag
DELETE/api/workspaces/:wid/skills/:idPermanently 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.

{
"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"
}
}
MethodEndpointDescription
GET/api/workspaces/:wid/dashboardsList dashboards
POST/api/workspaces/:wid/dashboardsCreate a dashboard
GET/api/workspaces/:wid/dashboards/:didGet dashboard details
PUT/api/workspaces/:wid/dashboards/:didUpdate dashboard
DELETE/api/workspaces/:wid/dashboards/:didDelete dashboard
POST/api/workspaces/:wid/dashboards/:did/duplicateDuplicate a dashboard
GET/api/workspaces/:wid/dashboards/:did/versionsList dashboard version history
GET/api/workspaces/:wid/dashboards/:did/versions/:versionGet a specific dashboard version
POST/api/workspaces/:wid/dashboards/:did/versions/:version/restoreRestore dashboard to a past version
POST/api/workspaces/:wid/dashboards/:did/version-commentAI-suggested commit message for pending changes
GET/api/workspaces/:wid/dashboards/:did/collaboratorsList per-user collaborators
POST/api/workspaces/:wid/dashboards/:did/collaboratorsAdd/update a collaborator ({ userId, role }, role viewer|editor; owner/admin only)
PATCH/api/workspaces/:wid/dashboards/:did/collaborators/:userIdChange a collaborator’s role (owner/admin only)
DELETE/api/workspaces/:wid/dashboards/:did/collaborators/:userIdRemove a collaborator (owner/admin only)
PATCH/api/workspaces/:wid/dashboards/:did/sharingUpdate general access ({ access, workspaceRole }; owner/admin only)
POST/api/workspaces/:wid/dashboards/:did/public-shareEnable/create a public link ({ password? }; owner/admin only)
GET/api/workspaces/:wid/dashboards/:did/public-share/passwordReveal the public-link password (owner/admin only)
PATCH/api/workspaces/:wid/dashboards/:did/public-shareUpdate password / rotate token / rename slug (owner/admin only)
DELETE/api/workspaces/:wid/dashboards/:did/public-shareDisable the public link (owner/admin only)
MethodEndpointDescription
GET/api/workspaces/:wid/dashboard-foldersList dashboard folders
POST/api/workspaces/:wid/dashboard-foldersCreate a folder
PUT/api/workspaces/:wid/dashboard-folders/:fidUpdate a folder
DELETE/api/workspaces/:wid/dashboard-folders/:fidDelete a folder
MethodEndpointDescription
GET/api/workspaces/:wid/dashboards/:did/materialization/statusGet materialization status for all data sources
POST/api/workspaces/:wid/dashboards/:did/materialization/triggerTrigger materialization for a data source
POST/api/workspaces/:wid/dashboards/:did/materialization/trigger-allTrigger materialization for all data sources
GET/api/workspaces/:wid/dashboards/:did/materialization/stream/:dataSourceIdStream Parquet artifact (supports range requests)

React apps built inside the workspace (Apps). Private apps are owner-only — admins and API keys cannot access another member’s private app.

MethodEndpointDescription
GET/api/workspaces/:wid/appsList apps visible to the caller
POST/api/workspaces/:wid/appsCreate an app (scaffolds a React + TypeScript starter)
GET/api/workspaces/:wid/apps/:idGet an app (files, dependencies, data bindings)
PUT/api/workspaces/:wid/apps/:idUpdate an app (files, dependencies, bindings, access)
DELETE/api/workspaces/:wid/apps/:idDelete an app
POST/api/workspaces/:wid/apps/:id/bindings/:bid/materializeBuild/rebuild a binding’s Parquet artifact ({force})
GET/api/workspaces/:wid/apps/:id/bindings/:bid/materializationPoll a binding’s materialization status
GET/api/workspaces/:wid/apps/:id/bindings/:bid/materialization/artifactStream the materialized Parquet artifact

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.

Token-gated, read-only endpoints for published dashboard/app links. These are intentionally unauthenticated (no session or API key) and serve only materialized snapshots.

MethodEndpointDescription
GET/api/share/:tokenGet public-share metadata (title, whether a password is required)
POST/api/share/:token/unlockExchange a password for access to a protected link
GET/api/share/:token/contentGet the shared resource’s materialized content
GET/api/share/:token/artifacts/:artifactIdStream a materialized Parquet artifact (supports range requests)
POST/api/share/:token/refreshThrottled anonymous re-materialization of the snapshot
MethodEndpointDescription
POST/api/inngestInngest webhook handler (internal)

Subscription management endpoints. All require workspace membership. When BILLING_ENABLED is false (self-hosted default), all endpoints return { "billingEnabled": false }.

MethodEndpointDescription
GET/api/workspaces/:wid/billing/statusGet plan, usage quota, and subscription status
POST/api/workspaces/:wid/billing/checkoutCreate a Stripe Checkout session (returns { url })
POST/api/workspaces/:wid/billing/portalCreate a Stripe Customer Portal session (returns { url })
{
"billingEnabled": true,
"plan": "free",
"subscriptionStatus": null,
"usageQuotaUsd": 5,
"hardLimitUsd": 5,
"currentUsageUsd": 1.23,
"modelTier": "free",
"maxDatabases": 3,
"maxMembers": 3
}
StatusDescription
403Not a workspace owner or admin
409Active subscription already exists (on checkout)