Skip to main content

Actions & Control

Looking for the full Control documentation?

This page is the API reference for action submission and the legacy Control endpoints. For the full feature documentation — custom policies, approval workflows, the governance dashboard, and per-agent overrides — see the dedicated Control section:

The Actions router evaluates agent actions against the active policy set — built-in policies (FinancialSafety, DataExfiltration) plus any custom policies authored at the tenant or agent scope. Actions resolve to one of three statuses: allowed, blocked, or pending_review. When a rule fires with on_violation: warn, the action status is allowed and the warning is appended to policy_result.warnings.

Base URL: https://novyx-ram-api.fly.dev

Tier: All tiers can submit actions. Approval workflows available on all tiers.

Connectors: github, slack, linear, pagerduty, http

Approval modes: solo, team, enterprise


Submit Action

POST /v1/actions

Submit an action for policy evaluation via Sentinel. The action is evaluated against all active policies and returns one of three outcomes: allowed, blocked, or pending_review.

Request body

ParameterTypeRequiredDescription
actionstringYesAction name (e.g., github.merge_pr, slack.post_message)
paramsobjectNoAction parameters passed to the policy evaluator

Response fields

FieldTypeDescription
actionstringAction name
statusstringallowed, blocked, or pending_review
policy_resultobject | nullPolicy evaluation details (risk score, triggered policy, violations)
messagestringHuman-readable explanation

Examples

from novyx import Novyx

nx = Novyx(api_key="nram_your_key")

result = nx.action_submit(
action="github.merge_pr",
params={"repo": "myorg/myrepo", "pr_number": 42}
)
print(f"Status: {result['status']}")
print(f"Message: {result['message']}")

Response

{
"action": "github.merge_pr",
"status": "allowed",
"policy_result": {
"risk_score": 0.12,
"evaluation_time_ms": 3.4
},
"message": "Action permitted by policy evaluation"
}

Blocked response example:

{
"action": "http.transfer_funds",
"status": "blocked",
"policy_result": {
"triggered_policy": "FinancialSafetyPolicy",
"reason": "High-value financial operation requires approval",
"risk_score": 0.85,
"severity": "high"
},
"message": "Action blocked: High-value financial operation requires approval"
}

Errors

StatusCodeCause
401UNAUTHORIZEDInvalid or missing API key
403BLOCKEDAction blocked by policy

Explain Action

GET /v1/actions/{action_id}/explain

Get the full causal chain for an action: policy evaluation, approval flow, agent memories at the time, and cryptographic audit trail. One API call to answer "why did my agent do that?"

Path parameters

ParameterTypeDescription
action_idstringThe action identifier

Response fields

FieldTypeDescription
action_idstringAction identifier
actionstringAction name/operation
agent_idstringAgent that submitted the action
connectorstringConnector used (github, slack, etc.)
operationstringSpecific operation
submitted_atstringISO 8601 timestamp
policy_resultobject | nullPolicy evaluation result
approvalobject | nullApproval flow details
memories_at_timearray | nullAgent memories at the moment of the action
audit_trailarrayCryptographic audit entries
summarystringHuman-readable summary of the entire chain

Examples

explanation = nx.action_explain("action_abc123")
print(explanation["summary"])
for entry in explanation["audit_trail"]:
print(f" {entry['timestamp']}: {entry['event']}")

Response

{
"action_id": "action_abc123",
"action": "github.merge_pr",
"agent_id": "deploy-bot",
"connector": "github",
"operation": "merge_pr",
"submitted_at": "2026-03-15T14:30:00Z",
"policy_result": {
"status": "allowed",
"policies_evaluated": ["FinancialSafetyPolicy", "DataExfiltrationPolicy"],
"risk_score": 0.12,
"violations": null
},
"approval": null,
"memories_at_time": [
{
"memory_id": "mem_xyz",
"observation": "PR #42 passed all CI checks",
"importance": 7,
"tags": ["ci", "deploy"],
"created_at": "2026-03-15T14:25:00Z"
}
],
"audit_trail": [
{
"sequence_number": 1,
"timestamp": "2026-03-15T14:30:00Z",
"event": "action_executed",
"entry_hash": "sha256:abc123...",
"metadata": {"connector": "github", "operation": "merge_pr"}
}
],
"summary": "Agent 'deploy-bot' submitted a github.merge_pr action at 2026-03-15T14:30:00Z. Action was approved. Agent had 42 memories at the time."
}

