Technical Reference · June 2026

Navige Technical Reference

Navige is a governance proxy and API for AI agent tool calls. It sits between your agent and external actions, evaluating each call against your rules before allowing it to proceed. Every decision is logged to Supabase and anchored to the Polygon blockchain hourly.

API Base URL
https://api.navige.ai
Auth Header
x-api-key: tl_your_key

Quick Start

The fastest path is the drop-in proxy — change one environment variable and every OpenAI or Anthropic call is governed automatically.

Option A — OpenAI proxy (no code change)

python
from openai import OpenAI

client = OpenAI(
    api_key="sk-your-openai-key",
    base_url="https://api.navige.ai/v1",        # ← only change needed
    default_headers={"x-api-key": "tl_your_key"}     # ← add TrustLoop auth
)
# Everything else is identical to normal OpenAI usage

Option B — Python SDK (explicit intercept)

bash
pip install trustloop-sdk
python
from trustloop import TrustLoop

tl = TrustLoop(api_key="tl_your_key", agent_name="my-agent")

# Option 1: explicit intercept
result = tl.intercept("send_email", {"to": "user@example.com"})
if result["allowed"]:
    send_email(...)

# Option 2: decorator — wraps a function, blocks it if not allowed
@tl.guard()
def delete_records(table: str, where: dict):
    ...

Authentication

All authenticated endpoints require your Navige API key. Pass it as a header:

http
x-api-key: tl_your_key_here

Keys are created when you sign up at navige.ai/signup. Each key belongs to a tenant and carries all associated limits and rules. Retrieve a lost key via POST /api/resend-key with your email.

OpenAI Drop-in Proxy

Endpoint: POST /v1/chat/completions Requires x-api-key

A transparent proxy to the OpenAI Chat Completions API. Set this as your client's base_url. Your OpenAI key goes in the standard Authorization: Bearer header. Navige API key goes in x-api-key.

Zero code change. If your agent already uses the OpenAI SDK, you only need to change 2 lines: add base_url and default_headers to your client constructor.

Headers

HeaderRequiredDescription
AuthorizationRequiredYour OpenAI key: Bearer sk-xxx
x-api-keyRequiredYour Navige key: tl_xxx
x-agent-nameOptionalAgent identifier for per-agent tracking in the dashboard

Python

python
from openai import OpenAI

client = OpenAI(
    api_key="sk-your-openai-key",
    base_url="https://api.navige.ai/v1",
    default_headers={
        "x-api-key": "tl_your_key",
        "x-agent-name": "finance-agent"  # optional
    }
)

Node.js

javascript
const { OpenAI } = require('openai')

const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
  baseURL: 'https://api.navige.ai/v1',
  defaultHeaders: {
    'x-api-key': process.env.TRUSTLOOP_API_KEY,
    'x-agent-name': 'my-agent'
  }
})
Streaming: Streaming calls are passed through transparently — governance (kill-switch, rules) is enforced on non-streaming calls only. Streaming calls are logged post-stream. If you need enforcement, disable streaming or use the REST intercept endpoint.

Anthropic Drop-in Proxy

Endpoint: POST /proxy/anthropic/v1/messages Requires x-api-key

Transparent proxy to the Anthropic Messages API. Intercepts tool_use content blocks before returning the response to your agent. Same governance pipeline as the OpenAI proxy.

Headers

HeaderRequiredDescription
x-anthropic-api-keyRequiredYour Anthropic API key
x-api-keyRequiredYour Navige key
anthropic-versionOptionalForwarded to Anthropic. Default: 2023-06-01
x-agent-nameOptionalAgent identifier for dashboard tracking

Python

python
import anthropic

client = anthropic.Anthropic(
    api_key="sk-ant-your-key",
    base_url="https://api.navige.ai/proxy/anthropic",
    default_headers={
        "x-api-key": "tl_your_key",
        "x-agent-name": "my-claude-agent"
    }
)

Python SDK

bash
pip install trustloop-sdk                      # sync (requests)
pip install "trustloop-sdk[async]"             # + async (httpx)
pip install "trustloop-sdk[langchain]"         # + LangChain helpers
pip install "trustloop-sdk[crewai]"            # + CrewAI helpers
pip install "trustloop-sdk[all]"               # everything

Core client

