oakallowAPI Docs
Get API Key
Table of Contents

oakallow API Reference

Complete API reference for oakallow — security infrastructure for AI agents. Register tools, define permissions, mint execution tokens, manage approvals, and log every action.

Introduction

oakallow provides a hosted API for governing AI agent tool execution. Instead of building your own permission system, token minting, approval workflows, and audit trails, integrate with oakallow's API and get production-grade security infrastructure in minutes.

The API is organized around REST. All requests and responses use JSON. All endpoints (except health check) require authentication via API key.

Authentication

Authenticate by including your API key in the X-API-Key header on every request. API keys are scoped to a single organization. There are three key types:

Key TypePurposeAccessBilling
ManagementCRUD operations, CI/CD, seedingTools, orgs, tenants, resources, methods, rulesFree
StandardRuntime agent operationsPermission checks, parameter validation, token minting, approval workflow actions, execution logging$0.005/billable call

Management keys are for setup and configuration — seeding tools, creating tenants, managing permission rules. They cannot access runtime endpoints (permission checks, approvals). Use these in CI/CD pipelines and configuration scripts.

Standard keys are for runtime — your agent uses these to check permissions, mint tokens, drive approval workflows, and log executions. They can read (GET) management resources but cannot create or modify them. Every runtime call is $0.005.

Route only the actions you want governed. oakallow is for the moments that matter: gated, approved, audited. If a tool fires thousands of times an hour and never needs a human in the loop, register it with default_permission: allowed and skip the permission check entirely. Per-call pricing is charged for governed-action volume, not application telemetry — keep general logging in your own observability stack.

Example Request
curl https://api.oakallow.io/v1/tools \
  -H "X-API-Key: oak_live_your_key_here"

Keys are created in the oakallow dashboard. Each key is bound to one organization — you cannot access another organization's data with a different key. The organization scope is enforced at the edge and cannot be overridden.

Key format: oak_live_ followed by 32 hex characters. The first 17 characters are used as a lookup prefix (collision-safe at 32 bits of entropy). Never share your full API key.

Base URL

https://api.oakallow.io

All API endpoints are prefixed with /v1. Requests are authenticated and rate-limited at the Cloudflare edge before reaching the origin server.

Errors

oakallow uses standard HTTP status codes.

StatusMeaning
200Success
201Created
204Deleted (no content)
400Bad request — missing or invalid parameters
401Unauthorized — missing or invalid API key
404Not found — resource does not exist or is not in your scope
409Conflict — resource already exists
429Rate limited — too many requests
500Internal server error

Error responses include a JSON body:

Error Response
{
  "error": "tool_name is required"
}

Data Model

oakallow's data model is a hierarchy. Every entity is scoped to a developer (you).

Hierarchy
Developer (you — authenticated via API key)
  └── Organization (your app — API key is scoped to one org)
       ├── Tenants (your customers)
       ├── Resources (servers, databases, endpoints — targets)
       ├── Methods (ssh, api, cli — how tools execute)
       ├── Tool Categories (health, security — with default permissions)
       ├── Tools (check_memory, restart_service, etc.)
       └── Permission Rules
            └── tenant + resource + tool + method → permission

Organizations represent your application. Each API key is bound to one org.

Tenants represent your customers. They are optional — if your app is single-tenant, you can skip tenants entirely and define permissions at the org level.

Resources are the targets that tools operate on: servers, databases, API endpoints, Kubernetes namespaces, etc. You define the external_id (your own identifier).

Tools are the actions your AI agent can perform. Tools are org-scoped — each organization has its own tool catalog. The same tool name in different orgs are separate tools. Each tool has a name, category, risk level, and optional parameters schema.

Permission Rules map combinations of tenant + resource + tool + method to a permission level: allowed, requires_approval, or disabled.

Permission Resolution

When you check a permission, oakallow walks a 12-level resolution chain from most specific to least specific. The first match wins.

Resolution Chain (most specific first)
If tenant_id is provided, tenant-scoped rules are checked first:
  Level 1:  tenant + resource + tool + method
  Level 2:  tenant + resource + tool
  Level 3:  tenant + resource + method
  Level 4:  tenant + resource
  Level 5:  tenant + tool + method
  Level 6:  tenant + tool              ← most common tenant rule
  Level 7:  tenant + method
  Level 8:  tenant + tag match

