Developers / API
API Reference
Everything you need to integrate Intended into your systems.
Authentication
All API requests must be authenticated. Intended supports two authentication methods, and every request must include a tenant identifier.
API Key Authentication
Pass your API key via the Authorization header or the x-api-key header.
Authorization: Bearer mrt_live_...
or
x-api-key: mrt_live_...
Portal Session Authentication
For portal / console integrations, pass the session ID header.
x-portal-session-id: ps_...
Tenant Identification
All requests must include a tenant identifier to scope authority evaluation to the correct organization.
x-tenant-id: tenant_...
curl -X POST https://api.intended.so/v1/intent \
-H "Authorization: Bearer mrt_live_abc123" \
-H "x-tenant-id: tenant_xyz" \
-H "Content-Type: application/json" \
-d '{
"action": "deploy application to production",
"actor": "agent:github-actions",
"system": "github",
"metadata": {
"repo": "acme/frontend",
"branch": "main"
}
}'Core Endpoints
The Intended REST API operates over HTTPS. All request and response bodies are JSON-encoded.
Intent Evaluation
/intentSubmit an intent for evaluation. Returns a decision, risk score, confidence level, and a signed authority token./intent/:idGet intent details and decision trace for a previously evaluated intent./intent/:id/evidence-bundleDownload the HMAC-signed evidence bundle for a completed intent evaluation.Authority & Approval
/authority/approvalRecord a human approval for an escalated intent. Includes rationale and approver identity./authority/thresholds/:tenantIdGet current risk thresholds for the specified tenant./authority/thresholds/:tenantIdUpdate risk thresholds for the specified tenant. Requires admin or policy_admin role.Audit & Evidence
/audit/:tenantId/timelineGet paginated audit timeline events with filtering by actor, system, and date range./audit/verify-chainVerify the integrity of the hash-chained audit trail. Returns chain status and any break points.Connectors
/connectorsList all connected systems and their current health status./connectors/:id/testTest connector health by performing a connectivity check and measuring latency.System
/healthSystem health check. Returns service status, version, and uptime.Request & Response
The primary surface is POST /intent. Submit a natural-language or structured intent, and Intended returns a deterministic authority decision.
{
"action": "deploy application to production",
"actor": "agent:github-actions",
"system": "github",
"metadata": {
"repo": "acme/frontend",
"branch": "main"
}
}{
"intentId": "int_abc123",
"decision": "ALLOW",
"riskScore": 42,
"confidence": 0.94,
"token": "mrt_tok_...",
"trace": {
"policySet": "prod-deploy-v3",
"triggeredRules": ["allow-ci-deploy"],
"evaluatedAt": "2026-03-22T14:30:00Z"
}
}MCP Gateway
Drop-in authority for MCP servers. Intercepts every tool call, evaluates it against your policies, and only forwards approved calls.
Installation
npm install @intended/mcp-gateway
import { createIntendedGateway } from "@intended/mcp-gateway";
const gateway = createIntendedGateway({
apiKey: "mrt_live_...",
tenantId: "tenant-a",
upstream: "http://localhost:8080/mcp",
});
// Point your AI agent to gateway.url instead of your MCP serverFail-closed
If Intended is unreachable, tool calls are denied. Every MCP tool invocation requires a valid authority decision before it reaches your upstream server.
Python SDK
Native Python client with sync and async support.
Installation
pip install intended
from intended import IntendedClient
client = IntendedClient(api_key="mrt_live_...", tenant_id="tenant-a")
decision = client.submit_intent(
action="deploy to production",
actor="github-actions",
system="github",
)
print(decision.verdict) # ALLOW | DENY | ESCALATELangChain integration
Wrap any LangChain tool with Intended authorization. Every tool invocation is evaluated against your policies before execution.
from intended import IntendedClient
from langchain.tools import tool
client = IntendedClient(api_key="mrt_live_...", tenant_id="tenant-a")
@tool
def deploy(repo: str, branch: str):
"""Deploy a repository to production."""
decision = client.submit_intent(
action="deploy to production",
actor="langchain-agent",
system="github",
metadata={"repo": repo, "branch": branch},
)
if decision.verdict != "ALLOW":
return f"Blocked: {decision.reason}"
return f"Deployed {repo}@{branch}"PydanticAI integration
Add Intended authorization to PydanticAI agent tools with a single check before executing the action.
from intended import IntendedClient
from pydantic_ai import Agent
client = IntendedClient(api_key="mrt_live_...", tenant_id="tenant-a")
agent = Agent("openai:gpt-4o")
@agent.tool
async def write_record(ctx, table: str, data: dict) -> str:
decision = client.submit_intent(
action=f"write to {table}",
actor="pydantic-ai-agent",
system="salesforce",
)
if decision.verdict != "ALLOW":
return f"Blocked: {decision.reason}"
return "Record written successfully"SDKs & CLI
Native SDKs and integration tools for every stack.
TypeScript / Node.js
Available@intended/cli
Python
Availablemeritt
MCP Gateway
Available@intended/mcp-gateway
Go
Coming soonRate Limits
Rate limits are enforced per API key. Exceeding the limit returns 429 Too Many Requests.
| Plan | Rate Limit |
|---|---|
| Free | 100 req / min |
| Pro | 500 req / min |
| Business | 2,000 req / min |
| Enterprise | Custom |
Errors
All errors follow a consistent JSON structure. The error field contains a machine-readable error code, message provides a human-readable explanation, and statusCode mirrors the HTTP status.
{
"error": "INVALID_INTENT",
"message": "Intent could not be classified",
"statusCode": 400
}| Status | Code | Meaning |
|---|---|---|
| 400 | INVALID_INTENT | The submitted intent could not be parsed or classified. |
| 401 | UNAUTHORIZED | Missing or invalid API key. |
| 403 | FORBIDDEN | API key lacks the required scope for this operation. |
| 404 | NOT_FOUND | The requested resource does not exist. |
| 409 | CONFLICT | The request conflicts with current state (e.g., duplicate submission). |
| 429 | RATE_LIMITED | Too many requests. Back off and retry with exponential delay. |
| 500 | INTERNAL_ERROR | An unexpected server error occurred. |
| 503 | SERVICE_UNAVAILABLE | The service is temporarily unavailable. Fail-closed: intents are denied. |
Webhooks
Intended can push decision notifications to your systems in real-time. Configure webhook endpoints in the console to receive events when intents are evaluated, escalated, approved, or denied.
Supported Events
decision.completedAn intent was evaluated and a decision was rendered.decision.escalatedAn intent was escalated and requires human approval.decision.approvedA previously escalated intent was approved.decision.deniedAn intent was denied by policy or human review.chain.breakAn audit chain integrity issue was detected.
Signature Verification
Every webhook delivery includes a x-meritt-signature header containing an HMAC-SHA256 signature of the payload. Verify this signature using your webhook secret before processing the event.
{
"event": "decision.completed",
"intentId": "int_abc123",
"decision": "ALLOW",
"riskScore": 42,
"timestamp": "2026-03-22T14:30:00Z",
"signature": "sha256=a1b2c3d4e5f6..."
}Contract Facts
< 50ms p99
Decision latency
Authority evaluation and token issuance.
RS256
Token algorithm
Per-tenant RSA key pairs. 300s max TTL.
Per-plan
Rate limiting
Enforced per API key. See rate limit table.
Hard-enforced
Fail-closed boundaries
Unavailable dependencies result in denied or escalated outcomes.