OpenKnowra Platform · Action API

Action Builder

Put a decision policy to work as an agent: other AI agents call it over A2A or MCP, your systems over REST, people through a chat, with a person approving before it acts.

POST /a2a/{actionId}
Base URL https://okp.openknowra.ai Auth Action API key Protocol A2A 1.0 (JSON-RPC) Also as MCP server · REST · webhooks · website chat

When to use this API

Use the Action Builder when a decision should lead to something being done, and other software, an AI agent or a person needs to ask for it.

An action is built in the console from a decision policy of the Logic Controller. You choose the interfaces it ships as (a chat, an API, an MCP server, an A2A agent, a schedule or a connector) and its oversight: whether a person approves before it acts (the default) or reviews after. Every request and every decision is written to the audit log.

InterfaceUse it for
A2AAnother AI agent asks the action to act on a record, or asks it a question. Requests wait for a person's approval when the oversight says so.
MCP serverAn AI agent reads the action's recommendations as tools.
RESTYour systems get the recommendation for a record, list them, or report a change.
WebhooksYour systems are told when a record's recommendation changes.
Website chatPeople ask the action in plain words on your site or intranet.

Authentication

Every interface takes the action's API key. Create one in the console under the action's API & integration. A key opens this one action only, is shown once (only a hash of it is kept) and can be set to expire after 30, 90 or 365 days; rotate it with a grace period, or revoke it at once. Keys start with ok_live_.

Either header
x-ok-api-key: ok_live_xxxxxxxxxxxxxxxxxxxxxxxx
Authorization: Bearer ok_live_xxxxxxxxxxxxxxxxxxxxxxxx
One key per caller. A key opens every interface of the action, and the audit log names the caller by the key's label. Give each calling agent or system its own key, and give the website chat its own too, since its key sits in your page.

Parameters

Path

NameTypeRequiredDescription
actionIdstringrequiredThe action's id, shown under API & integration (for example uc-5e20d7).

The agent card

GET /a2a/{actionId}/.well-known/agent-card.json is public and describes the action to other agents: its endpoint, the security schemes (x-ok-api-key or bearer) and its skills. Send A2A-Version: 1.0 for the 1.0 form; without it the card is served in the 0.3 form. The card is offered once the action is deployed with A2A among its interfaces.

Skills

Name the skill in message.metadata.skill (or skill in a data part) and put its input in a data part. A plain-text message with no skill is taken as a question.

SkillInputWhat it does
request_action{ key, entity?, reason? }Asks the action to act on a record. With approves before it acts the task waits for a person; with reviews after it acts at once.
describe_decisions{ }The entities, fields and rules the action decides with.
decide{ entity, record }The recommendation for a record your system holds.
get_decision{ entity, key }One record's recommendation with its evidence.
list_decisions{ entity?, outcome?, limit?, offset? }The recommendations the deployed version holds.

Request

Ask the action to act on a record (A2A 1.0, SendMessage):

curl -X POST https://okp.openknowra.ai/a2a/$ACTION_ID \
  -H "x-ok-api-key: $OPENKNOWRA_ACTION_KEY" \
  -H "Content-Type: application/json" \
  -H "A2A-Version: 1.0" \
  -d '{"jsonrpc":"2.0","id":1,"method":"SendMessage","params":{"message":{"messageId":"m-1","role":"ROLE_USER",
       "metadata":{"skill":"request_action"},
       "parts":[{"data":{"key":"WO-2291","entity":"WorkOrder","reason":"Crew available on site today"}}]}}}'
import os, json, urllib.request

body = {"jsonrpc": "2.0", "id": 1, "method": "SendMessage", "params": {"message": {
    "messageId": "m-1", "role": "ROLE_USER", "metadata": {"skill": "request_action"},
    "parts": [{"data": {"key": "WO-2291", "entity": "WorkOrder", "reason": "Crew available on site today"}}]}}}
req = urllib.request.Request(
    "https://okp.openknowra.ai/a2a/" + os.environ["ACTION_ID"],
    data=json.dumps(body).encode(),
    headers={"x-ok-api-key": os.environ["OPENKNOWRA_ACTION_KEY"], "Content-Type": "application/json",
             "A2A-Version": "1.0"},
    method="POST")
print(json.load(urllib.request.urlopen(req, timeout=30)))
const res = await fetch(`https://okp.openknowra.ai/a2a/${process.env.ACTION_ID}`, {
  method: "POST",
  headers: { "x-ok-api-key": process.env.OPENKNOWRA_ACTION_KEY!, "Content-Type": "application/json", "A2A-Version": "1.0" },
  body: JSON.stringify({
    jsonrpc: "2.0", id: 1, method: "SendMessage",
    params: { message: { messageId: "m-1", role: "ROLE_USER", metadata: { skill: "request_action" },
      parts: [{ data: { key: "WO-2291", entity: "WorkOrder", reason: "Crew available on site today" } }] } },
  }),
});
console.log(await res.json());
Any A2A client works. The action speaks A2A 1.0 over JSON-RPC (SendMessage, SendStreamingMessage, GetTask, CancelTask, ListTasks) and also accepts the 0.3 method names (message/send, tasks/get, ...).