Then org-wide rules (tenant_id = NULL):
  Same 8 levels as above

Defaults:
  Level 9:  tool.default_permission
  Level 10: tool_category.default_permission
  Level 11: tool_approved → allowed (if tool status is approved)
  Level 12: fail_safe → requires_approval

If a tool has status: approved and no rules or defaults match, it resolves as allowed (Level 11). Only unapproved tools fall through to the fail-saferequires_approval at Level 12.

Tier gating:Tools can require a minimum tier. If your API key's tier is lower than the tool's required_tier, the permission check returns disabled with resolved_from: "insufficient_tier".

Onboarding Flow

To fully integrate with oakallow, make API calls in this order. Steps 1-7 use a management key (free). Steps 8-10 use a standard key (billed).

StepKeyEndpointPurpose
1mgmtGET /v1/orgsVerify your org exists
2mgmtPOST /v1/orgs/:org/tenantsCreate tenants (your customers)
3mgmtPOST /v1/orgs/:org/resourcesCreate resources (servers, databases)
4mgmtPOST /v1/methodsRegister methods (ssh, api, cli)
5mgmtPOST /v1/categoriesCreate tool categories with defaults
6mgmtPOST /v1/tools/seedRegister your tools (org-scoped)
7mgmtPOST /v1/permissions/rulesDefine permission rules
8stdPOST /v1/permissions/checkCheck permissions at runtime
9stdPOST /v1/tokens/mintMint execution tokens
10stdPOST /v1/executions/logLog execution results

Organizations

Organizations represent your application. Your API key is already scoped to one org. Use this endpoint to verify your org exists and retrieve its external_id.

GET/v1/orgsList your organizations
Response
{
  "orgs": [
    {
      "id": "uuid",
      "external_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
      "name": "My App",
      "created_at": "2026-03-21T03:49:07Z"
    }
  ],
  "count": 1
}
POST/v1/orgsCreate an organization
namestringrequired
Name for the organization.
Request
{
  "name": "My Production App"
}
Response (201)
{
  "id": "uuid",
  "external_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
  "name": "My Production App",
  "created_at": "2026-03-21T03:49:07Z"
}

Approval Webhook Configuration

Configure via the dashboard Settings page or programmatically via the API. The webhook secret is auto-generated on first setup. To regenerate, pass regenerate_secret: true.

PUT/v1/orgs/:external_id/webhookSet approval webhook URL
approval_webhook_urlstring
HTTPS URL to receive approval events. Set to empty string to disable.
regenerate_secretboolean
Set to true to regenerate the signing secret.
Response
{
  "approval_webhook_url": "https://your-app.com/webhooks/oakallow",
  "webhook_secret": "a1b2c3...hex64",
  "message": "Save this secret. It will not be returned again."
}
GET/v1/orgs/:external_id/webhookGet webhook config

Tenants

Tenants represent your customers within an organization. They are optional — if your app is single-tenant, skip this step and define permissions at the org level. Tenant external IDs are auto-generated with a ten_ prefix.

POST/v1/orgs/:org_external_id/tenantsCreate a tenant
namestring
Display name for the tenant.
metadataobject
Arbitrary metadata (stored as JSON).
Request
POST /v1/orgs/org_ftcECvT5dtdjIEgFCe6hGniT/tenants

{
  "name": "Acme Corp",
  "metadata": { "plan": "enterprise", "region": "us-east" }
}
Response (201)
{
  "id": "uuid",
  "external_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe",
  "name": "Acme Corp",
  "org_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
  "created_at": "2026-03-21T03:50:06Z"
}
GET/v1/orgs/:org_external_id/tenantsList tenants
Response
{
  "tenants": [
    {
      "id": "uuid",
      "external_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe",
      "name": "Acme Corp",
      "metadata": "{}",
      "created_at": "2026-03-21T03:50:06Z"
    }
  ],
  "count": 1
}
GET/v1/orgs/:org_external_id/tenants/:tenant_external_idGet a tenant
PUT/v1/orgs/:org_external_id/tenants/:tenant_external_idUpdate a tenant
DELETE/v1/orgs/:org_external_id/tenants/:tenant_external_idDelete a tenant

