Admin API
Pull your organization's MCP usage into scripts, BI dashboards, and scheduled reports over HTTP. The Admin API serves the same numbers as the MCP activity dashboard and the Team usage table, and it authenticates with an organization-owned key, so a job can run without a signed-in user.
The API is organized around REST: it has resource-oriented URLs, takes query parameters, and returns JSON-encoded responses with standard HTTP status codes. Every endpoint is read-only.
The API is described by an OpenAPI 3.1 spec, mintmcp-admin-api.json, so you can load it into Postman, Insomnia, or a client generator.
https://app.mintmcp.com/api/admin/v1
GET /api/admin/v1/organizations/me
GET /api/admin/v1/mcp-activity/summary
GET /api/admin/v1/mcp-activity/users
Authentication
The Admin API uses Admin API keys to authenticate requests. Send the key as a bearer token in the Authorization header on every request. A request without a valid key returns a 401.
Make all API requests over HTTPS, and keep keys on the server. Keys are secrets, and the API doesn't accept cross-origin browser requests, so call it from a backend job rather than from browser code or a public repository.
Your API key
Admin API keys belong to the organization rather than to the person who created them, so a key keeps working if its creator changes roles or leaves. Only organization admins can create, list, and revoke them.
Each key carries the permissions checked when it was created, and nothing more. There are two:
| Permission | What the key can read |
|---|---|
View organization activity metadata (org:activity-metadata:view) | Usage counts, actors, timing, and status across the organization. No request, response, or tool content. |
View organization activity, including payload content (view-organization-logs) | The same org-wide activity, with permission to read content as well. |
Grant a key only what its job needs. The usage endpoints accept either permission, so a key restricted to View organization activity metadata covers usage reporting and never exposes request or response content. The creator of a key must hold each permission they grant it.
- cURL
- Python
- TypeScript
curl https://app.mintmcp.com/api/admin/v1/organizations/me \
-H "Authorization: Bearer $MINTMCP_ADMIN_API_KEY"
import os
import requests
API_KEY = os.environ["MINTMCP_ADMIN_API_KEY"]
resp = requests.get(
"https://app.mintmcp.com/api/admin/v1/organizations/me",
headers={"Authorization": f"Bearer {API_KEY}"},
)
resp.raise_for_status()
print(resp.json())
const res = await fetch("https://app.mintmcp.com/api/admin/v1/organizations/me", {
headers: { Authorization: `Bearer ${process.env.MINTMCP_ADMIN_API_KEY}` },
});
if (!res.ok) throw new Error(`Admin API returned ${res.status}`);
console.log(await res.json());
Create a key
- Open Enterprise in the sidebar and select the API keys tab.
- Under MintMCP Admin API keys, click Create Admin API key.
- Enter a Name that identifies the job or system using the key, such as
usage-report-prod. - Under Permissions, check what the key may read.
- Choose an Expiry: 7 days, 30 days, 90 days (the default), or 1 year.
- Click Create, then copy the key and store it in your secret manager. The key is shown once, so if you lose it, create a new one.
export MINTMCP_ADMIN_API_KEY="mint_adminkey_..."
Rotate and revoke keys
Every key expires, after at most one year, and the API keys tab shows each key's permissions, last use, creation date, and expiry. To rotate a key, create a new one, switch your job to it, and then revoke the old one. A revoked or expired key stops working on its next request. Key creation and revocation are recorded in the organization's audit log, under Enterprise → Audit logs, and in SIEM export.
Errors
The API uses conventional HTTP status codes: 2xx means success, 4xx means the request failed because of the information it sent (a bad parameter, a missing key), and 5xx means something went wrong on MintMCP's side.
| Status | code | Cause |
|---|---|---|
400 | invalid_request | A malformed or unknown query parameter, start not before end, a window longer than 90 days, or a cursor that doesn't match the request |
401 | unauthorized | A missing, malformed, expired, or revoked key |
403 | forbidden | The key lacks the endpoint's permission, or the organization's subscription has expired |
404 | not_found | The resource doesn't exist |
500 | internal_error | An unexpected server error. Retry with backoff, and contact support@mintmcp.com if it persists. |
The error object
-
error.codestringA machine-readable code from the table above. Branch on this, not on
message. -
error.messagestringA human-readable description of what went wrong.
-
error.issuesarray, optionalPresent when query parameters fail validation, with one entry per failing parameter.
Child attributes
-
pathstringThe parameter that failed.
-
messagestringWhy it failed.
-
{
"error": {
"code": "invalid_request",
"message": "The window from `start` to `end` can be at most 90 days."
}
}
Pagination
List endpoints return one page at a time. When more results remain, the response includes nextCursor; pass it back as the cursor query parameter to fetch the next page, and stop when a response has no nextCursor.
The cursor keeps the first request's window and filters, so every page reads the same data. On later pages, either omit start, end, and includeInactive or resend the first request's values, because a different value returns a 400. limit applies to each page and can be sent with the cursor.
- cURL
- Python
- TypeScript
curl -G https://app.mintmcp.com/api/admin/v1/mcp-activity/users \
-H "Authorization: Bearer $MINTMCP_ADMIN_API_KEY" \
--data-urlencode "limit=100" \
--data-urlencode "cursor=eyJzdGFydCI6IjIwMjYtMDktMDFUMDA6MDA6MDBaIi..."
import os
import requests
API_KEY = os.environ["MINTMCP_ADMIN_API_KEY"]
params = {
"start": "2026-09-01T00:00:00Z",
"end": "2026-10-01T00:00:00Z",
"limit": 100,
}
users = []
while True:
resp = requests.get(
"https://app.mintmcp.com/api/admin/v1/mcp-activity/users",
headers={"Authorization": f"Bearer {API_KEY}"},
params=params,
)
resp.raise_for_status()
page = resp.json()
users.extend(page["users"])
if "nextCursor" not in page:
break
params["cursor"] = page["nextCursor"]
const params = new URLSearchParams({
start: "2026-09-01T00:00:00Z",
end: "2026-10-01T00:00:00Z",
limit: "100",
});
const users = [];
while (true) {
const res = await fetch(`https://app.mintmcp.com/api/admin/v1/mcp-activity/users?${params}`, {
headers: { Authorization: `Bearer ${process.env.MINTMCP_ADMIN_API_KEY}` },
});
if (!res.ok) throw new Error(`Admin API returned ${res.status}`);
const page = await res.json();
users.push(...page.users);
if (page.nextCursor === undefined) break;
params.set("cursor", page.nextCursor);
}
Retrieve the calling key
GET /api/admin/v1/organizations/me
Returns the organization the key belongs to, along with the key's ID, permissions, and expiry. It requires no permission, so it works as a health check for a newly deployed key and as a way to alert before a key expires.
Parameters
No parameters.
Returns
-
organization.idstringThe organization the key belongs to.
-
adminApiKeyobjectThe key that made the request.
Child attributes
-
idstringThe key's ID, as shown on the API keys tab.
-
permissionsarray of stringsThe key's permissions:
org:activity-metadata:view,view-organization-logs, or both. -
expiresAtstring, ISO 8601When the key stops working.
-
- cURL
- Python
- TypeScript
curl https://app.mintmcp.com/api/admin/v1/organizations/me \
-H "Authorization: Bearer $MINTMCP_ADMIN_API_KEY"
resp = requests.get(
"https://app.mintmcp.com/api/admin/v1/organizations/me",
headers={"Authorization": f"Bearer {API_KEY}"},
)
resp.raise_for_status()
key = resp.json()["adminApiKey"]
const res = await fetch("https://app.mintmcp.com/api/admin/v1/organizations/me", {
headers: { Authorization: `Bearer ${process.env.MINTMCP_ADMIN_API_KEY}` },
});
if (!res.ok) throw new Error(`Admin API returned ${res.status}`);
const { adminApiKey } = await res.json();
{
"organization": { "id": "org_01JZ8Q2Y4N6T5V3W7X9A1B2C3D" },
"adminApiKey": {
"id": "adminkey_01K7E4R8M2P6Q9S3T5V7W9X1Y2",
"permissions": ["org:activity-metadata:view"],
"expiresAt": "2027-01-05T18:22:41.000Z"
}
}
Retrieve an organization usage summary
GET /api/admin/v1/mcp-activity/summary
Summarizes MCP tool calls across the organization over a window of up to 90 days: totals, a call timeline, activity per Virtual MCP and per connector, and the most-called tools. Requires either activity permission.
Identical requests within five minutes can return the same result, so when you leave end unset, a repeated request may report the same window.
Parameters
-
startstring, ISO 8601, optionalStart of the window. Defaults to 24 hours before
end. -
endstring, ISO 8601, optionalEnd of the window. Defaults to now.
Returns
-
windowobjectThe
startandendthe numbers cover. -
totalsobjectOrg-wide totals for the window.
Child attributes
-
callsintegerTool calls.
-
successfulCallsintegerTool calls that succeeded.
-
failedCallsintegerTool calls that failed.
-
activeActorsintegerDistinct users and agent identities that made a call.
-
averageResponseTimeMsnumberAverage response time, in milliseconds.
-
-
timelineobjectCalls over time.
Child attributes
-
bucketMinutesintegerThe width of each bucket, in minutes.
-
bucketsarray of objectsEach bucket's
starttimestamp andcalls, oldest first. Buckets align to multiples ofbucketMinutes, so the first and last can extend past the window.
-
-
vmcpsarray of objectsActivity per Virtual MCP.
Child attributes
-
id,namestringThe Virtual MCP.
-
deletedbooleanWhether the Virtual MCP has since been deleted.
-
calls,successfulCalls,activeActors,averageResponseTimeMsintegerThe Virtual MCP's activity counts.
-
connectorsarray of objectsThe same breakdown per connector within this Virtual MCP:
id,name, and the activity counts.
-
-
connectorsarray of objectsActivity per connector across all Virtual MCPs:
id,name,calls,successfulCalls,activeActors, andaverageResponseTimeMs. -
topToolsarray of objectsThe five most-called tools.
Child attributes
-
namestringThe tool name.
-
connectorId,connectorNamestringThe connector that provides the tool.
-
callsintegerCalls to the tool in the window.
-
- cURL
- Python
- TypeScript
curl -G https://app.mintmcp.com/api/admin/v1/mcp-activity/summary \
-H "Authorization: Bearer $MINTMCP_ADMIN_API_KEY" \
--data-urlencode "start=2026-09-01T00:00:00Z" \
--data-urlencode "end=2026-10-01T00:00:00Z"
resp = requests.get(
"https://app.mintmcp.com/api/admin/v1/mcp-activity/summary",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"start": "2026-09-01T00:00:00Z", "end": "2026-10-01T00:00:00Z"},
)
resp.raise_for_status()
summary = resp.json()
const params = new URLSearchParams({
start: "2026-09-01T00:00:00Z",
end: "2026-10-01T00:00:00Z",
});
const res = await fetch(`https://app.mintmcp.com/api/admin/v1/mcp-activity/summary?${params}`, {
headers: { Authorization: `Bearer ${process.env.MINTMCP_ADMIN_API_KEY}` },
});
if (!res.ok) throw new Error(`Admin API returned ${res.status}`);
const summary = await res.json();
{
"window": { "start": "2026-09-01T00:00:00.000Z", "end": "2026-10-01T00:00:00.000Z" },
"totals": {
"calls": 48210,
"successfulCalls": 47655,
"failedCalls": 555,
"activeActors": 87,
"averageResponseTimeMs": 412.6
},
"timeline": {
"bucketMinutes": 1440,
"buckets": [
{ "start": "2026-09-01T00:00:00.000Z", "calls": 1520 },
{ "start": "2026-09-02T00:00:00.000Z", "calls": 1688 }
]
},
"vmcps": [
{
"id": "g_2XPDS05NMAGSeRGTxnGaS5",
"name": "Engineering",
"deleted": false,
"calls": 31877,
"successfulCalls": 31502,
"activeActors": 54,
"averageResponseTimeMs": 388,
"connectors": [
{
"id": "hosted-github",
"name": "GitHub",
"calls": 20311,
"successfulCalls": 20140,
"activeActors": 51,
"averageResponseTimeMs": 341
}
]
}
],
"connectors": [
{
"id": "hosted-github",
"name": "GitHub",
"calls": 20311,
"successfulCalls": 20140,
"activeActors": 51,
"averageResponseTimeMs": 341
}
],
"topTools": [
{ "name": "search_code", "connectorId": "hosted-github", "connectorName": "GitHub", "calls": 9120 }
]
}
List usage per user
GET /api/admin/v1/mcp-activity/users
Returns each member's MCP tool activity over a window of up to 90 days: their tool calls, how many Virtual MCPs and distinct tools they used, when they were last active, and their most-used tools and Virtual MCPs. It covers organization members only, so agent identities aren't listed. Requires either activity permission.
By default the endpoint lists only members with activity, most calls first. With includeInactive=true, it lists every current member in user ID order, which is how you find members who haven't used MCP in the window. Results are paginated; see Pagination.
Parameters
-
startstring, ISO 8601, optionalStart of the window. Defaults to 24 hours before
end. -
endstring, ISO 8601, optionalEnd of the window. Defaults to now.
-
includeInactivetrueorfalse, optionaltruelists every current member, including members with no activity in the window. Defaults tofalse. -
limitinteger, optionalUsers per page, from 1 to 100. Defaults to 25.
-
topItemsPerUserinteger, optionalHow many top tools and top Virtual MCPs to return per user, from 1 to 20. Defaults to 5.
-
cursorstring, optionalThe
nextCursorvalue from the previous page.
Returns
-
windowobjectThe
startandendthe numbers cover. -
usersarray of objectsOne entry per member.
Child attributes
-
id,name,emailstringThe member's identity.
-
rolestringAdminorMember. -
statusstringActive, orInvitedfor a member who hasn't joined yet. -
lastActivestring, ISO 8601, nullableThe member's most recent activity, or
nullif they have none. -
callsintegerTool calls in the window.
-
vmcpsUsed,toolsUsedintegerDistinct Virtual MCPs and tools the member called.
-
topToolsarray of objectsThe member's most-called tools, most calls first, each with
nameandcalls. -
topVmcpsarray of objectsThe member's most-called Virtual MCPs, most calls first, each with
id,name, andcalls.
-
-
nextCursorstring, optionalPresent when more users remain. Pass it back as
cursor.
- cURL
- Python
- TypeScript
curl -G https://app.mintmcp.com/api/admin/v1/mcp-activity/users \
-H "Authorization: Bearer $MINTMCP_ADMIN_API_KEY" \
--data-urlencode "start=2026-09-01T00:00:00Z" \
--data-urlencode "end=2026-10-01T00:00:00Z" \
--data-urlencode "limit=100"
resp = requests.get(
"https://app.mintmcp.com/api/admin/v1/mcp-activity/users",
headers={"Authorization": f"Bearer {API_KEY}"},
params={
"start": "2026-09-01T00:00:00Z",
"end": "2026-10-01T00:00:00Z",
"limit": 100,
},
)
resp.raise_for_status()
users = resp.json()["users"]
const params = new URLSearchParams({
start: "2026-09-01T00:00:00Z",
end: "2026-10-01T00:00:00Z",
limit: "100",
});
const res = await fetch(`https://app.mintmcp.com/api/admin/v1/mcp-activity/users?${params}`, {
headers: { Authorization: `Bearer ${process.env.MINTMCP_ADMIN_API_KEY}` },
});
if (!res.ok) throw new Error(`Admin API returned ${res.status}`);
const { users } = await res.json();
{
"window": { "start": "2026-09-01T00:00:00.000Z", "end": "2026-10-01T00:00:00.000Z" },
"users": [
{
"id": "user_01JZ9B3C5D7E9F1G3H5J7K9M1N",
"name": "Dana Kim",
"email": "dana.kim@example.com",
"role": "Member",
"status": "Active",
"lastActive": "2026-09-30T21:14:08.000Z",
"calls": 2214,
"vmcpsUsed": 3,
"toolsUsed": 17,
"topTools": [
{ "name": "search_code", "calls": 640 },
{ "name": "get_issue", "calls": 412 }
],
"topVmcps": [
{ "id": "g_2XPDS05NMAGSeRGTxnGaS5", "name": "Engineering", "calls": 1980 }
]
}
],
"nextCursor": "eyJzdGFydCI6IjIwMjYtMDktMDFUMDA6MDA6MDBaIi..."
}
Related
- Admin MCP: manage your organization from an MCP client in natural language
- Export to SIEM: stream tool calls and audit events to your observability platform in real time
- Roles and permissions: control who can administer MintMCP