Response

200 OK - a task. With approves before it acts, a request_action task stays working until a person decides in the console:

application/json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "task": {
      "id": "8f1c2a90-4b7e-4d2a-9a51-1b2c3d4e5f60",
      "contextId": "c-77b1",
      "status": {
        "state": "TASK_STATE_WORKING",
        "message": { "role": "ROLE_AGENT", "parts": [{ "text": "Awaiting approval by the action's approvers: Field dispatch acts on WO-2291 once a person approves. Read the outcome with GetTask." }] }
      }
    }
  }
}

Poll the task with GetTask until it settles:

State (1.0 · 0.3)Meaning
TASK_STATE_WORKING · workingWaiting for a person's approval (or still running).
TASK_STATE_COMPLETED · completedApproved and done, or acted on at once under reviews after. The result is an artifact named after the skill, with a text part and a data part.
TASK_STATE_REJECTED · rejectedDeclined by a person; the status message gives who and why.
TASK_STATE_FAILED · failedThe request could not be carried out, for example an unknown skill or record. The status message says why.
GetTask
curl -X POST https://okp.openknowra.ai/a2a/$ACTION_ID \
  -H "x-ok-api-key: $OPENKNOWRA_ACTION_KEY" -H "Content-Type: application/json" -H "A2A-Version: 1.0" \
  -d '{"jsonrpc":"2.0","id":2,"method":"GetTask","params":{"id":"8f1c2a90-4b7e-4d2a-9a51-1b2c3d4e5f60"}}'
Read results promptly. The action does not push task updates to you (pushNotifications: false on the card): poll with GetTask, or use SendStreamingMessage while you wait. Tasks are kept for a limited time, so read a settled task's outcome soon after it settles; the decision itself stays on the action's audit log.

MCP server

The action is also an MCP server (Streamable HTTP, JSON-RPC 2.0) at https://okp.openknowra.ai/api/okp/mcp/{actionId}, with the tools describe_decisions, decide, get_decision and list_decisions. They read recommendations; asking the action to act is A2A's request_action.

MCP client configuration
{
  "mcpServers": {
    "field-dispatch": {
      "type": "http",
      "url": "https://okp.openknowra.ai/api/okp/mcp/<actionId>",
      "headers": { "Authorization": "Bearer ok_live_xxxxxxxxxxxxxxxxxxxxxxxx" }
    }
  }
}

REST

The action answers the same REST API as its decision policy, relative to https://okp.openknowra.ai/api/okp/d/{actionId}: GET / (describe), POST /decide, GET /decisions, GET /decisions/{entity}/{key}, POST /events and GET /openapi.json. The request and response shapes are on the Logic Controller page.

Request
curl https://okp.openknowra.ai/api/okp/d/$ACTION_ID/decisions/WorkOrder/WO-2291 \
  -H "x-ok-api-key: $OPENKNOWRA_ACTION_KEY"

Webhooks

Under API & integration, add a webhook to be told when a record gains or loses an outcome (rule_result.gained, rule_result.lost) or a new version is deployed (version.published). Deliveries are signed with your secret in x-ok-signature (sha256= HMAC of timestamp + "." + body, with x-ok-timestamp in milliseconds) and sent once with an 8-second timeout. The headers, payloads and a verification example are on the Logic Controller page.

Website chat

Paste the action's chat into any page; people ask it in plain words and get its recommendations.

Embed
<script src="https://okp.openknowra.ai/okplatform/widget.js"
        data-agent="<actionId>" data-key="ok_live_xxxxxxxxxxxxxxxxxxxxxxxx"
        data-title="Field dispatch" data-position="right"></script>

Optional attributes: data-title, data-color, data-position (right or left), data-open="true", data-inline (a CSS selector to render into) and data-theme (light or dark).

Pricing

Requests over A2A, MCP and REST, and webhook deliveries, carry no per-call charge. Questions people ask in the website chat are billed as Natural Language Queries, and the context graph the action decides on is billed under the Context Compiler. The APIs, AI agents and workers an action can call are priced on their own cards: Action Builder pricing.

Errors

A2A and MCP answer with JSON-RPC errors; REST and the chat with { "error", "message" }.

StatusCodeMeaning
401-32001 · invalid_api_keyMissing, revoked or expired key, or a key for another action.
402insufficient_creditsWebsite chat: your organisation's balance cannot pay for the question.
404-32001 · not_foundNo such action, or it is not offered over A2A (not deployed, or A2A is not among its interfaces).
405-32000MCP: only POST is supported.
409not_publishedThe action has no deployed version yet.
423-32001 · pausedThe action is paused in the console.
200-32601 · -32602JSON-RPC: unknown method, or an unknown tool or bad arguments.
5xx-32603 · failedTransient. Retry with exponential backoff.