Observed since 20 Oct, 21:25 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
The authorization gateway for AI agents — spend authority, audit trail, and LangChain tools in one package.
The authorization gateway for AI agents.
One line to log. One line to authorize. One URL to verify.
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.
pip install agenitry
Zero dependencies. Python 3.9+.
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')}")
Agenitry doesn't just record what happened — it controls what can happen. Think of it as a traffic light, not a dashcam.
| # | 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) |
PENDING → APPROVED → EXECUTED → SETTLED
↘ ↘
DENIED REVERSED
↗
EXPIRED
# 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"])
# 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)
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"})
| 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.
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.
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) |
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.
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.
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.
| 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 |
| 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 |
AgenitryErrorRaised 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.
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"
]
MIT
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.2.0 | 11 Apr 2026 | 2 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 21:25 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:1fffd843cb254b28dce0cc2234d87b718323607c7ba62ad05cd30c6865d0d767