python
from trustloop import TrustLoop, TrustLoopBlockedError

tl = TrustLoop(api_key="tl_xxx", agent_name="my-agent")

# Explicit intercept
result = tl.intercept("send_email", {"to": "...", "subject": "..."})
if result["allowed"]:
    send_email(...)

# Guard decorator — raises TrustLoopBlockedError if blocked
@tl.guard("delete_records")
def delete_records(table: str, where: dict):
    ...

# LangChain integration
from trustloop.integrations.langchain import wrap_tools
governed_tools = wrap_tools(tl, tools)

# CrewAI integration
from trustloop.integrations.crewai import governed_tool

@governed_tool(tl)
class SendEmailTool(BaseTool):
    ...

Node.js SDK

bash
npm install trustloop
javascript
const { TrustLoop } = require('trustloop')

const tl = new TrustLoop({ apiKey: process.env.TRUSTLOOP_API_KEY, agentName: 'my-agent' })

const result = await tl.intercept('send_email', { to: 'user@example.com' })
if (result.allowed) {
  await sendEmail(...)
}

MCP — Claude Desktop

Connect Claude Desktop by adding Navige as an MCP server in your config. Every tool call Claude makes passes through Navige's governance pipeline.

json — claude_desktop_config.json
{
  "mcpServers": {
    "trustloop": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://api.navige.ai/sse?api_key=tl_xxx"]
    }
  }
}

REST Intercept

Use the REST endpoint when you want explicit control — call it before any sensitive action in your own code, no SDK needed.

POST /api/intercept POST Auth

Evaluates a tool call against your governance rules. Call this before executing any sensitive action. Optionally, include forward_to to have Navige execute the tool on your behalf after approval — single round trip, actual response returned.

Request body

FieldTypeRequiredDescription
tool_namestringRequiredThe action or tool being called. Use descriptive names: send_email, delete_record, transfer_funds.
argumentsobjectOptionalParameters passed to the tool. Included in AI rule evaluation and audit log (PII masked before storage).
agent_namestringOptionalIdentifier for the calling agent. Enables per-agent tracking, breakdowns, and scoped kill-switches.
reasonstringOptionalPlain English explanation of why the agent wants to take this action. Stored in the audit log and shown in the approval email so the human approver sees intent, not just raw parameters. PII is masked before storage.
forward_toobjectOptionalIf provided and the call is ALLOWED, Navige forwards the request to this HTTP endpoint and returns the real response. If the tool has a stored credential, it is injected automatically. Blocked calls are never forwarded. See below.
approval_idstringOptionalUUID from a previous PENDING response. Pass with approved_hash to fast-path the call after human approval without re-evaluating rules.
approved_hashstringOptionalThe payload_hash returned in the PENDING response. Navige verifies this matches the stored hash and the current arguments — if args changed since approval, the call is blocked.

forward_to object

FieldTypeRequiredDescription
urlstringRequiredThe HTTPS endpoint to call. Private/internal IPs are blocked.
methodstringOptionalHTTP method. Defaults to POST.
headersobjectOptionalHeaders to include in the forwarded request (e.g. Authorization). Not stored in audit logs.
bodyobjectOptionalRequest body to forward. If omitted, arguments is used as the body.
python — intercept + forward in one call
result = requests.post("https://api.navige.ai/api/intercept",
  headers={"x-api-key": "tl_xxx"},
  json={
    "tool_name": "send_email",
    "arguments": {"to": "user@example.com", "subject": "Hello"},
    "agent_name": "my-agent",
    "reason": "User requested a welcome email after completing onboarding",
    "forward_to": {
      "url": "https://api.resend.com/emails",
      "method": "POST",
      "headers": {"Authorization": "Bearer re_xxx"}
    }
  }
).json()
# result → { "allowed": true, "forwarded": true, "status_code": 200, "result": {...} }
# If blocked → { "allowed": false, "decision": "BLOCKED" } — forward_to is never called

Response

json — ALLOWED
{ "allowed": true, "decision": "ALLOWED" }
json — ALLOWED + forwarded
{ "allowed": true, "decision": "ALLOWED", "forwarded": true, "status_code": 200, "result": { "..." } }
json — BLOCKED
{ "allowed": false, "decision": "BLOCKED", "message": "Blocked by governance rule: ..." }
json — PENDING APPROVAL
{ "allowed": false, "decision": "ESCALATED", "status": "pending_approval", "approval_id": "uuid", "payload_hash": "sha256hex", "expires_at": "2026-07-22T14:30:00.000Z" }