Deleting a tenant cascades to all its permission rules and resources.

Resources

Resources are targets that tools operate on — servers, databases, API endpoints, Kubernetes namespaces, S3 buckets, etc. You provide the external_id (your own identifier).

POST/v1/orgs/:org_external_id/resourcesCreate a resource
external_idstringrequired
Your identifier for this resource (max 200 chars).
namestring
Display name.
metadataobject
Arbitrary metadata (IP, provider, OS, etc.).
Request
POST /v1/orgs/org_ftcECvT5dtdjIEgFCe6hGniT/resources

{
  "external_id": "server-prod-01",
  "name": "Production Server",
  "metadata": {
    "ip": "64.225.125.239",
    "provider": "digitalocean",
    "os": "linux"
  }
}
Response (201)
{
  "id": "uuid",
  "external_id": "server-prod-01",
  "name": "Production Server",
  "metadata": { "ip": "64.225.125.239", "provider": "digitalocean", "os": "linux" },
  "created_at": "2026-03-23T..."
}
GET/v1/orgs/:org_external_id/resourcesList resources
DELETE/v1/orgs/:org_external_id/resources/:resource_external_idDelete a resource

Deleting a resource cascades to all permission rules scoped to it.

POST/v1/orgs/:org_external_id/resources/bulkBulk create resources (max 500)
Request
{
  "resources": [
    { "external_id": "server-prod-01", "name": "Prod Server", "metadata": {} },
    { "external_id": "server-staging-01", "name": "Staging Server", "metadata": {} },
    { "external_id": "db-prod", "name": "Production Database", "metadata": {} }
  ]
}

Methods

Methods define how tools are executed — your vocabulary for execution patterns. Common methods: ssh, go_agent, api, cli,manual, scheduled.

POST/v1/methodsCreate a method
namestringrequired
Method name (unique per developer).
descriptionstring
Description of when this method is used.
Request
{
  "name": "ssh",
  "description": "Execute via SSH connection to the target server"
}
GET/v1/methodsList all methods
DELETE/v1/methods/:nameDelete a method (cascades to permission rules)

Tool Categories

Categories group tools and provide a default permission for the group. If a tool has no specific permission rule and no tool-level default, the category default is used.

Note: Category management endpoint is coming soon. Categories are currently created via the dashboard or when tools reference them during seeding.

Tools

Tools are the actions your AI agent can perform. Each tool has a name, description, category, risk level, parameter schema, and tier requirement.

GET/v1/toolsList all registered tools
Response
{
  "tools": [
    {
      "id": "uuid",
      "name": "check_memory",
      "description": "Check system memory usage and availability",
      "category": "health",
      "risk_level": "read_only",
      "required_tier": "standard",
      "status": "approved",
      "default_permission": null,
      "requires_second_approval": false,
      "approval_timeout_seconds": null,
      "parameters": {
        "threshold_percent": {
          "type": "integer",
          "description": "Alert threshold percentage",
          "default": 90
        }
      }
    }
  ],
  "count": 1
}
POST/v1/toolsCreate a tool
namestringrequired
Tool name (unique per developer).
descriptionstring
What the tool does.
categorystring
Category name (e.g., "health", "security", "database").
risk_levelstring
One of: read_only, low, medium, high, critical.
required_tierstring
Minimum tier: standard.
statusstring
One of: draft, testing, approved, disabled.
default_permissionstring
Default permission if no rule matches: allowed, requires_approval, or disabled.
parametersobject
JSON schema for tool parameters.
tagsobject
Arbitrary tags for tag-based permission rules.
requires_second_approvalboolean
When true, approval requests for this tool escalate from Approval 1 to Approval 2 after the first approval lands. Second-level escalation only triggers if the account has an Approval 2 group configured with at least one member — otherwise the request stays single-level. Configure groups under Team → Approver Groups. Defaults to false.
approval_timeout_secondsinteger
How long an approval request stays pending before being auto-expired. Minimum 60 seconds, maximum 604800 (7 days). When omitted or null, the tool inherits the org default (set under Settings); if the org default is also unset, the global fallback is 3600 (1 hour).
PUT/v1/tools/:idUpdate a tool
DELETE/v1/tools/:idDelete a tool

