Skip to content

Quickstart

Put AgentPlane in front of one tool in about ten minutes. You will register an agent, send its first action, and see it allowed, held or blocked.

Quickstart

  1. 1Create a workspace. It starts with eight recommended policies.
  2. 2In the console, open Agents and register one. List only the tools it needs, such as kb.* or email.send. Copy the key; it is shown once.
  3. 3Before your agent calls a protected tool, send the action to evaluate. Here is the smallest possible request:
Shell
curl -X POST https://your-host/api/v1/action-requests/evaluate \
  -H "Authorization: Bearer $AGENTPLANE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "initiating_principal": "maya.chen@example.com",
    "objective": "Resolve support case 48213",
    "action":   { "type": "kb.article.read", "operation": "read" },
    "resource": { "type": "kb_article", "id": "kb-1182",
                  "sensitivity": "public", "environment": "sandbox" }
  }'
Response
{
  "request":  { "id": "req_4f1c09a2be71", "payload_hash": "9b0e...c41d", "status": "decided" },
  "decision": {
    "id": "dec_7d20e4c1d3f8",
    "decision": "ALLOW",
    "risk_score": 5,
    "risk_band": "LOW",
    "reason_codes": ["PUBLIC_READ"],
    "matched_policies": [{ "id": "pol_public_reads", "version": 5 }],
    "obligations": [],
    "expires_at": "2026-10-21T12:05:00Z"
  },
  "approval": null
}

Every decision carries its reason codes, the policy versions that matched and each risk factor's contribution. Open the request in the console to see the same explanation.

The action envelope

One shape for every framework. Missing context is never trusted by default.

initiating_principalWho started the task. Missing means ESCALATE. This person cannot approve it.
objectiveWhy, in a sentence. Missing means ESCALATE.
action.typeDotted tool name. Must be in the agent's permitted tools.
action.operationread, write, send, export, delete, transfer or admin.
resourceType, id, sensitivity, environment, destination, record_count, amount.
payloadExactly what the tool will receive. It is hashed; approvals bind to the hash.
idempotency_keySafe retries. The same key returns the same request.
TypeScript
// Wrap every protected tool call. Nothing reaches the tool without a decision.
async function guarded(action, run) {
  const res = await fetch("https://your-host/api/v1/action-requests/evaluate", {
    method: "POST",
    headers: {
      authorization: `Bearer ${process.env.AGENTPLANE_KEY}`,
      "content-type": "application/json",
    },
    body: JSON.stringify(action),
  });
  const { request, decision } = await res.json();

  switch (decision.decision) {
    case "ALLOW":
      return run();                       // then report the outcome via execute
    case "REQUIRE_APPROVAL":
      return { held: request.id };        // resume when the approval lands
    case "ESCALATE":
      return { escalated: decision.reason_codes };
    case "DENY":
      throw new Error(decision.reason_codes.join(", "));
  }
}
Python
import os, requests

def evaluate(action: dict) -> dict:
    r = requests.post(
        "https://your-host/api/v1/action-requests/evaluate",
        headers={"Authorization": f"Bearer {os.environ['AGENTPLANE_KEY']}"},
        json=action,
        timeout=5,
    )
    r.raise_for_status()
    return r.json()["decision"]

decision = evaluate({
    "initiating_principal": "maya.chen@example.com",
    "objective": "Resolve support case 48213",
    "action": {"type": "email.send", "operation": "send"},
    "resource": {"type": "email", "id": "customer:jordan", "sensitivity": "confidential",
                 "environment": "production", "destination": "external"},
    "payload": {"to": "jordan@example.net", "template": "refund_confirmed"},
    "idempotency_key": "case-48213-refund-email",
})

Handling decisions

AllowedRun the tool, then call execute so a receipt and verification are recorded.Valid for 5 minutes. After that, evaluate again.
Needs approvalPause. A person with the Approver role sees the exact payload in the console.Holds expire after 30 minutes. Poll the request or resume when notified.
EscalatedStop and route to a reviewer. Usually missing context.Send the missing principal, objective or target and evaluate again.
DeniedDo not run the tool. Show the reason codes to whoever needs them.Retrying the same action will not change the answer.