After the human approves, retry with approval_id and approved_hash (the value of payload_hash above). Navige verifies the approval and that the payload hasn't changed before allowing.

GET /api/logs GET Auth

Returns the last 100 tool call records for your account, newest first.

Query params

ParamDescription
agentFilter by agent name. Use all or omit for all agents.
limitMax results. Default 100.

GET /api/stats GET Auth

Returns aggregate counts for the current month plus per-agent breakdown.

json
{
  "total": 1842,
  "allowed": 1790,
  "blocked": 48,
  "pending": 4,
  "usage": { "plan": "growth", "used": 1842, "limit": 1000000 },
  "agents": {
    "used": 3, "limit": 10,
    "breakdown": [
      { "name": "finance-agent", "total": 920, "allowed": 898, "blocked": 22 }
    ]
  }
}

Approval Rules Auth

GET /api/approval-rules
List all governance rules for your account.
POST /api/approval-rules
Create a new governance rule in plain English.
FieldRequiredDescription
rule_textRequiredPlain-English rule: "Block any action that deletes customer data"
actionRequiredblock or approve (requires human approval)
approver_emailOptionalOverride notification email for this rule. Falls back to account default.
DELETE /api/approval-rules/:id
Delete a rule by ID. Invalidates rule and AI decision caches immediately.

Kill-Switch Auth

GET /api/blocked-tools
List all currently blocked tools. Returns agent_name: null for global blocks.
POST /api/blocked-tools
Immediately block a tool. Takes effect on the next intercept call.
FieldRequiredDescription
tool_nameRequiredTool to block
reasonOptionalReason stored in audit log
agent_nameOptionalScope block to a specific agent. Omit or null for all agents.
DELETE /api/blocked-tools/id/:id
Unblock by row ID. Use this (not tool name) to avoid accidentally removing the wrong scoped rule.

Tool Registry Auth

Register your real tools so Navige's MCP server advertises them to Claude Desktop instead of the default demo set. Each tool can include a forward_url — when a call is ALLOWED, Navige calls that endpoint and returns the real response.

GET /api/tools
List all registered tools for your account.
POST /api/tools
Register or update a tool. Use upsert behaviour — posting the same tool_name twice updates it.
FieldRequiredDescription
tool_nameRequiredUnique name for this tool, e.g. send_email
descriptionRequiredPlain-English description shown to the LLM
input_schemaOptionalJSON Schema object describing the tool's arguments
forward_urlOptionalHTTPS endpoint to call when this tool is ALLOWED. If omitted, Navige logs the call but does not execute it.
forward_methodOptionalHTTP method for the forwarded call. Default POST.
forward_headersOptionalHeaders for the forwarded request, e.g. {"Authorization": "Bearer sk_xxx"}. Not stored in audit logs.
python
requests.post("https://api.navige.ai/api/tools",
  headers={"x-api-key": "tl_xxx"},
  json={
    "tool_name": "send_email",
    "description": "Send a transactional email",
    "input_schema": {
      "type": "object",
      "properties": {
        "to": {"type": "string"},
        "subject": {"type": "string"},
        "body": {"type": "string"}
      },
      "required": ["to", "subject", "body"]
    },
    "forward_url": "https://api.resend.com/emails",
    "forward_headers": {"Authorization": "Bearer re_xxx"}
  }
)
DELETE /api/tools/:tool_name
Remove a registered tool. The MCP server will stop advertising it immediately.

Credential Storage

Store an encrypted API key for a tool. Navige injects it automatically into forward_to requests — the agent never holds the credential directly. Credentials are encrypted with AES-256-GCM at rest and never returned by the API.

POST /api/tools/:tool_name/credentials
Store or replace the credential for a tool.
FieldRequiredDescription
header_nameOptionalHeader to inject the credential into. Default Authorization.
valueRequiredThe credential value, e.g. Bearer sk-xxx. Encrypted immediately, never stored in plain text.
GET /api/tools/:tool_name/credentials
Check whether a credential is set. Returns { exists, header_name, created_at } — the credential value is never returned.
DELETE /api/tools/:tool_name/credentials
Remove the stored credential for a tool.