Errors

StatusCodeCause
404actions.not_foundNo audit trail found for the action

List Approvals

GET /v1/approvals

List pending action approvals for the current tenant. Used by the Vault dashboard to show the approval queue.

Query parameters

ParameterTypeRequiredDefaultDescription
limitnumberNo50Max results
statusstringNoFilter by status (e.g., pending_review)

Response fields

FieldTypeDescription
approvalsarrayArray of pending approval objects
totalnumberTotal count

Each approval includes:

FieldTypeDescription
approval_idstringApproval/action identifier
actionstringAction name
connectorstringConnector used
agent_idstringSubmitting agent
statusstringCurrent status
submitted_atstringISO 8601 timestamp
risk_scorenumber | nullRisk score from policy evaluation

Examples

pending = nx.action_list()
for approval in pending["approvals"]:
print(f"{approval['action']} by {approval['agent_id']}{approval['status']}")

Approve / Reject Action

POST /v1/approvals/{approval_id}/decision

Approve or deny a pending action. Records the decision in the cryptographic audit trail and emits an event bus notification.

Path parameters

ParameterTypeDescription
approval_idstringThe approval/action identifier

Query parameters

ParameterTypeRequiredDefaultDescription
decisionstringNoapproveapprove or deny
reasonstringNoReason for the decision
approver_idstringNoID of the person making the decision (defaults to tenant)

Response fields

FieldTypeDescription
approval_idstringApproval identifier
decisionstringapprove or deny
reasonstring | nullDecision reason
statusstringapproved or denied

Examples

result = nx.approve_action(
"approval_abc123",
decision="approve",
reason="Reviewed and safe to proceed"
)
print(f"Decision: {result['status']}")

Response

{
"approval_id": "approval_abc123",
"decision": "approve",
"reason": "Reviewed and safe to proceed",
"status": "approved"
}

Errors

StatusCodeCause
400control.invalid_decisionDecision must be approve or deny
404NOT_FOUNDApproval not found

List Policies

GET /v1/control/policies

List active Control policies and their configuration. Returns which policies are active, supported connectors, and approval modes.

Response fields

FieldTypeDescription
policiesarrayActive policy objects
modestringEvaluation mode (enforcement or shadow)
connectorsstring[]Supported connectors
approval_modesstring[]Available approval modes

Each policy includes:

FieldTypeDescription
namestringPolicy name
enabledbooleanWhether the policy is active
descriptionstringHuman-readable description

Examples

policies = nx.policy_check()
for p in policies["policies"]:
print(f"{p['name']}: {'enabled' if p['enabled'] else 'disabled'}")
print(f"Connectors: {', '.join(policies['connectors'])}")

Response

{
"policies": [
{
"name": "FinancialSafety",
"enabled": true,
"description": "Policy to prevent unauthorized financial operations.",
"source": "builtin",
"agent_id": null
},
{
"name": "DataExfiltration",
"enabled": true,
"description": "Policy to prevent data exfiltration attempts.",
"source": "builtin",
"agent_id": null
},
{
"name": "pii_protection",
"enabled": true,
"description": "Block PII exposure to external systems",
"source": "custom",
"agent_id": null,
"scope": "tenant",
"version": 1,
"created_at": "2026-04-10T14:30:00Z",
"updated_at": "2026-04-10T14:30:00Z"
}
],
"mode": "enforcement",
"connectors": ["github", "slack", "linear", "pagerduty", "http"],
"approval_modes": ["solo", "team", "enterprise"]
}

Built-in policies only return name, enabled, description, source, and agent_id. Custom policies additionally include scope, version, created_at, and updated_at.

Custom policies are first-class as of the Phases 1-5 release. To author your own, see Custom Policies. The full CRUD API (POST/PUT/DELETE /v1/control/policies) and SDK methods (nx.create_policy, nx.update_policy, nx.delete_policy) are documented there.