Previous PayReality technical work. This page documents an earlier product direction and does not describe our current offering or availability. See what we're working on now.

← Developers

SDKs

A Python package that wraps the Intent API, so integrating an agent never means hand-implementing ED25519 signing, certificate headers, or retry logic.

PythonLIVE

The PayReality SDK (payreality) is a client, not a platform change: it consumes the same /v1/principals, /v1/agents, /v1/intents, and /v1/decisions endpoints that exist on the API today. Nothing about the Decision Engine, the Compiler, OPA, or Evidence changes because the SDK exists; it just removes the parts a developer shouldn't have to hand-roll.

The package isn't on public PyPI yet, so pip install payreality doesn't resolve today; build it from source (python -m build in sdk-python/) or install the wheel from a release artifact in the meantime. A public PyPI release is prepared, not shipped.

You don't need a production credential, or the platform Operator Key, to try any of this. A sandbox organization, its own real backend authority path, is self-service:

get_sandbox.sh
curl -X POST https://api.aisecurewatch.com/v1/sandbox/organizations \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com"}'

# -> {"organization_id": "...", "api_key": "pr_live_...", "starter_policy_key": "..."}

That response is a real, scoped API key for a real, isolated sandbox organization on the same production backend, already carrying one starter Runtime Policy (a low-risk reference action, allowed with no configuration) so your very first authorize() call below returns a real ALLOW, not just a stub. See the Getting Started guide for sandbox limits and what happens to a sandbox organization over time.

Register an agent

quickstart.py
from payreality import Agent

agent = Agent(bearer_token="pr_live_...", base_url="https://api.aisecurewatch.com")
identity = agent.register(name="AP Automation Agent", principal="Finance Manager")

print(identity.agent_id)         # server-assigned, never hand-picked
print(identity.certificate_id)   # the certificate this agent signs with

register() generates an ED25519 key pair locally, uploads only the public key, and returns a ready-to-use identity in one call. Registration is idempotent per key: calling register() again with the same private key returns the cached identity instead of creating a duplicate agent, which makes it safe to call on every process start rather than something you need to guard yourself.

Registering an agent establishes its identity. It doesn't, by itself, grant that agent any authority; that's the runtime's own job, evaluated per request. The SDK is a thin developer interface into PayReality, not a local copy of your governance logic: your Runtime Policies and Authority Graph live, and are evaluated, on PayReality's side, every time you call authorize().

Submitting an action

submit_intent.py
decision = agent.authorize(
    principal="Finance Manager",
    operation="submit_invoice",
    resource="Vendor Payment",
    resource_data={
        "amount": 8500,
        "currency": "USD",
        "vendor": "Acme Supplies",
    },
)

if decision.outcome == "ALLOW":
    ...  # proceed
elif decision.outcome == "HUMAN_REVIEW":
    ...  # a person will resolve this in the Review Queue

authorize() signs the request with the agent's own certificate, exactly like every signed Intent the API accepts. There are exactly three outcomes: ALLOW, DENY, or HUMAN_REVIEW. An action the platform doesn't recognize is never silently allowed: it's escalated to a human, the same fail-closed behavior the Decision Engine applies everywhere.

Calling authorize() doesn't ask PayReality to decide whether the action is a good idea. It asks the runtime to independently check the request against the policy your organization already set, the same approval matrices and spending limits that govern your human workforce, now evaluated against an agent instead of a person. The organization's policy is what authorizes the action; authorize() is the call that evaluates it.

What authenticates register(), and what doesn't

register(), rotate_keys(), and retire() are administrative actions, so they need an administrative credential: either Agent(bearer_token=...) (a session token or a scoped API key, like a sandbox credential, an organization's own/v1/organization/api-keys, or the sandbox response above), or Agent(api_key=...), the platform-wide Operator Key (see Authentication), an internal, administrative credential, not something a new external developer is issued. Prefer bearer_token for anything beyond the platform's own internal use. Neither is required for authorize() or heartbeat(), which authenticate purely via the agent's own certificate signature, the same way a human employee's badge doesn't require their manager's key to walk through a door they're already authorized for.

Issuing and verifying a Capability Authorization

capability.py
# After an ALLOW decision:
capability = agent.request_capability(decision.decision_id, audience="reference-pep")

# Or after a Human Review decision has since been approved:
capability = agent.request_capability_from_review(decision.decision_id, audience="reference-pep")

# At the enforcement checkpoint, before letting the downstream operation proceed:
consumed = agent.verify_capability(
    capability.token,
    audience="reference-pep",
    action="supplier_bank_details_change",
    resource="supplier:SUPPLIER_482",
    constraints={},
)

request_capability() and request_capability_from_review() authenticate the same way register() does: with a bearer token or API key if you have one, falling back to the Operator Key (naming its target organization) otherwise. Either can issue at most one Capability per decision, ever. verify_capability() is the checkpoint's own call: it consumes the Capability exactly once, rechecking that the organization, the originating agent, and any Trusted Integration identity it depends on are still active immediately beforehand, and fails closed if one isn't.

Why the SDK is synchronous

agent.authorize(...) is called directly, no await. This matches the default surface most developers already expect from a first SDK release (Stripe, OpenAI, and Supabase all ship synchronous clients as their default), keeping the initial surface area matched to what most integrations actually need. An async client is a natural, additive future addition, not a redesign.

Retries and error handling

Connection failures, timeouts, and 5xx responses are retried automatically with capped exponential backoff. 401, 403, and any other 4xx (including 422 validation failures) are never retried, since none of these can succeed by trying again unmodified. Every failure, network or HTTP, is mapped onto a typed exception before it reaches your code: you never see a raw HTTP client exception or a bare status code.

Language roadmap

Python ships first because it's what most agent frameworks in this space are already written in (LangGraph, CrewAI, AutoGen, the OpenAI and Anthropic SDKs). The following are planned, not started: there is no partial implementation to preview yet:

Node.jsPLANNED
GoPLANNED
JavaPLANNED
.NETPLANNED
RustPLANNED

For the full lifecycle methods (rotating keys, heartbeats, retiring an agent), see Integration Examples.

Other documentation

Getting StartedCreate an organization, register an agent, and get your first Authorization Receipt back.ArchitectureThe full path from an agent's signed intent to a decision and its evidence, component by component.Runtime APIThe Intent API: POST /v1/intents, its three possible outcomes, and the request/response lifecycle.AuthenticationThe Operator Key, per-user roles and permissions, per-developer API keys, and agent certificates.Authority GraphDelegated authority, roles, resources, and approval limits, and how governance becomes machine-readable.Runtime PoliciesHow a policy is compiled, versioned, and deployed, and why that differs from the governance document it came from.Authorization ReceiptsWhy logs aren't enough, the receipt lifecycle, and the planned architecture for independent verification.Evidence VerificationSignature verification, evidence export, and audit workflows against the Evidence Portal today.WebhooksEnterprise events (IntentReceived, DecisionCompleted, ReceiptIssued, and more) with real payloads.Integration ExamplesRotating keys, sending a heartbeat, and retiring an agent, with real SDK code for each.Integration GuidesConnecting Runtime Authority to agent frameworks, model providers, and enterprise systems.Agent RegistrationThe full agent lifecycle: registered, active, suspended, retired, or revoked.API ReferenceEndpoints, schemas, headers, status codes, errors, and versioning.Order WalkthroughOne order, followed end to end: signed intent, declared material fields, capability issuance, rejection on a changed field, and what the receipt path does and doesn't prove.