API reference
Endpoints, auth, error codes for direct HTTP integration.
Base URL: https://api.intervensecurity.com
Auth
All public endpoints accept a Bearer API key:
Authorization: Bearer iv_live_<your_key>Mint API keys at app.intervensecurity.com/api-keys. Keys are shown once at creation β store immediately in your secrets manager.
POST /v1/scan
Evaluate a single outbound API call.
Request
{
"method": "POST",
"url": "https://hooks.slack.com/services/T../B../secret",
"headers": { "Content-Type": "application/json" },
"body": { "text": "hello" },
"agent_id": "00000000-0000-0000-0000-000000000123",
"runtime_type": "langchain"
}| Field | Type | Required | Notes |
|---|---|---|---|
method | string | yes | HTTP verb the agent intends |
url | string | yes | Absolute URL |
body | any | no | Request body (object, array, string) |
headers | object | no | Outbound request headers |
agent_id | UUID | no | Override the API key's default agent |
agent_name | string | no | Human-readable agent name for telemetry |
runtime_type | string | no | langchain, crewai, openai_assistants, openclaw, custom |
context | string | no | Conversation context for semantic risk analysis |
Response
{
"decision": "ALLOW",
"risk_score": 0.12,
"risk_band": "LOW",
"reason_codes": [],
"trace_id": "f1e2d3c4-...",
"tool_name": "slack",
"operation": "post_message",
"classifications": [],
"signals": []
}| Field | Present when | Description |
|---|---|---|
decision | always | ALLOW, DENY, SANITIZE, or REQUIRE_APPROVAL |
risk_score | always | 0.0 β 1.0 |
risk_band | always | LOW, MEDIUM, HIGH, CRITICAL |
reason_codes | always | Why the decision was made (e.g. SECRETS, PII, EXTERNAL_PRINCIPAL) |
trace_id | always | Unique trace ID for telemetry correlation |
tool_name | always | Detected tool (e.g. github, slack, custom_proxy) |
operation | always | Detected operation (e.g. create_pr, post_message) |
classifications | always | Data classes found (SECRETS, PII) |
sanitized_body | SANITIZE | Redacted body β forward this instead of the original |
approval_id | REQUIRE_APPROVAL | UUID β poll or use wait_for_approval() |
policy_id | when matched | Policy that triggered the decision |
policy_name | when matched | Human-readable policy name |
signals | always | Risk signals that fired (baseline anomaly, threat intel, etc.) |
POST /v1/scan/response
Classify the response body of an upstream call. Used for forensics and readβwrite exfil detection.
{
"trace_id": "<from /v1/scan>",
"response_body": <string or object>,
"response_status": 200
}Response: { data_classes, fields_redacted_count, content_fingerprint }.
GET /v1/approvals/[approval_id]/status
Poll for approval status while the analyst decides.
{ "status": "approved" } // or "pending" | "denied" | "expired"POST /v1/policies/apply
Idempotent upsert of a policy. Creates a new policy_version row server-side
so the audit trail stays intact.
Request:
{
"name": "block-secrets-egress",
"description": "DENY any outbound carrying SECRETS",
"env_name": "production",
"rules": [
{
"rule_id": "deny-secrets",
"match": {},
"condition": { "has_data_class": ["SECRETS"] },
"action": "DENY",
"priority": 100
}
]
}Response: { policy_id, name, env_name, version, rules }.
See Policies for full rule schema.
GET /v1/policies/by-name/[name]?env=production
Fetch the latest version of a named policy.
POST /v1/keys/ephemeral
Mint a short-lived, scope-restricted credential (prefix iv_eph_*).
Use when you need to give an agent (e.g. Devin, 11x, Artisan) a credential
you can revoke quickly.
{
"ttl_seconds": 600,
"max_uses": 1,
"scope": { "tools": ["slack"], "verbs": ["WRITE"] },
"description": "One-time Slack post for incident #1234"
}Response includes the full key β shown once. See Ephemeral Keys.
POST /v1/a2a/scan
Scan an agent-to-agent message (when one of your agents delegates to another).
{
"from_agent_id": "uuid-of-caller",
"to_agent_id": "uuid-of-recipient",
"method": "delegate",
"intent": "Have agent B post the incident summary to #ops",
"payload": { "incident_id": "INC-123", "channel": "#ops" }
}Cross-tenant and cross-environment A2A messages are rejected.
ALL /inbound/[prefix]/*
Destination-side proxy. Configure inbound routes in Console β Inbound Routes, then point SaaS agents (Salesforce Agentforce, HubSpot Breeze, Zendesk AI, Intercom Fin) at this URL instead of the real API.
Interven scans every request through the policy + risk pipeline, then forwards to the configured upstream with stored credentials. Agent never sees the credential.
Response headers always include:
X-Interven-DecisionβALLOW/DENY/SANITIZE/REQUIRE_APPROVALX-Interven-Trace-Idβ UUID for telemetry correlationX-Interven-Reasonsβ comma-separated reason codes (when present)
See SaaS Agent Protection for platform-specific setup guides.
Error codes
| Status | Meaning |
|---|---|
400 | Bad request β body validation failed |
401 | Bearer token missing/invalid/revoked |
413 | Request body exceeded MAX_BODY_BYTES (default 256KB) |
429 | Per-tenant rate limit exceeded |
5xx | Gateway issue β SDKs retry once on 5xx automatically |
Limits
- Body size: 256 KB per request (
MAX_BODY_BYTES) - Replay window: 60 seconds (
REPLAY_WINDOW_SEC) - Default rate: 60 scans / minute / tenant β contact us to raise