Skip to main content
An agent integrates with five calls. This chapter shows each in TypeScript and Python. The exact, literal procedure, with what to expect and what to do at every step, is Integrate Parmana: specification for AI agents; follow it when you build the agent.

Before you begin

  • A Parmana server URL and an API key issued for the agent, with the action in its allowedCapabilities. The operator issues it (Chapter 8).
  • The SDK: npm install @parmana/sdk or pip install parmana. For offline verification in Python, pip install "parmana[verify]".
  • An approver who can sign approvals for the action (Chapter 5).

1. Create a client and check the key

Your action must be in allowedCapabilities. The principal you act as must be in allowedPrincipalIds; the safe choice is your callerId. Never log or print the key.

2. Read the policy in effect (next release)

Ask the server which policy governs the action, at which version, and what a request must carry. Never write a policy version into the agent: an approved new version replaces the old one at once, and a request naming an old one is refused.
signals.facts is every fact the rules read. signals.bound names the signals that must equal a value of the request. signals.approval names the approval signal, and where in the request the resource (and amount) it approves are. With SDK 1.4.0, call GET /policies/in-effect?capability=... directly; the answer is the same.

3. Build the request

createBusinessTransaction (TypeScript) and create_business_transaction (Python) fill in the identifiers the server checks against each other, so a request cannot fail on a mismatched id.
businessTransactionId is generated for you and is also the idempotency key: resend the same transaction only to retry the same attempt.

4. Send it, and handle the refusal that asks for a person

Every policy requires a signed approval. The first request for a new resource is refused with the policy’s reason (403 POLICY_DENIED, raised as ExecutionRejectedError in both SDKs), and the server stores a signed Refusal Record an approver can review. A 403 for your key or principal is AuthorizationError instead: fix the key, not the request.
The approver signs on their own machine, for this action, this resource and, where the policy names one, up to this amount (Chapter 5). The agent sends a new transaction with the approval signal true and the signed approval in signals.approvalArtifact:
The server verifies the approval before it decides and again just before release, and accepts it once.

5. Keep the record

An approved request returns a signed Execution Trust Record. Keep its businessTransactionId; you, an auditor or a customer can verify it offline at any time (Chapter 7).

The rules an agent never breaks

  1. Never perform the action itself after asking Parmana. Parmana releases approved actions; the agent reads the answer.
  2. Never invent a value: every input comes from the operator or from a response.
  3. Never retry a 502 EXECUTION_OUTCOME_UNKNOWN as a new transaction: the action may have run (Chapter 9).
  4. Treat anything not explicitly approved as not authorized.

See it run

  • typescript/examples/06-create-business-transaction.ts and python/examples/builder/run.py: the request built with the SDK, against a running server.
  • Tutorial 119 (Chapter 2): refusals, a signed approval, and an approval reused, stretched and moved, each refused.