Tool Seeding

The seed endpoint is designed for bulk tool registration. It performs an idempotent upsert — creates tools that don't exist and updates those that do. You can optionally include permission rules inline with each tool.

POST/v1/tools/seedBulk upsert tools (max 500)
Request
{
  "tools": [
    {
      "name": "check_memory",
      "description": "Check system memory usage and availability",
      "category": "health",
      "risk_level": "read_only",
      "required_tier": "standard",
      "status": "approved",
      "requires_second_approval": false,
      "parameters": {
        "threshold_percent": {
          "type": "integer",
          "description": "Alert threshold percentage",
          "default": 90
        }
      },
      "tags": {
        "tool_types": ["ssh"],
        "os": "linux",
        "readOnly": true
      },
      "permissions": [
        {
          "tenant_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe",
          "permission": "allowed"
        },
        {
          "tenant_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe",
          "resource_id": "server-prod-01",
          "permission": "allowed"
        }
      ]
    }
  ]
}

Important: The tenant_id and resource_idreferenced in permissions must already exist. The seed endpoint looks them up by external_id — if they don't exist, the permission rule is skipped and reported in the errors array.

Response
{
  "tools_created": 1,
  "tools_updated": 0,
  "rules_created": 2,
  "rules_updated": 0,
  "errors": []
}

Permission Check

Check whether a tool execution is allowed for a given context. This is the hot path — single-digit millisecond resolution at the Cloudflare edge.

POST/v1/permissions/checkCheck permission for a tool
tool_namestringrequired
Name of the tool to check.
tenant_idstring
Tenant external_id (if multi-tenant).
resource_idstring
Resource external_id (if resource-scoped).
methodstring
Method name (if method-scoped).
Request
{
  "tool_name": "check_memory",
  "tenant_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe",
  "resource_id": "server-prod-01",
  "method": "ssh"
}
Response
{
  "permission": "allowed",
  "resolved_from": "tenant_resource_tool_method",
  "resolved_level": 1,
  "tool_id": "uuid",
  "tool_status": "approved",
  "category": "health",
  "resource_id": "server-prod-01",
  "method": "ssh",
  "_timing": { "resolve_ms": 4, "auth": "cache" }
}

The resolved_from field tells you which level of the permission chain matched. This is invaluable for debugging why a tool is allowed or blocked.

resolved_fromMeaning
tenant_resource_tool_methodLevel 1: Most specific tenant rule
tenant_resource_toolLevel 2: Tenant + resource + tool
tenant_toolLevel 6: Tenant + tool (most common)
tenant_tagLevel 8: Tenant tag match
org_resource_tool_methodLevel 1: Most specific org-wide rule
org_toolLevel 6: Org-wide tool rule
tool_defaultLevel 9: Tool default_permission
category_defaultLevel 10: Category default
tool_approvedLevel 11: Tool is approved, no rules needed
fail_safeLevel 12: No rules, tool not approved → requires_approval
insufficient_tierAPI key tier too low for this tool
tool_not_foundTool does not exist

Note: The org_id is not in the request body — it comes from your API key. You cannot check permissions for a different organization.

Permission Rules

Permission rules define the access control for your tools. Each rule maps a combination of tenant + resource + tool + method to a permission level.

