Documentation

Get your agent talking to AgentGate.

Four steps: create an account, connect Slack, call the API before a risky action, and let a human decide. No infrastructure to run — the queue, the Slack bot, and the audit log are already live.

01

Create an account and get an API key

Go to the sign-up page and create an organization — just a name, email is optional. You'll immediately get back an API key that looks like ag_xxxxxxxxxxxxxxxxxxxxxxxx.

Save it now. The key is only ever shown once, right after signup (or after a regenerate). AgentGate stores a hash of it, not the raw key — there's no "forgot my key" recovery, only regenerate, which invalidates the old one.

This key identifies your organization, not an individual agent. Every request your agents send — one agent or twenty — uses this same key, and every approval request created with it belongs to your org and only your org.

02

Connect Slack (or Teams)

Log in, go to Settings → Slack Integration, and click Add to Slack. You'll be sent to Slack to pick the workspace you want approvals posted to, then redirected back — connected.

  1. Click Add to Slack in Settings.
  2. Choose your Slack workspace (sign in if your browser isn't already signed in to it).
  3. Review the single permission requested — chat:write, so AgentGate can post approval cards — and click Allow.
  4. You're redirected back to Settings showing Connected.

There's no bot token to create or paste, and nothing to edit in a config file. Approval requests default to posting in #agent-approvals — create that channel in your workspace, or override it per-request (see below).

Prefer Microsoft Teams? In the same Settings page, add an Incoming Webhook URL from your Teams channel's connector settings instead — no OAuth needed for Teams.

03

Call the API before a risky action

Wherever your agent is about to do something that's expensive to get wrong — send an email, delete a record, deploy, move money — send a POST /api/v1/approvals request first, then wait for a decision before continuing.

Install the SDK

bash
pip install useagentgate

The install command is useagentgate — the import stays agentgate. Requires Python 3.10+, no other setup; the SDK already points at the live AgentGate API.

python
from agentgate import AgentGate

gate = AgentGate(api_key="ag_your_key_here")

result = await gate.request_approval(
    action="send_email",
    description="Send Q4 pricing proposal to client@acme.com",
    context={"deal_value": "$50,000", "recipient": "client@acme.com"},
    risk_tier="high",
    timeout_minutes=30,
)

if result.approved:
    send_the_email()
elif result.rejected:
    log_skipped(result.reason)
else:
    log_skipped("timed_out")

Not in an async context? Use from agentgate import AgentGateSync instead — same method, no await.

Using LangChain? Skip straight to the LangChain integration below — wrap any BaseTool with ApprovalRequiredTool instead of calling request_approval directly, zero extra boilerplate.

Or call the REST API directly

No Python, or want to see exactly what the SDK does under the hood? Same two calls, by hand:

curl
curl -X POST https://agentgate-w5qx.onrender.com/api/v1/approvals \
  -H "X-AgentGate-Key: ag_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "send_email",
    "description": "Send Q4 pricing proposal to client@acme.com",
    "context": { "deal_value": "$50,000", "recipient": "client@acme.com" },
    "risk_tier": "high",
    "timeout_minutes": 30
  }'

# then poll until status isn't "pending":
curl https://agentgate-w5qx.onrender.com/api/v1/approvals/{id} \
  -H "X-AgentGate-Key: ag_your_key_here"

Set risk_tier to low / medium / high / critical — this controls the default timeout (critical gets the shortest) and how the request is flagged in Slack. Leave it out and it defaults to medium.

04

What your reviewer sees and does

As soon as the request is created, a message posts to your connected Slack channel with the action, description, risk tier, and any context you sent — plus two buttons.

→
Approve resolves the request immediately — your agent's waiting call returns status: "approved".
→
Reject opens a small form asking for a reason, which gets attached to the request and shown back to your agent.
→
No response before the deadline auto-resolves to timed_out — silence is never treated as approval.

Every request, decision, and reason is recorded in your Audit Log(Dashboard → Audit Log), exportable as CSV.

05

LangChain integration

langchain-agentgate wraps any existing BaseTool so it requires approval before it runs — no rewriting the tool, no restructuring your agent. It's a thin layer around what you already built.

bash
pip install langchain-agentgate
python
from agentgate import AgentGate
from langchain_agentgate import ApprovalRequiredTool

gate = AgentGate(api_key="ag_your_key_here")

