The authorization gateway for AI agents — spend authority, audit trail, and LangChain tools in one package.
Project description
Agenitry Python SDK
The authorization gateway for AI agents.
One line to log. One line to authorize. One URL to verify.
The problem
Your AI agent takes actions — reservations, orders, comps, purchases — but nobody controls what it can spend. You're flying blind with an open wallet.
Agenitry gives every agent action a permanent, verifiable record and lets you control what agents can do before they do it. Log an event in one line. Authorize spend in one line. Share a URL. Done.
Install
pip install agenitry
Zero dependencies. Python 3.9+.
Quick start
from agenitry import Agenitry
agent = Agenitry(api_key="ag_your_key", venue_id="nobo-downtown")
# ── Audit trail ──────────────────────────────────────────────
# Log an event — fire and forget by default
agent.log(action="order_captured", amount=42.50, direction="inbound")
# Await confirmation if you need the event ID
event = agent.log(action="reservation_booked", amount=0, await_confirmation=True)
print(event["id"]) # evt_abc123
# Query events
result = agent.events(action="order_captured", limit=10)
# Get stats
stats = agent.stats(period="7d")
print(stats["total_inbound"], stats["event_count"])
# ── Spend authority ──────────────────────────────────────────
# Set a policy: max $500 per order, need approval above $200
agent.set_policy(
agent_id="voice-agent",
max_single_amount=500,
max_daily_spend=5000,
require_approval_above=200,
allowed_actions=["order_captured", "reservation_booked", "comp_issued"],
)
# Authorize before the agent acts
auth = agent.authorize(action="order_captured", amount=127.00, agent_id="voice-agent")
if auth["approved"]:
# Agent can proceed — mark as executed
agent.execute(auth["authorization_id"])
# Payment confirmed — settle it
agent.settle(auth["authorization_id"])
else:
# Denied or pending owner approval
print(f"Denied: {auth.get('denial_reason')}")
Spend Authority
Agenitry doesn't just record what happened — it controls what can happen. Think of it as a traffic light, not a dashcam.
How it works
- Set a policy — define limits for each agent (or venue-wide defaults)
- Authorize before acting — every spend request goes through the policy engine
- Auto-approve, auto-deny, or pending — based on your rules
- Execute → Settle — track the full lifecycle
The 5 checks (in order)
| # | Check | If failed | Example |
|---|---|---|---|
| 1 | Max single amount | Auto-denied | $36K order blocked by $500 limit |
| 2 | Allowed actions | Auto-denied | refund_issued not in whitelist |
| 3 | Daily spend limit | Auto-denied | Would exceed $5K/day |
| 4 | Monthly spend limit | Auto-denied | Would exceed $50K/month |
| 5 | Approval threshold | Pending | $340 order needs owner approval (threshold: $200) |
Authorization lifecycle
PENDING → APPROVED → EXECUTED → SETTLED
↘ ↘
DENIED REVERSED
↗
EXPIRED
Methods
# Request authorization — always await this
auth = agent.authorize(action="order_captured", amount=127.00)
# Mark as executed (auto-creates an audit trail event)
agent.execute(auth["authorization_id"])
# Settle — payment confirmed, permanently closed
agent.settle(auth["authorization_id"])
# Reverse — cancel an approved or executed authorization
agent.reverse(auth["authorization_id"])
# List authorizations with filters
agent.authorizations(status="pending", agent_id="voice-agent")
# Get a single authorization
agent.get_authorization(auth["authorization_id"])
Policies
# Create or update a policy (per-agent or venue-wide)
agent.set_policy(
agent_id="voice-agent", # None = venue-wide default
max_single_amount=500, # Max per transaction
max_daily_spend=5000, # Rolling 24-hour limit
max_monthly_spend=50000, # Rolling 30-day limit
require_approval_above=200, # Amount that triggers human approval
allowed_actions=["order_captured", "reservation_booked", "comp_issued"],
)
# List all policies
policies = agent.get_policies()
# Delete a policy
agent.delete_policy(policy_id)
LangChain Integration
Agenitry ships with built-in LangChain tools so your agents can request authorization before spending money:
pip install agenitry langchain langchain-openai
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
from agenitry.langchain import create_authorize_tool, create_log_event_tool
# Create tools backed by your Agenitry policy
authorize = create_authorize_tool(
api_key="ag_your_key",
venue_id="nobo-downtown",
agent_id="voice-agent",
)
log_event = create_log_event_tool(
api_key="ag_your_key",
venue_id="nobo-downtown",
agent_id="voice-agent",
)
# Use with any LangChain agent
llm = ChatOpenAI(model="gpt-4o")
prompt = ChatPromptTemplate.from_messages([
("system", "You are a restaurant voice agent. Always authorize before taking orders."),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
])
agent = create_tool_calling_agent(llm, [authorize, log_event], prompt)
executor = AgentExecutor(agent=agent, tools=[authorize, log_event])
# The agent will now check spend authority before placing orders
result = executor.invoke({"input": "I'd like to order the omakase dinner for 2"})
Available LangChain tools
| Tool | Description |
|---|---|
create_authorize_tool() |
Request spend authorization before taking financial actions |
create_log_event_tool() |
Log events to the audit trail |
create_set_policy_tool() |
Create or update spend policies (admin use) |
Each tool is a proper StructuredTool with typed inputs, descriptions, and error handling.
Verify URL
Every event gets a permanent, shareable URL:
https://agenitry.com/verify/{venue_id}/{event_id}
No login required. No dashboard needed. Just share the link and anyone can verify what happened.
API Reference
Agenitry(api_key, venue_id, *, agent_id=None, base_url=None, max_retries=3, retry_base_delay=0.5)
Create a new Agenitry client.
| Parameter | Type | Default | Description |
|---|---|---|---|
api_key |
str |
required | Your venue API key (ag_...) |
venue_id |
str |
required | Your venue identifier |
agent_id |
str |
None |
Default agent ID for all events |
base_url |
str |
https://api.agenitry.com |
API base URL |
max_retries |
int |
3 |
Max retry attempts on 429/5xx |
retry_base_delay |
float |
0.5 |
Base delay in seconds (exponential backoff) |
Audit Trail
agent.log(action, *, amount=None, currency=None, direction=None, agent_id=None, context=None, reason=None, await_confirmation=False)
Log an event to the audit trail.
| Parameter | Type | Default | Description |
|---|---|---|---|
action |
str |
required | Event action (see below) |
amount |
float |
None |
Dollar amount |
currency |
str |
None |
ISO-4217 currency code |
direction |
str |
None |
inbound, outbound, or internal |
agent_id |
str |
constructor default | Agent that performed the action |
context |
dict |
None |
Arbitrary JSONB context data |
reason |
str |
None |
Human-readable reason |
await_confirmation |
bool |
False |
If True, waits for server response |
Fire and forget (default): returns immediately with {id: "", status: "logged"}. If the request fails, it's silently swallowed.
Await confirmation: waits for the server response and raises AgenitryError on failure.
agent.events(*, agent_id=None, action=None, context=None, limit=50, offset=0)
Query events for the venue.
agent.stats(*, period="today")
Get aggregate stats. Period: today, 7d, 30d, or all.
Spend Authority
agent.authorize(action, amount, *, agent_id=None, currency=None, context=None, reason=None)
Request spend authorization. Always await this — you need to know if the action is approved before proceeding.
Returns a dict with approved (bool), status (approved/denied/pending), authorization_id, and denial_reason if denied.
agent.execute(authorization_id, *, actual_amount=None, context=None)
Mark an authorization as executed. Auto-creates a linked event in the audit trail.
agent.settle(authorization_id, *, context=None)
Settle an executed authorization — permanently close it after payment is confirmed.
agent.reverse(authorization_id)
Reverse an approved or executed authorization. Creates a reversal event in the audit trail.
agent.authorizations(*, agent_id=None, action=None, status=None, limit=50, offset=0)
List authorizations with filters.
agent.get_authorization(authorization_id)
Get a single authorization by ID.
Policies
agent.set_policy(*, agent_id=None, max_single_amount=None, max_daily_spend=None, max_monthly_spend=None, require_approval_above=None, allowed_actions=None)
Create or update a spend policy. If agent_id is provided, the policy applies only to that agent. If None, it's the venue-wide default.
agent.get_policies()
List all spend policies for the venue.
agent.delete_policy(policy_id)
Delete a policy by ID.
Event Actions
| Action | Description | Direction | Example |
|---|---|---|---|
order_captured |
Agent captured an order | inbound |
Voice agent took a $42.50 takeout order |
reservation_booked |
Agent booked a reservation | inbound |
Chatbot reserved table 7 for 8pm |
price_changed |
Agent changed a price | internal |
Agent updated happy hour draft from $6 to $7 |
item_86d |
Agent marked an item as unavailable | internal |
Agent 86'd the tuna special |
comp_issued |
Agent issued a comp | outbound |
Agent comped dessert for a regular |
purchase_order |
Agent placed a purchase order | outbound |
Agent ordered 50 lbs of salmon |
Authorization Statuses
| Status | Meaning |
|---|---|
pending |
Awaiting owner approval (above threshold) |
approved |
Auto-approved or owner-approved |
denied |
Auto-denied or owner-denied |
expired |
Approved but not executed within 5 minutes |
executed |
Action has been carried out |
settled |
Payment confirmed, permanently closed |
reversed |
Cancelled after approval/execution |
AgenitryError
Raised on API errors. Attributes:
| Attribute | Type | Description |
|---|---|---|
status |
int |
HTTP status code (0 if no response) |
body |
dict or None |
Parsed response body |
code |
str |
Error code: NETWORK, TIMEOUT, or API |
create_agenitry(api_key, venue_id, **kwargs)
Factory function. Returns an Agenitry instance. Same arguments as the constructor.
Type Aliases
EventAction = Literal[
"order_captured", "reservation_booked", "price_changed",
"item_86d", "comp_issued", "purchase_order"
]
EventDirection = Literal["inbound", "outbound", "internal"]
StatsPeriod = Literal["today", "7d", "30d", "all"]
AuthorizationStatus = Literal[
"pending", "approved", "denied", "expired", "reversed", "executed", "settled"
]
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agenitry-0.2.0.tar.gz.
File metadata
- Download URL: agenitry-0.2.0.tar.gz
- Upload date:
- Size: 16.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e11789712eb9c72347c35741f8151e31c2515a8b85f9a1e258ff604caee7f48f
|
|
| MD5 |
e8b230f224db6c86d33a4a61612a185a
|
|
| BLAKE2b-256 |
2680793f82207d9f4d93f9a1ab352907b1c3bbc90616c2eed7b7e1877b915a3e
|
File details
Details for the file agenitry-0.2.0-py3-none-any.whl.
File metadata
- Download URL: agenitry-0.2.0-py3-none-any.whl
- Upload date:
- Size: 12.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d158123eeb0ffcb1e32777da623dbcb3f07d626005627b03da940de52eba8e61
|
|
| MD5 |
a16762f0e3e8de9fdeae165cc931a60f
|
|
| BLAKE2b-256 |
8d5804a1e003959b5da7e5f428fea01126ab319f1579d0320bb50ed189ba9c26
|