What endpoints does the Enforgate API expose?
The gateway has two authenticated surfaces (a verdict check and an MCP proxy) plus public, token-capability approve/deny links. Examples use the gateway at the URL below.
Authentication
All /v1/* and /mcp requests use a Bearer API key. The gateway looks up the sha256 hash of the key; missing, invalid, revoked, or expired keys get a 401. The matched key's policy is what your call is evaluated against.
Authorization: Bearer enf_your_api_keyPOST /v1/check
Returns a verdict for a single tool call and writes one audit-log entry. Use it to gate a call from your own code without proxying through MCP.
Request body: serverName and toolName are required; args is optional and evaluated in memory only (never stored):
curl -s https://api.enforgate.com/v1/check \
-H "Authorization: Bearer enf_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"serverName": "demo",
"toolName": "send_email",
"args": { "to": "someone@example.com" }
}'Response: decision is allow, deny, or pending:
{
"decision": "allow",
"reason": "matched rule 0 of policy \"default\"",
"policyId": "8f3c…",
"toolCallId": "1a2b…",
"latencyMs": 6
}Treat anything other than allowas “do not proceed.” If the audit write fails, the endpoint returns 500and no verdict. Enforgate never allows a call it couldn't record.
decision: "pending" is not a final outcome. When a policy says require_approval, the gateway never holds this connection open waiting on a human — it returns immediately with a referenceId instead of policyId/toolCallId alone:
{
"decision": "pending",
"reason": "matched rule 1 of policy \"default\"",
"policyId": "8f3c…",
"toolCallId": "1a2b…",
"referenceId": "9c0d…",
"message": "awaiting human approval — this response does not represent the final outcome…",
"latencyMs": 4
}The decision (approved, denied, or timed out) is resolved in the background after this response is sent. The only way to learn it is the approval.created / approval.resolved webhooks — there is no polling endpoint today. See setting up approvals for the full flow.
POST /mcp
The MCP proxy. Connect any MCP client here with your Bearer key. On initialize the gateway opens a session bound to your key and connects to that key's Connected Tools. tools/list returns their tools namespaced <name>__<tool>; tools/call is guarded by your policy: allowed calls are forwarded, blocked ones return an MCP error result with the reason. A call needing approval also returns immediately — never held — as a structured, Enforgate-specific result: {status: "pending", referenceId, message}, not a standard MCP shape. No off-the-shelf MCP client understands this on its own; your agent/orchestrator code needs to recognize it and resume from the approval.resolved webhook once it fires. See the integration guides for client config.
Session tokens (ens_)
Session tokens are short-lived, optionally tool-scoped credentials minted from a long-lived enf_ key. Hand one to each agent run; when the run ends, the session expires automatically. Revoke a session immediately from the Sessions page if a token is leaked.
All session routes require a enf_ Bearer key. Session tokens themselves cannot mint child sessions.
curl -s -X POST https://api.enforgate.com/v1/sessions \
-H "Authorization: Bearer enf_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"label": "my-agent-run",
"ttlMinutes": 60,
"scopeTools": ["demo__send_email"]
}'The response includes the raw token (returned exactly once) plus metadata:
{
"token": "ens_…",
"id": "uuid",
"label": "my-agent-run",
"prefix": "ens_a1b2",
"scopeTools": ["demo__send_email"],
"expiresAt": "2025-01-01T02:00:00Z"
}Pass the session token as the Bearer key for all subsequent MCP or /v1/check calls. The session inherits the parent key's policy and, when scopeTools is set, additionally blocks any tool not in the list before policy evaluation.
GET /v1/sessions: list active sessions for the calling key.DELETE /v1/sessions/:id: revoke a session immediately.
Approve / deny endpoints
These are public (no Bearer key): the capability is the single-use token in the URL, sent in the approval notification. They are rate-limited per IP.
GET /v1/approve/:token?action=approve|deny: resolves the held call in one click (approve is for this call only). The page auto-submits the decision in a real browser but never mutates on the GET itself, so email-scanner link prefetch can't trigger it. Keys requiring authenticated approval redirect to the dashboard sign-in first, then resolve with the clicked action.POST /v1/approve/:token: resolves the approval (JSON or form):{ "action": "approve", "duration": "1h" }. Used or expired tokens return410.
curl -s -X POST https://api.enforgate.com/v1/approve/THE_TOKEN \
-H "Content-Type: application/json" \
-d '{ "action": "approve", "duration": "1h" }'