# send_email_tool is any BaseTool you already have — unchanged
gated_send_email = ApprovalRequiredTool(
    wrapped_tool=send_email_tool,
    gate=gate,
    risk_tier="high",
    timeout_minutes=15,
)

# use gated_send_email anywhere send_email_tool would have gone —
# same name, same input schema, same output type
agent_executor = create_agent_executor(tools=[gated_send_email, ...])

result = await agent_executor.ainvoke({
    "input": "email the Q4 proposal to john@acme.com"
})

That's the whole integration. gated_send_email has the same name and args schema as the tool it wraps, so nothing else in your agent needs to know it's gated. When the agent calls it, execution pauses, a request posts to Slack/Teams exactly like the REST flow above, and the call only resumes once a human responds — or the timeout hits.

ParameterWhat it does
wrapped_toolThe existing BaseTool to gate. Required.
gateAn AgentGate (async) or AgentGateSync instance. Required.
risk_tierlow / medium / high / critical. Defaults to medium.
timeout_minutesAuto-rejects if nobody responds in time. Defaults to 30.
approverOptional Slack handle to @mention directly, e.g. "@sarah".
slack_channelOptional override of the default connected channel.
Rejections don't crash your agent. If the request is rejected, the tool call returns a string like "Action 'send_email' was rejected by @sarah: too aggressive a discount" as its output instead of raising an exception — so the agent sees what happened and can react to it (apologize, try a different approach, ask the user), the same way it would handle any other tool result.

Officially listed in LangChain's own integrations docs and published on PyPI.

06

CrewAI integration

crewai-agentgate is the same wrapper pattern as the LangChain integration, built for CrewAI's BaseTool. Gate any tool you give an Agent — no restructuring the crew.

bash
pip install crewai-agentgate
python
from agentgate import AgentGate
from crewai_agentgate import ApprovalRequiredTool

gate = AgentGate(api_key="ag_your_key_here")

# publish_content_tool is any BaseTool you already have — unchanged
gated_publish = ApprovalRequiredTool(
    wrapped_tool=publish_content_tool,
    gate=gate,
    risk_tier="high",
    timeout_minutes=15,
)

# give gated_publish to an Agent anywhere publish_content_tool would have gone
publisher = Agent(
    role="Content Publisher",
    goal="Publish approved content to the appropriate platforms",
    tools=[gated_publish],
)

Same behavior as the LangChain wrapper: gated_publish keeps the same name and args schema as the tool it wraps, execution pauses when the agent calls it, a request posts to Slack/Teams, and the call only resumes once a human responds — or the timeout hits. Parameters (risk_tier, timeout_minutes, approver, slack_channel) are identical to the LangChain version above.

Rejections don't crash your crew. Same as LangChain — a rejected or timed-out call returns a string explaining what happened as its output instead of raising, so the crew keeps running and the agent can react to it.

Published on PyPI.

Frequently asked

How does "Add to Slack" link to my agent?

It doesn't connect to a specific agent — it connects to your organization. Here's the full path a single approval request takes:

1
Your agent's code calls POST /api/v1/approvals using your org's X-AgentGate-Key.
2
AgentGate looks up which org that key belongs to, and finds the Slack workspace token that org connected via Add to Slack.
3
It posts the approval card into your connected workspace — never a different org's.
4
A teammate clicks Approve or Reject in Slack. That click hits AgentGate's Slack endpoint and resolves the request.
5
Your agent's call — which has been polling GET /api/v1/approvals/{id} — sees the new status and continues or stops.

So the Slack connection is a one-time, per-organization setup step — you do it once in Settings, and every agent, script, or process that uses your API key automatically posts into that same workspace. You never connect Slack per-agent, and you never touch a bot token.

Reference

Core endpoints

All requests need X-AgentGate-Key: ag_your_key_here. Full interactive reference: https://agentgate-w5qx.onrender.com/docs.

EndpointWhat it does
POST /api/v1/approvalsCreate an approval request. Posts to Slack/Teams if connected.
GET /api/v1/approvals/{id}Check a request's status. Poll this until it's not pending.
GET /api/v1/approvalsList requests, filterable by status and risk_tier.
POST /api/v1/actions/logLog a completed action to the audit trail without requiring approval.
GET /api/v1/audit-logRetrieve or export (?export_csv=true) the audit trail.