Pending Approvals Auth

GET /api/pending-approvals
List all tool calls currently awaiting human decision.
POST /api/pending-approvals/:id/decide
Approve or deny a pending tool call.
FieldRequiredDescription
actionRequired"approved" or "denied"

Governance Pipeline

Every call to /api/intercept or through the proxy runs this pipeline in order. The first rule that matches stops evaluation and returns a decision.

1
Authentication
API key validated. Account and plan resolved from the database.
401 if invalid
2
Usage limit check
Monthly tool call count checked against plan limit. Free = 5K, Starter = 100K, Growth = 1M, Business = 5M.
429 if exceeded
3
Agent limit check
If agent_name is new this month, checks whether the tenant has capacity for another agent under their plan.
429 if exceeded
4
Kill-switch check
Checks for global kill-switch rules and any agent-scoped rules matching the calling agent. Instant — no AI involved.
BLOCKED
5
AI rule evaluation
Plain-English rules are fetched and evaluated by an AI model against the incoming tool call. Decisions are cached to keep latency low. ~90% cache hit rate in practice.
BLOCKED
6
Pending approval (if rule action = approve)
Creates a pending approval record. Sends notification to Slack, Teams, Discord, and/or email. Call returns PENDING — agent must retry after human decides.
PENDING
7
Log + ALLOWED
Tool call logged to the audit database with PII masking applied. Decision returned to caller.
ALLOWED

AI Rule Caching

To keep latency low, Navige uses two caches:

Important: After you add or delete a rule, the next tool call for that tenant will always re-run the AI evaluation — the caches are invalidated synchronously on rule changes.

PII & Compliance

Before any tool call is written to the audit log, Navige's compliance middleware automatically:

Additional compliance endpoints:

Blockchain Anchoring

Every hour, Navige hashes all tool call logs from the previous hour and records the hash on the Polygon Mainnet via a smart contract at 0xd2544fc3164ac0eBfb6B7A2c193800F9651Fc46F.

This creates an independently verifiable tamper-evident record. If any logs are deleted or modified in Supabase, recomputing the hash from the remaining records will not match what's on-chain.

Anchor records are stored alongside your audit logs. Use the Blockchain tab in your dashboard to see every anchor with a direct Polygonscan link, or query the API below to verify programmatically.

Current implementation: Batch-level hashing — proves a batch of records was unchanged, but doesn't prove completeness (a deleted record before the hash is taken won't be detected). Per-record Merkle proofs are on the roadmap.

GET /api/blockchain/anchors GET Auth

Returns the list of blockchain anchor records for your account. Each record includes the batch hash, Polygon transaction hash, and a pre-computed Polygonscan link so you can verify without any blockchain tooling.

Query params

FieldTypeRequiredDescription
limitnumberOptionalMax records to return. Default 20, max 100.
json — response
{
  "contract_address": "0xd2544fc3164ac0eBfb6B7A2c193800F9651Fc46F",
  "anchors": [
    {
      "id": "uuid",
      "log_hash": "0xabc123...",
      "tx_hash": "0xdef456...",
      "log_count": 142,
      "created_at": "2026-07-22T14:00:00.000Z",
      "polygonscan_url": "https://polygonscan.com/tx/0xdef456..."
    }
  ]
}

How to verify a batch independently

  1. Export your audit log for the batch's time window
  2. Recompute: ethers.keccak256(ethers.toUtf8Bytes(JSON.stringify(records))) over id, tenant_id, tool_name, status, created_at ordered by created_at ascending
  3. Compare to log_hash above
  4. Open the polygonscan_urlMore details → Input data — the same hash is written on-chain

Plan Limits

PlanPriceCalls/moAgentsRetention
Free$05,00017 days
Starter$29/mo100,000330 days
Growth$249/mo1,000,0001090 days
Business$649/mo5,000,000Unlimited1 year
EnterpriseCustomCustomUnlimitedCustom

Limits are enforced at the intercept point. When a limit is exceeded, the API returns HTTP 429 with a clear error message. Usage resets on the 1st of each calendar month.

Ready to connect?
Follow the interactive setup guide for your exact stack.
Open Setup Guide →