Skip to main content

Approve / Reject Action

Approve or reject actions that are pending human approval. These endpoints require JWT authentication and appropriate admin permissions.

Approve Action

Endpoint

POST /api/v1/actions/{action_id}/approve

Authentication

JWT Token only - API keys cannot approve/reject actions for security reasons.

Request

Headers

HeaderRequiredDescription
AuthorizationYesBearer token with admin/manager role
Content-TypeNoapplication/json (optional body)

Path Parameters

ParameterTypeRequiredDescription
action_idintegerYesThe action ID to approve

Body (Optional)

{
"reason": "Approved for quarterly data analysis project"
}

Response

Success (200 OK)

{
"action_id": 12345,
"status": "approved",
"approved_by": 42,
"approved_at": "2026-01-20T14:35:00Z",
"correlation_id": "action_20260120_143500_xyz789"
}

Response Fields

FieldTypeDescription
action_idintegerThe approved action ID
statusstringAlways approved
approved_byintegerUser ID of the approver
approved_atstringISO 8601 timestamp of approval
correlation_idstringUnique ID for audit trail

Errors

CodeDescription
400Bad request - action is not pending approval
401Unauthorized - missing or invalid JWT token
403Forbidden - user lacks approval permissions
404Not found - action does not exist

Not Pending Error (400):

{
"detail": "Action is not pending approval (current status: approved)",
"error_code": "INVALID_STATE",
"status": 400
}

Reject Action

Endpoint

POST /api/v1/actions/{action_id}/reject

Authentication

JWT Token only - API keys cannot approve/reject actions for security reasons.

Request

Headers

HeaderRequiredDescription
AuthorizationYesBearer token with admin/manager role
Content-TypeYesapplication/json

Path Parameters

ParameterTypeRequiredDescription
action_idintegerYesThe action ID to reject

Body

{
"reason": "Action violates data retention policy"
}
ParameterTypeRequiredDescription
reasonstringNoReason for rejection (recommended for audit)

Response

Success (200 OK)

{
"action_id": 12345,
"status": "denied",
"rejected_by": 42,
"rejected_at": "2026-01-20T14:35:00Z",
"reason": "Action violates data retention policy",
"correlation_id": "action_20260120_143500_abc123"
}

Response Fields

FieldTypeDescription
action_idintegerThe rejected action ID
statusstringAlways denied
rejected_byintegerUser ID of the reviewer
rejected_atstringISO 8601 timestamp of rejection
reasonstringRejection reason (if provided)
correlation_idstringUnique ID for audit trail

Errors

CodeDescription
400Bad request - action is not pending approval
401Unauthorized - missing or invalid JWT token
403Forbidden - user lacks approval permissions
404Not found - action does not exist

Permission Requirements

To approve or reject actions, users must have one of the following roles:

RoleCan ApproveCan RejectNotes
adminYesYesFull approval authority
security_managerYesYesSecurity team approvals
managerYes*Yes*May be limited by risk level
userNoNoRead-only access

*Managers may have risk level limits configured by their organization.

Approval Level System

Some organizations use approval levels based on risk:

Risk LevelRequired Approval LevelExample Roles
Low (0-39)Level 1+Manager, Admin
Medium (40-69)Level 2+Senior Manager, Admin
High (70-84)Level 3+Security Manager, CISO
Critical (85-100)Level 4+CISO, Board approval

Examples

cURL - Approve

curl -X POST https://pilot.owkai.app/api/v1/actions/12345/approve \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiI..." \
-H "Content-Type: application/json" \
-d '{
"reason": "Approved for Q1 data migration project"
}'

cURL - Reject

curl -X POST https://pilot.owkai.app/api/v1/actions/12345/reject \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiI..." \
-H "Content-Type: application/json" \
-d '{
"reason": "Action targets production database during peak hours"
}'

Python

from ascend import AscendClient

# Note: Must use JWT authentication, not API key
client = AscendClient(access_token="eyJhbGciOiJSUzI1NiI...")

# Approve an action
result = client.actions.approve(
action_id=12345,
reason="Approved for quarterly data analysis"
)
print(f"Action {result.action_id} approved at {result.approved_at}")

# Reject an action
result = client.actions.reject(
action_id=12346,
reason="Violates data retention policy"
)
print(f"Action {result.action_id} rejected")

Node.js

import { AscendClient } from '@anthropic/ascend-sdk';

// Note: Must use JWT authentication, not API key
const client = new AscendClient({ accessToken: 'eyJhbGciOiJSUzI1NiI...' });

// Approve an action
const approveResult = await client.actions.approve(12345, {
reason: 'Approved for quarterly data analysis'
});
console.log(`Action ${approveResult.actionId} approved`);

// Reject an action
const rejectResult = await client.actions.reject(12346, {
reason: 'Violates data retention policy'
});
console.log(`Action ${rejectResult.actionId} rejected`);

Python (requests)

import requests

BASE_URL = "https://pilot.owkai.app"
JWT_TOKEN = "eyJhbGciOiJSUzI1NiI..."

headers = {
"Authorization": f"Bearer {JWT_TOKEN}",
"Content-Type": "application/json"
}

# Approve action
response = requests.post(
f"{BASE_URL}/api/v1/actions/12345/approve",
headers=headers,
json={"reason": "Approved for data migration"}
)
print(response.json())

# Reject action
response = requests.post(
f"{BASE_URL}/api/v1/actions/12346/reject",
headers=headers,
json={"reason": "Target system is in maintenance mode"}
)
print(response.json())

Audit Trail

All approval and rejection actions are logged to the immutable audit trail:

{
"audit_id": 98765,
"action_type": "action_approved",
"user_id": 42,
"organization_id": 1,
"timestamp": "2026-01-20T14:35:00Z",
"details": "Action 12345 approved by user 42",
"ip_address": "192.168.1.100",
"user_agent": "Mozilla/5.0...",
"correlation_id": "action_20260120_143500_xyz789"
}

Audit logs can be queried via the /api/admin/audit-logs endpoint or exported for compliance reporting.


Bulk Operations

For processing multiple pending actions:

Bulk Approve

POST /api/v1/actions/bulk-approve
{
"action_ids": [12345, 12346, 12347],
"reason": "Bulk approval for scheduled maintenance window"
}

Bulk Reject

POST /api/v1/actions/bulk-reject
{
"action_ids": [12348, 12349],
"reason": "Actions submitted with incorrect parameters"
}