A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Metabase API is how an app or AI agent works with a Metabase instance: running a saved question, running an ad-hoc query against a connected database, building dashboards and collections, and managing users and permissions groups. Access is granted through an API key, which is assigned to one permissions group and carries exactly that group's permissions, so the key reaches only what its group can see. Metabase does not version its API, and it pushes nothing to apps, so an agent polls or queries rather than waiting for events.
How an app or AI agent connects to Metabase determines what it can reach. There is a route for making calls with an API key, a route that exchanges a username and password for a temporary session token, and a hosted server that exposes Metabase tools to agents, and each is governed by the permissions group behind the credential.
The REST API answers under /api on the Metabase instance's own host, takes and returns JSON, and is unversioned: it is tied to the Metabase release that is running and can change between releases. A call authenticates with an API key in the X-API-Key header, or with a session token in the X-Metabase-Session header.
Metabase ships a first-party MCP server, GA in Metabase 0.62, at /api/metabase-mcp using Streamable HTTP transport. It runs an embedded OAuth 2.0 server, so an MCP client connects through a Metabase consent screen and receives an access token scoped to that person's Metabase permissions. Tools include search, read_resource, construct_query, query, execute_query, visualize_query, create_question, update_question, create_dashboard, and create_collection. An admin turns it on at Admin, AI, MCP.
An API key is sent in the X-API-Key header and is the recommended way to authenticate programmatic calls. A key is assigned to one permissions group when it is created, and it has exactly that group's permissions, so a key is the unit of least-privilege access. Metabase shows the key only once, and a deleted key cannot be recovered.
A session token is obtained by posting a username and password to /api/session, then sent in the X-Metabase-Session header. The token carries the signed-in user's permissions and expires after a period of inactivity, so it must be refreshed. It suits short interactive use more than long-running automation.
The first-party MCP server runs an embedded OAuth 2.0 server. An MCP client is sent through a Metabase consent screen and receives an access token scoped to the connecting person's Metabase permissions, so the agent reaches only what that person can see.
The Metabase API is split into areas an agent can act on, like questions, dashboards, collections, databases, and the query engine that runs them. Each call runs with the permissions of the group its API key belongs to, and running a query reaches whatever data that group can see.
List, read, create, and update saved questions, and run a saved question to return its results.
List, read, create, and update dashboards and the cards placed on them.
List the collection tree, read a collection's items, and create or update collections.
List and read connected databases, add or update a connection, and trigger a metadata sync.
Run an ad-hoc query against a connected database and return its results.
List and read users, create a user, and update, deactivate, or reactivate one.
List, read, create, update, and delete permissions groups, and manage their membership.
List and read alerts, and remove an alert subscription.
Search across questions, dashboards, collections, and other content.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
Questions (Cards)List, read, create, and update saved questions, and run a saved question to return its results.6 | ||||||
| GET | /api/card | List all saved questions (cards) the caller can read. | read | Collection: read | Current | |
Returns only cards in collections the calling group can view. There are no per-endpoint scopes; access comes from the group the API key belongs to. Acts oncard Permission (capability) Collection: readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/card/:id | Get a single saved question by ID. | read | Collection: read | Current | |
Since Metabase 0.57 the query serializes as MBQL 5; pass ?legacy-mbql=true for the older shape. Acts oncard Permission (capability) Collection: readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/card | Create a saved question (card) from a query. | write | Collection: write | Current | |
Needs write access to the target collection, and create-queries on the database the card reads. Acts oncard Permission (capability) Collection: writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/card/:id | Update a saved question (its query, name, collection, or archived state). | write | Collection: write | Current | |
Archiving and moving a card both go through this endpoint. Acts oncard Permission (capability) Collection: writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/card/:card-id/query | Run the query saved on a card and return its results as JSON. | read | Database: query | Current | |
Reads the card but runs its query against the connected database, so it returns live data the group can see. Acts oncard Permission (capability) Database: queryVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/card/:card-id/query/:export-format | Run a card's query and return results as a file in csv, json, or xlsx. | read | Database: query | Current | |
Since Metabase 0.53 parameters must be sent in the request body, not as query-string parameters. Acts oncard Permission (capability) Database: queryVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
DashboardsList, read, create, and update dashboards and the cards placed on them.4 | ||||||
| GET | /api/dashboard | List dashboards the caller can read. | read | Collection: read | Current | |
Limited to dashboards in collections the calling group can view. Acts ondashboard Permission (capability) Collection: readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/dashboard/:id | Get a single dashboard, including the cards placed on it. | read | Collection: read | Current | |
Read-only. Acts ondashboard Permission (capability) Collection: readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/dashboard | Create a dashboard. | write | Collection: write | Current | |
Needs write access to the collection the dashboard is created in. Acts ondashboard Permission (capability) Collection: writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/dashboard/:id | Update a dashboard's details and the cards on it. | write | Collection: write | Current | |
Adding, moving, and removing dashboard cards is done through this update endpoint. Acts ondashboard Permission (capability) Collection: writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
CollectionsList the collection tree, read a collection's items, and create or update collections.4 | ||||||
| GET | /api/collection/tree | Fetch the full collection tree the caller can read. | read | Collection: read | Current | |
Since Metabase 0.50 official collections are returned ahead of other items. Acts oncollection Permission (capability) Collection: readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/collection/:id/items | List the items (cards, dashboards, sub-collections) inside a collection. | read | Collection: read | Current | |
Can be filtered by model type, such as card, dashboard, or collection. Acts oncollection Permission (capability) Collection: readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/collection | Create a collection. | write | Collection: write | Current | |
Needs write access to the parent collection. Acts oncollection Permission (capability) Collection: writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/collection/:id | Update a collection, including archiving, unarchiving, or moving it. | write | Collection: write | Current | |
Moving a collection changes what its contents inherit for permissions. Acts oncollection Permission (capability) Collection: writeVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
DatabasesList and read connected databases, add or update a connection, and trigger a metadata sync.5 | ||||||
| GET | /api/database | List the databases connected to the Metabase instance. | read | Database: read | Current | |
Returns connection metadata, not the stored credentials themselves. Acts ondatabase Permission (capability) Database: readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/database/:id | Get a single database connection's details. | read | Database: read | Current | |
Read-only. Acts ondatabase Permission (capability) Database: readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/database | Add a database connection to Metabase. | write | Admin: settings | Current | |
Restricted to admins; the request carries the credentials Metabase will use to reach the data source. Acts ondatabase Permission (capability) Admin: settingsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/database/:id | Update a database connection. | write | Admin: settings | Current | |
Admin-only; can change the connection's stored credentials. Acts ondatabase Permission (capability) Admin: settingsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/database/:id/sync_schema | Trigger a manual sync of a database's schema metadata. | write | Admin: settings | Current | |
Admin-only; refreshes the tables and fields Metabase knows about, without changing data. Acts ondatabase Permission (capability) Admin: settingsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Datasets (queries)Run an ad-hoc query against a connected database and return its results.2 | ||||||
| POST | /api/dataset | Run an ad-hoc query against a connected database and return its results. | read | Database: query | Current | |
Runs a query the caller composes, not a saved one, so it reaches any data the group's create-queries permission allows. Acts ondataset Permission (capability) Database: queryVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/dataset/:export-format | Run an ad-hoc query and return results as a file in csv, json, or xlsx. | read | Database: query | Current | |
The export-format path segment selects the file type returned. Acts ondataset Permission (capability) Database: queryVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
UsersList and read users, create a user, and update, deactivate, or reactivate one.5 | ||||||
| GET | /api/user | List users (active by default; pass ?status=all to include deactivated). | read | Admin: people | Current | |
Listing all users is an admin action; GET /api/user/current returns the caller's own profile without admin rights. Acts onuser Permission (capability) Admin: peopleVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/user/:id | Get a single user by ID. | read | Admin: people | Current | |
Admin-only for other users. Acts onuser Permission (capability) Admin: peopleVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/user | Create a user. | write | Admin: people | Current | |
Admin-only; creates an account that can sign in to Metabase. Acts onuser Permission (capability) Admin: peopleVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/user/:id | Update a user's details. | write | Admin: people | Current | |
Admin-only. Acts onuser Permission (capability) Admin: peopleVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /api/user/:id | Deactivate a user (a soft delete that blocks sign-in). | write | Admin: people | Current | |
Admin-only; PUT /api/user/:id/reactivate restores access. Acts onuser Permission (capability) Admin: peopleVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Permissions groupsList, read, create, update, and delete permissions groups, and manage their membership.5 | ||||||
| GET | /api/permissions/group | List all permissions groups with their member counts. | read | Admin: people | Current | |
Admin-only; a group is what an API key is assigned to, so a key gets that group's permissions. Acts onpermissions group Permission (capability) Admin: peopleVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/permissions/group/:id | Get a single permissions group and its members. | read | Admin: people | Current | |
Admin-only. Acts onpermissions group Permission (capability) Admin: peopleVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/permissions/group | Create a permissions group. | write | Admin: people | Current | |
Admin-only; a new group starts with no data access until its graph is set. Acts onpermissions group Permission (capability) Admin: peopleVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/permissions/membership | Add a user to a permissions group. | write | Admin: people | Current | |
Admin-only; changing membership changes what the member can reach. Acts onpermissions group Permission (capability) Admin: peopleVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /api/permissions/graph | Apply a batch update to the data-permissions graph for all groups. | write | Admin: settings | Current | |
Admin-only; since Metabase 0.50 the model splits view-data and create-queries instead of one data permission. Acts onpermissions graph Permission (capability) Admin: settingsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Alerts & subscriptionsList and read alerts, and remove an alert subscription.3 | ||||||
| GET | /api/alert | List alerts (scheduled or threshold notifications on a question). | read | Collection: read | Current | |
Since Metabase 0.54 most alert writes moved to the notification API; this read endpoint was retained. Acts onalert Permission (capability) Collection: readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/alert/:id | Get a single alert. | read | Collection: read | Current | |
Read-only. Acts onalert Permission (capability) Collection: readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /api/alert/:id/subscription | Remove the caller's subscription from an alert. | write | Collection: read | Current | |
Removes a recipient from the alert, not the alert itself. Acts onalert Permission (capability) Collection: readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
SearchSearch across questions, dashboards, collections, and other content.1 | ||||||
| GET | /api/search | Search across questions, dashboards, collections, models, and tables. | read | Collection: read | Current | |
Results are filtered to what the calling group can see. Acts onsearch result Permission (capability) Collection: readVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Metabase does not push events to an app. The closest equivalent is its built-in alerts and dashboard subscriptions, which Metabase sends on a schedule or when a result crosses a threshold, by email or to a Slack channel, rather than to an app endpoint.
| Event | What it signals | Triggered by |
|---|
Metabase does not enforce a request rate limit in its core API, so how fast an agent can call is bounded by the instance's own capacity. A query result returned by the API is capped at a fixed number of rows.
Metabase does not enforce a request rate limit in its core API, so how fast an app or AI agent can call is bounded by the instance's own capacity rather than a documented quota. A self-hosted instance can be put behind a reverse proxy that adds rate limiting if needed. Because a query call runs against a connected database, the real ceiling on heavy use is that database's load, not an API counter.
Most list endpoints, such as cards and dashboards, return the full set the caller can see in one response rather than paging. Search and some larger collections accept limit and offset parameters to page through results. There is no single account-wide cursor scheme across the API.
A query result returned through the API is capped at a fixed number of rows (2,000 in the standard JSON response, 1,048,576 in a downloaded export), with the rest truncated. Exports can be requested as csv, json, or xlsx through the query export endpoints.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | Bad Request | The request was malformed or a required parameter was missing or invalid, such as a query the engine cannot run. | Read the error message, correct the request body or parameters, and resend. |
| 401 | Unauthenticated | No valid API key or session token was provided, or the session token has expired. | Send a valid X-API-Key, or re-authenticate at /api/session for a fresh session token. |
| 403 | Forbidden | The credential is valid but its permissions group lacks access to the resource or action, for example an admin-only endpoint called with a non-admin key. | Assign the key to a group that has the needed permission, or use an admin key for admin endpoints. |
| 404 | Not Found | The resource does not exist, or the calling group cannot see it. | Confirm the ID, and check the group can view the collection or database it belongs to. |
Metabase does not version its API. There is one continuously evolving API tied to the version of Metabase that is running, and endpoints can change between releases, so the timeline below tracks notable changes by release.
Metabase does not version its API, so this entry names the release these facts were verified against, Metabase 62, released 16 June 2026. It made the first-party MCP server generally available at /api/metabase-mcp, alongside custom visualizations, a schema viewer, and a CLI built on the API.
Removed the LLM autodescribe endpoints in favor of the Metabot agent.
Card queries now serialize in the newer MBQL 5 shape, with a flag to keep the old shape.
Most alert endpoints were removed in favor of a new notification API; a few read and unsubscribe endpoints were retained.
The card export-query endpoint stopped accepting parameters as query-string values.
The single data permission was replaced by separate view-data and create-queries permissions, and collection listings reordered.
API key authentication via the X-API-Key header became the recommended way to authenticate programmatic calls, and export endpoints gained formatted-row control.
Pin to a Metabase release and review the API changelog before upgrading.
Metabase API changelog ↗Bollard AI sits between a team's AI agents and Metabase. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.