Executing safely

Call POST /api/v1/action-requests/{id}/execute to run through the enforcement point. It refuses anything denied, escalated, unapproved, expired, already executed, changed since approval, from a disabled agent, or sent while the kill switch is on. After running, a verifier checks the postcondition and records evidence.

Only actions that pass through the enforcement point are protected. Route every protected tool through it, and keep tool credentials out of the agent's reach.

Shadow mode

Start any agent in shadow mode to see what enforcement would do before it does anything. Your agent keeps working; every decision is recorded with what it would have been, in the would_be field.

  • Would-be holds, escalations and no-policy denials are allowed to proceed and are verified afterwards. No approval is created.
  • The hard floor is enforced in every mode: hard-deny rules, critical risk, disabled or revoked agents, tools outside scope, and the kill switch.
  • The shadow report shows how many actions would settle by policy, how many reviews a day enforcement would create, and which routine actions need a policy first.
  • Shadow decisions are left out of the overview numbers, so rehearsals never inflate your real automation rate.

How policies resolve

  1. Kill switch on, agent disabled, or tool not permitted: deny.
  2. Any matching hard deny wins over everything else.
  3. Missing principal, objective or a clear target: escalate.
  4. Lowest priority number wins. A tie goes to the stricter effect.
  5. Risk can only tighten: high risk turns allow into approval, critical turns anything into deny.
  6. No matching policy: deny. There is no implicit allow.

Try any change in the simulator before it goes live.

Errors

Every error has the same shape: a machine-readable code, a message, a request id and whether it is safe to retry.

400INVALID_REQUESTThe envelope failed validation. The message names the field.
401CREDENTIAL_INVALIDUnknown or rotated agent key.
403AGENT_MISMATCHThe key belongs to a different agent_id.
409APPROVAL_REQUIREDExecute was called before an approver decided.
409PAYLOAD_MISMATCHThe payload changed after it was authorized.
409REPLAY_REJECTEDThis action already ran. Send a new request.
409DECISION_EXPIREDThe allow decision is older than 5 minutes.
409KILL_SWITCH_ACTIVEAn Owner or Admin stopped all agent traffic.
413PAYLOAD_TOO_LARGEBodies are capped at 64 KB.
429RATE_LIMITEDOver 120 evaluate calls a minute for this agent. Safe to retry.

API reference

POST/api/v1/action-requests/evaluateValidate and decide. Never executes.
POST/api/v1/action-requests/{id}/executeRun through the sandbox enforcement point.
GET/api/v1/action-requestsSearch requests by agent, decision or text.
GET/api/v1/decisions/{id}A decision with its full explanation.
GET/api/v1/approvalsApprovals by status.
POST/api/v1/approvals/{id}/decisionApprove or deny, bound to payload_hash.
GET POST/api/v1/agentsList or register agents.
POST/api/v1/agents/{id}/rotate-credentialRotate, or revoke with revoke_only.
POST/api/v1/agents/{id}/modeSwitch between enforce and shadow.
GET/api/v1/shadow-reportWould-be outcomes and readiness per shadow agent.
GET POST/api/v1/policiesList or create policies.
POST/api/v1/simulateDry run against live policies.
GET/api/v1/audit-eventsSearch the audit chain and verify it.
POST/api/v1/kill-switchEngage or release, with a reason.
GET/api/health/readyReadiness of store, policies and audit chain.

Limits and guarantees

  • Decisions are deterministic: the same envelope and policy set always give the same answer.
  • Agent keys are stored as hashes and shown once. Rotation stops the old key immediately.
  • Audit events cannot be edited or deleted through any API, and the hash chain shows if they were changed.
  • Secrets, tokens and card-like fields are removed before anything is logged. Emails are masked.
  • The executor in this release is sandbox-only. Production adapters require a security review first.