API Reference
All REST endpoints are served through the Gateway.
Base URL: https://gateway.apexmcp.ai
Interactive explorer: https://gateway.apexmcp.ai/docs
Authentication
All /api/* endpoints require Authorization: Bearer <token>.
orgId is always derived from the JWT token — never passed in the request body.
Obtain a token via the client credentials grant:
curl -X POST https://gateway.apexmcp.ai/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=<id>&client_secret=<secret>"Response:
{
"access_token": "eyJhbGci...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "mcp:call"
}Pass Authorization: Bearer <access_token> on every subsequent request.
Authentication notes
API keys (OAuth2 client credentials) are scoped to an org. The orgId is always derived from the token — never passed in the request. API keys do not have user roles; access is granted at the org level.
User session tokens (Zitadel) carry a role. Role requirements:
| Endpoint group | Minimum role |
|---|---|
| Connectors, tools, approvals, audit | contributor |
| Webhooks | admin |
| Billing | finance |
| MCP protocol | any valid token |
Connectors
GET /api/connectors
List all active (non-archived) connectors for the authenticated org.
Response:
{
"connectors": [
{
"id": "uuid",
"name": "production-db",
"type": "postgresql",
"status": "active",
"allow_write": false,
"allow_ddl": false,
"created_at": "2024-10-01T09:00:00Z"
}
]
}GET /api/connectors/{id}
Get a single connector by ID.
PATCH /api/connectors/{id}
Update connector name, config, credentials, or write permissions.
allow_write and allow_ddl are only accepted for DB connector types (postgresql, mysql, mongodb, mssql, oracle). They are silently ignored for other types.
Request body:
{
"name": "renamed-db",
"allow_write": true,
"allow_ddl": false,
"credential": "new-password"
}DELETE /api/connectors/{id}
Soft-delete (archive) a connector. Tools are removed from the MCP endpoint on next provision.
Response: { "archived": true, "id": "uuid" }
POST /api/connectors/{id}/revalidate
Re-trigger credential and connectivity validation for an existing connector. Sets status to validating and returns immediately.
Response: { "status": "validating", "id": "uuid" }
MCP Provisioning & Tools
GET /api/mcp/{orgId}/status
Get MCP provisioning status for the org.
Response:
{ "status": "provisioned", "endpoint": "https://mcp.apexmcp.ai/mcp/my-org", "toolCount": 12 }GET /api/mcp/{orgId}/tools
List all tools exposed on the org’s MCP endpoint, including external MCP tools.
Query params: connector_id — filter to a specific connector.
Response:
{
"tools": [
{
"id": "uuid",
"tool_name": "query_postgres_orders",
"enabled": true,
"requires_approval": false,
"approval_ttl_seconds": 86400,
"approval_emails": [],
"connector_id": "uuid",
"connector_name": "production-db",
"connector_type": "postgresql"
}
]
}PATCH /api/mcp/{orgId}/tools/{toolId}/metadata
Update tool settings: enable/disable, approval gate, TTL, approver emails, name/description overrides.
Request body:
{
"enabled": true,
"requires_approval": true,
"approval_ttl_seconds": 3600,
"approval_emails": ["alice@example.com", "bob@example.com"],
"tool_name_override": "get_orders",
"tool_description_override": "Query orders table",
"read_only": true
}Approvals
GET /api/org/approvals
List approval requests for the org. Returns all statuses by default.
Query params:
| Param | Type | Description |
|---|---|---|
status | pending|executing|executed|rejected|failed|expired | Filter by status. Omit for all. |
limit | integer | Default: 200, max: 500 |
Response:
{
"approvals": [
{
"id": "uuid",
"tool_name": "delete_customer",
"status": "pending",
"arguments": { "customer_id": "cus_123" },
"requested_by": "agent_01abc",
"decided_by": null,
"decided_at": null,
"approver_emails": ["alice@example.com"],
"created_at": "2024-11-15T14:00:00Z",
"expires_at": "2024-11-16T14:00:00Z"
}
]
}POST /api/org/approvals/{id}/approve
Approve a pending tool call and execute it server-side. Records decided_by and decided_at. Writes an approval.approved audit entry.
Authorization: User session tokens must be a listed approver for the tool. API key (client credentials) tokens bypass the email check — org scoping enforced by JWT is sufficient.
Response:
{ "ok": true, "status": "executed", "result": { ... } }Errors: 403 not an approver · 404 not found · 409 not pending
POST /api/org/approvals/{id}/reject
Reject a pending tool call. Same authorization rules as approve.
Response: { "ok": true, "status": "rejected" }
Audit
GET /api/audit
List audit events for the org.
Query params:
| Param | Type | Description |
|---|---|---|
limit | integer | Default: 50, max: 200 |
action | string | Filter by action (e.g. connector.updated, approval.approved) |
days | integer | Lookback window in days |
GET /api/audit/export-json
Export full audit log as JSON. Admin only.
Query params: redact (boolean), action, days
Billing
GET /api/billing/subscription
Current plan, status, and trial expiry.
GET /api/billing/usage
API call usage for the current billing period.
GET /api/billing/limits
Tier limits (connector count, API call cap, current usage).
Webhooks
Admin role required for all webhook endpoints.
GET /api/org/webhooks
List all registered outbound webhooks.
POST /api/org/webhooks
Register a new outbound webhook. Returns secret (HMAC signing key) only on creation — store it immediately.
Request body:
{
"url": "https://example.com/hook",
"events": ["tool.called", "approval.requested", "approval.decided"]
}Response: 201 Created
{
"id": "uuid",
"url": "https://example.com/hook",
"events": ["tool.called", "approval.requested", "approval.decided"],
"enabled": true,
"secret": "wh_abc123...",
"created_at": "2024-11-15T14:00:00Z"
}PATCH /api/org/webhooks/{id}
Update URL, events, or enabled state.
DELETE /api/org/webhooks/{id}
Delete a webhook.
Webhook payload format:
{
"id": "evt_uuid",
"type": "tool.called",
"org_id": "uuid",
"created_at": "2024-11-15T14:32:01Z",
"data": { ... }
}Signature headers:
X-ApexMCP-Signature: sha256=<HMAC-SHA256(secret, "<timestamp>.<raw-body>")>
X-ApexMCP-Timestamp: <unix-seconds>
X-ApexMCP-Event: <event-type>MCP Protocol
POST /mcp/{orgSlug}
The agent-facing MCP JSON-RPC endpoint. Auth via X-Api-Key or Authorization: Bearer.
Supported methods:
tools/list— list all available toolstools/call— execute a tool
If a tool requires human approval, the call is held and returns:
{
"structuredContent": { "status": "pending_approval", "approvalId": "uuid" }
}Poll check_approval_status (a synthetic tool in the MCP endpoint) to retrieve the outcome.
See Tool Approvals for the full flow.
Error responses
All errors follow a consistent format:
{
"error": "connector_not_found",
"message": "No connector found with id conn_xxxx"
}| HTTP Status | Meaning |
|---|---|
400 | Bad request — validation error |
401 | Unauthenticated |
403 | Forbidden — insufficient role or not an approver |
404 | Resource not found |
409 | Conflict — wrong state for operation |
422 | Unprocessable — semantic validation failed |
429 | Rate limited or monthly quota reached |
500 | Internal server error |
502 | Upstream service unavailable |