POST/v1/permissions/rulesCreate or upsert a rule
org_idstringrequired
Organization external_id.
tenant_idstring
Tenant external_id (omit for org-wide rules).
resource_idstring
Resource external_id (omit for all-resource rules).
tool_namestring
Tool name (omit for wildcard tool rules).
methodstring
Method name (omit for all-method rules).
tag_keystring
Tag key for tag-based rules (Level 8).
tag_valuestring
Tag value (required if tag_key is set).
permissionstringrequired
One of: allowed, requires_approval, disabled.
Request — Tenant + Tool Rule (Level 6)
{
  "org_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
  "tenant_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe",
  "tool_name": "check_memory",
  "permission": "allowed"
}
Request — Tenant + Resource + Tool + Method Rule (Level 1)
{
  "org_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
  "tenant_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe",
  "resource_id": "server-prod-01",
  "tool_name": "restart_service",
  "method": "ssh",
  "permission": "requires_approval"
}
Request — Org-wide Wildcard (all tools require approval by default)
{
  "org_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
  "permission": "requires_approval"
}
Response (201)
{
  "id": "uuid",
  "org_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
  "tenant_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe",
  "resource_id": null,
  "tool_name": "check_memory",
  "method": null,
  "permission": "allowed",
  "created": true
}

Rules are upserted — if a rule with the same combination of fields already exists, the permission is updated instead of creating a duplicate.

GET/v1/permissions/rulesList rules (with optional filters)

Query parameters: org_id, tenant_id, tool_name, method.

DELETE/v1/permissions/rules/:idDelete a rule

Bulk Rules

POST/v1/permissions/rules/bulkCreate/upsert multiple rules (max 500)
Request
{
  "rules": [
    {
      "org_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
      "tenant_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe",
      "tool_name": "check_memory",
      "permission": "allowed"
    },
    {
      "org_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
      "tenant_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe",
      "tool_name": "restart_service",
      "resource_id": "server-prod-01",
      "method": "ssh",
      "permission": "requires_approval"
    },
    {
      "org_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
      "tool_name": "check_memory",
      "permission": "allowed"
    }
  ]
}
Response
{
  "created": 2,
  "updated": 1,
  "errors": []
}

Sync Rules

Full state sync — replaces all existing rules for an org/tenant scope with a new set. This is what a drag-and-drop permission UI calls on Save.

POST/v1/permissions/rules/syncReplace all rules for a scope (max 1000)
Request
{
  "org_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
  "tenant_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe",
  "rules": [
    { "tool_name": "check_memory", "permission": "allowed" },
    { "tool_name": "check_cpu", "permission": "allowed" },
    { "tool_name": "restart_service", "permission": "requires_approval" },
    { "tool_name": "drop_caches", "permission": "disabled" }
  ]
}

Warning: This deletes all existing rules for the given org + tenant scope before inserting the new rules. Omit tenant_id to sync org-level rules.

Token Minting

Execution tokens are single-use, time-limited HMAC tokens that authorize a specific tool execution. Mint a token after the permission check passes, then include it when executing the tool.

POST/v1/tokens/mintMint an execution token
org_idstringrequired
Organization external_id.
tool_idstringrequired
Tool UUID (from tool lookup or permission check).
paramsobject
Parameters for the execution (hashed into the token).
ttl_secondsinteger
Token lifetime in seconds (default: 300).
tenant_idstring
Tenant external_id.
Request
{
  "org_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
  "tool_id": "uuid-from-permission-check",
  "params": { "threshold_percent": 90 },
  "ttl_seconds": 120,
  "tenant_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe"
}
Response
{
  "token_id": "uuid",
  "tool_id": "uuid",
  "params_hash": "sha256-hex",
  "nonce": "unique-nonce",
  "expires_at": "2026-03-23T12:02:00Z",
  "hmac": "hex-signature"
}

Approvals

When a permission check returns requires_approval, your agent should request approval before executing the tool. Approvals have a configurable timeout (default: 1 hour).

Important: No PII in approval requests

oakallow is not designed to store personally identifiable information. Do not include PII (emails, SSNs, addresses, phone numbers, financial data) in the reason or any other field. Any detected PII will be automatically redacted. Use reference_id to correlate approvals back to records in your own system.

Approval Webhooks

Configure an approval webhook URL per organization in the Settings page. When an approval request is created, oakallow sends a POST to your webhook URL with the event type approval.created and the approval details (tool name, reason, reference ID, approval ID, expiration). When a human decides, another webhook fires with approval.decidedand the decision. Webhook payloads contain only the redacted data stored by oakallow.

Payloads are signed with HMAC-SHA256 using your webhook secret. Verify the X-Oakallow-Signature header (sha256=<hex>) to confirm authenticity. You can also poll GET /v1/approvals/:id as an alternative or fallback.

Webhook Payload — approval.created
{
  "event": "approval.created",
  "timestamp": "2026-03-24T12:00:00Z",
  "org_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
  "data": {
    "approval_id": "uuid",
    "tool_name": "restart_service",
    "reason": "Service restart requested",
    "reference_id": "incident-4821",
    "status": "pending",
    "expires_at": "2026-03-24T13:00:00Z",
    "tenant_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe"
  }
}
Webhook Payload — approval.decided
{
  "event": "approval.decided",
  "timestamp": "2026-03-24T12:05:00Z",
  "org_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
  "data": {
    "approval_id": "uuid",
    "tool_name": "restart_service",
    "reference_id": "incident-4821",
    "decision": "approved",
    "decided_by": "admin@example.com",
    "note": "Confirmed safe to restart"
  }
}

API Endpoints

POST/v1/approvals/requestRequest approval
org_idstringrequired
Organization external_id.
tool_namestringrequired
Tool name.
tool_idstring
Tool UUID.
reasonstring
Short display label for the approver (max 200 characters). Do not include PII — it will be redacted.
reference_idstring
Your internal correlation ID (max 100 characters). Use this to link the approval back to a record in your own system (e.g., ticket-14, incident-4821).
timeout_secondsinteger
Optional. When provided, the value is persisted to the per-tool override in the dashboard (Tools page Timeout column) for this (org, tool) pair, so every future approval honors it without needing the field passed again. Range 60 to 604800 (7 days); clamped automatically. Clear it from the dashboard with "Inherit from org". Omit to use whatever's already set in the UI.
tenant_idstring
Tenant external_id.
Response
{
  "approval_id": "uuid",
  "status": "pending",
  "expires_at": "2026-03-23T13:00:00Z",
  "reference_id": "incident-4821"
}
GET/v1/approvals/pendingList pending approvals

Each approval includes a display reference number in the format REF-XXXXXXXX-XXXX (derived from the approval UUID). This reference number also appears on linked execution logs in the dashboard, making it easy to trace an execution back to its approval.

GET/v1/approvals/:idCheck approval status (poll or after webhook)
POST/v1/approvals/:id/decideApprove or deny
decisionstringrequired
One of: approved or denied.
decided_bystring
Email or name of the person deciding.
notestring
Optional note from the approver.
POST/v1/approvals/:id/cancelCancel a pending approval

Execution Logging

Log every tool execution for audit trail. This is called after the tool runs, regardless of whether it succeeded or failed.

POST/v1/executions/logLog an execution
org_idstringrequired
Organization external_id.
tool_namestringrequired
Tool name.
tool_idstring
Tool UUID.
run_token_idstring
Token UUID from minting step.
execution_resultstringrequired
One of: success, failed, error, blocked.
duration_msinteger
How long the execution took.
triggered_bystringrequired
Who/what triggered this (user, agent, cron, etc.).
tenant_idstring
Tenant external_id.
metadataobject
Arbitrary metadata about the execution.
approval_request_idstring
Approval request UUID. Include this when the execution was triggered after an approval was granted, to link the execution to its approval record.
Request
{
  "org_id": "org_ftcECvT5dtdjIEgFCe6hGniT",
  "tool_name": "check_memory",
  "tool_id": "uuid",
  "run_token_id": "uuid",
  "execution_result": "success",
  "duration_ms": 42,
  "triggered_by": "ai_agent",
  "tenant_id": "ten_lLxSMc0CwLMbgGwCPA3Y95Xe",
  "approval_request_id": "uuid",
  "metadata": {
    "memory_used_percent": 67,
    "memory_total_gb": 8
  }
}
GET/v1/executionsQuery execution log

Query parameters: org_id, tenant_id, tool_name, execution_result, approval_request_id.

Executions that include an approval_request_id are linked to their approval record in the dashboard. The approval status, decision, and reference number are displayed alongside the execution details.

Questions? Contact us at hello@oakallow.io