API reference
Per-action authority for AI agents acting on delegated financial authority. Version 0.1.0. The source is the OpenAPI 3.1 file.
Authentication
Send an API key as Authorization: Bearer <key>. Key format pv_test_GET /.well-known/jwks.json.
Base URLs
https://api.polivor.comhttps://api.staging.polivor.com
Operations
- mcp: POST /mcp
- authorize: POST /v1/authorize, POST /v1/simulate, GET /v1/decisions/{id}
- authorization: POST /v1/authorizations/{id}/execution, POST /v1/authorizations/{id}/not-executed
- identity: POST /v1/principals, GET /v1/agents, POST /v1/agents, POST /v1/agents/{id}/versions, POST /v1/agents/{id}/suspend
- mandate: GET /v1/mandates, POST /v1/mandates, POST /v1/mandates/import/ap2, GET /v1/trusted-issuers, POST /v1/trusted-issuers, GET /v1/mandates/{id}, POST /v1/mandates/{id}/versions, POST /v1/mandates/{id}/activate, POST /v1/mandates/{id}/suspend, POST /v1/mandates/{id}/resume, POST /v1/mandates/{id}/revoke
- beneficiary: GET /v1/beneficiaries, POST /v1/beneficiaries, PATCH /v1/beneficiaries/{id}
- policy: GET /v1/policies, POST /v1/policies, POST /v1/policies/{version}/publish
- evidence: GET /v1/evidence, GET /v1/evidence/export, GET /.well-known/jwks.json
- keys: GET /v1/keys, POST /v1/keys, POST /v1/keys/{id}/revoke
- webhook: GET /v1/webhook, PUT /v1/webhook, DELETE /v1/webhook
mcp
POST /mcp
Model Context Protocol server with the tools authorize and get_decision (role agent)
Roles: agent. Operation id mcpMessage.
MCP over Streamable HTTP, answered as plain JSON (no event stream, no sessions): one JSON-RPC 2.0 message per POST. Supported methods:
initialize, ping, tools/list and tools/call; notifications get 202. Protocol versions 2025-06-18, 2025-03-26 and 2024-11-05.
The tool authorize takes the fields of AuthorizeRequest plus a required idempotency_key; get_decision takes decision_id. A tool
result carries the same JSON as the REST response (as structuredContent and as text); a business error is a tool result with
isError: true holding a problem details object. Same API keys, roles and rate limits as /v1. Requests with an Origin header are
refused (MCP clients are programs, not web pages). GET is not supported (405).
| Name | In | Required | Type | Description |
|---|---|---|---|---|
MCP-Protocol-Version | header | no | 2025-06-18, 2025-03-26, 2024-11-05 | Sent by clients after initialize |
Request body (JSON, required): JsonRpcMessage
| Status | Meaning | Body |
|---|---|---|
200 | A JSON-RPC response (a result, or an error object) | JsonRpcMessage |
202 | A notification was received (no response body) | |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
429 | Problem details with a stable code |
authorize
Request authority for one action (role agent)
Roles: agent. Operation id authorize.
400 IDEMPOTENCY_KEY_REQUIRED when the header is missing. 409 IDEMPOTENCY_KEY_REUSED when the key was used with a different body (or by another agent), and IDEMPOTENCY_KEY_EXPIRED once the 24 h retention is over. A replay returns the stored response unchanged. REQUIRE_APPROVAL reserves no budget; budget is reserved when the approval is granted.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no |
Request body (JSON, required): AuthorizeRequest
| Status | Meaning | Body |
|---|---|---|
200 | ALLOW (with authorization) or DENY | AuthorizeResponse |
202 | REQUIRE_APPROVAL, decision is pending | AuthorizeResponse |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
409 | Problem details with a stable code | |
422 | Problem details with a stable code | |
429 | Problem details with a stable code |
POST /v1/simulate
Dry run of the same decision as authorize. No writes, no budget reserved, no authorization, no evidence (role admin)
Roles: admin. Operation id simulate.
Request body (JSON, required): SimulateRequest
| Status | Meaning | Body |
|---|---|---|
200 | Simulated decision | SimulateResponse |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code | |
422 | Problem details with a stable code |
GET /v1/decisions/{id}
Decision status; authorization once approved (roles agent, admin)
Roles: agent, admin. Operation id getDecision.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no |
| Status | Meaning | Body |
|---|---|---|
200 | Decision | DecisionStatus |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code |
authorization
POST /v1/authorizations/{id}/execution
Enforcement point reports a terminal execution result (role enforcer)
Roles: enforcer. Operation id reportExecution.
One terminal report per authorization. 409 ALREADY_REPORTED for a second one, 410 REPORT_WINDOW_CLOSED more than 24 h after the authorization expired. REJECTED and FAILED release the reserved budget; EXECUTED keeps it consumed.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no |
Request body (JSON, required): ExecutionReport
| Status | Meaning | Body |
|---|---|---|
200 | Recorded | AuthorizationStatus |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code | |
409 | Problem details with a stable code | |
410 | Problem details with a stable code |
POST /v1/authorizations/{id}/not-executed
Release an unreported authorization and its reserved budget (role admin)
Roles: admin. Operation id markNotExecuted.
Only after the authorization has expired (409 AUTHORIZATION_STILL_VALID before), because until then the enforcement point could still use it.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no |
| Status | Meaning | Body |
|---|---|---|
200 | Released | AuthorizationStatus |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code | |
409 | Problem details with a stable code |
identity
POST /v1/principals
Roles: admin. Operation id createPrincipal.
Request body (JSON, required): PrincipalCreate
| Status | Meaning | Body |
|---|---|---|
201 | Created | Principal |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
422 | Problem details with a stable code |
GET /v1/agents
Roles: admin. Operation id listAgents.
| Status | Meaning | Body |
|---|---|---|
200 | Agents with their versions | array of Agent |
401 | Problem details with a stable code | |
403 | Problem details with a stable code |
POST /v1/agents
Roles: admin. Operation id createAgent.
Request body (JSON, required): AgentCreate
| Status | Meaning | Body |
|---|---|---|
201 | Created | Agent |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
422 | Problem details with a stable code |
POST /v1/agents/{id}/versions
Roles: admin. Operation id registerAgentVersion.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no |
Request body (JSON, required): object
| Status | Meaning | Body |
|---|---|---|
201 | Registered | Agent |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code | |
409 | Problem details with a stable code | |
422 | Problem details with a stable code |
POST /v1/agents/{id}/suspend
Roles: admin. Operation id suspendAgent.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no |
| Status | Meaning | Body |
|---|---|---|
200 | Suspended | Agent |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code |
mandate
GET /v1/mandates
Roles: admin. Operation id listMandates.
| Status | Meaning | Body |
|---|---|---|
200 | Mandates | array of Mandate |
401 | Problem details with a stable code | |
403 | Problem details with a stable code |
POST /v1/mandates
Create a native Financial Mandate (validated against financial-mandate/v0)
Roles: admin. Operation id createMandate.
Request body (JSON, required): MandateBody
| Status | Meaning | Body |
|---|---|---|
201 | Created as DRAFT, version 1 | Mandate |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
422 | Problem details with a stable code |
POST /v1/mandates/import/ap2
Import an AP2 open payment mandate into a DRAFT native mandate (adapter; body at most 64 KB)
Roles: admin. Operation id importAp2Mandate.
Accepts an AP2 v0.2 Open Payment Mandate (vct mandate.payment.open.1) as an SD-JWT signed ES256 by a key of a trusted issuer
(POST /v1/trusted-issuers). The signature, every disclosure and the expiry are checked. What AP2 states precisely is copied
(per-payment maximum as integer minor units and its currency, the validity window); everything else is listed in the report as
not enforced natively or as still to complete. Principal and agent come from the request.
Constraints Polivor cannot enforce. AP2 says a constraint a verifier does not understand must fail evaluation, and a native
mandate is looser than the credential wherever it cannot enforce one. So an import that carries payees, a budget, recurrence,
payment instruments, PISPs, a reference or a minimum amount is refused (422 AP2_UNENFORCED_CONSTRAINTS, one error per type) until the
request names each of them in acknowledge_unenforced; constraint types AP2 does not define at all are never imported
(422 AP2_UNKNOWN_CONSTRAINT). Issuer keys are the ones registered for the issuer plus, if it has a jwks_url, the set published
there at the time of the import (AP2_ISSUER_KEYS_UNAVAILABLE if that cannot be fetched). The DRAFT cannot be activated until a new
version with the missing fields is created (POST /v1/mandates/{id}/versions). The raw credential and its hash are kept.
Request body (JSON, required): object
| Status | Meaning | Body |
|---|---|---|
201 | DRAFT mandate and what was done with each part of the credential | Ap2ImportResult |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code | |
409 | Problem details with a stable code | |
422 | Problem details with a stable code |
GET /v1/trusted-issuers
Roles: admin. Operation id listTrustedIssuers.
| Status | Meaning | Body |
|---|---|---|
200 | Trusted issuers of this tenant | array of TrustedIssuer |
401 | Problem details with a stable code | |
403 | Problem details with a stable code |
POST /v1/trusted-issuers
Register an issuer whose AP2 credentials may be imported (public keys only)
Roles: admin. Operation id registerTrustedIssuer.
Give the issuer's public P-256 keys (jwks), the HTTPS URL where it publishes them (jwks_url), or both. A URL is fetched when a
credential is imported and is never cached, so a rotated or withdrawn key takes effect immediately. The URL must be public (no
private or internal addresses), is not followed through redirects, and must serve at most 10 public keys, each with a kid.
Request body (JSON, required): any or any
| Status | Meaning | Body |
|---|---|---|
201 | Registered | TrustedIssuer |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
422 | Problem details with a stable code |
GET /v1/mandates/{id}
The version in force, or any other version with ?version=n (versions are immutable and stay readable)
Roles: admin. Operation id getMandate.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no | |||
version | query | no | integer (minimum 1) |
| Status | Meaning | Body |
|---|---|---|
200 | Mandate with all versions readable | Mandate |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code |
POST /v1/mandates/{id}/versions
Create version n+1 (versions are immutable)
Roles: admin. Operation id createMandateVersion.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no |
Request body (JSON, required): MandateBody
| Status | Meaning | Body |
|---|---|---|
201 | New version | Mandate |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code | |
409 | Problem details with a stable code | |
422 | Problem details with a stable code |
POST /v1/mandates/{id}/activate
Roles: admin. Operation id activateMandate.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no |
| Status | Meaning | Body |
|---|---|---|
200 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code | |
409 | Problem details with a stable code | |
422 | Problem details with a stable code |
POST /v1/mandates/{id}/suspend
Roles: admin. Operation id suspendMandate.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no |
| Status | Meaning | Body |
|---|---|---|
200 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code | |
409 | Problem details with a stable code |
POST /v1/mandates/{id}/resume
Roles: admin. Operation id resumeMandate.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no |
| Status | Meaning | Body |
|---|---|---|
200 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code | |
409 | Problem details with a stable code |
POST /v1/mandates/{id}/revoke
Final; cannot be undone
Roles: admin. Operation id revokeMandate.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no |
| Status | Meaning | Body |
|---|---|---|
200 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code | |
409 | Problem details with a stable code |
beneficiary
GET /v1/beneficiaries
Roles: admin. Operation id listBeneficiaries.
| Status | Meaning | Body |
|---|---|---|
200 | Allowlist | array of Beneficiary |
401 | Problem details with a stable code | |
403 | Problem details with a stable code |
POST /v1/beneficiaries
Roles: admin. Operation id createBeneficiary.
Request body (JSON, required): BeneficiaryCreate
| Status | Meaning | Body |
|---|---|---|
201 | Created | Beneficiary |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
409 | Problem details with a stable code | |
422 | Problem details with a stable code |
PATCH /v1/beneficiaries/{id}
Roles: admin. Operation id updateBeneficiary.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no |
Request body (JSON, required): BeneficiaryUpdate
| Status | Meaning | Body |
|---|---|---|
200 | Updated | Beneficiary |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code | |
422 | Problem details with a stable code |
policy
GET /v1/policies
Roles: admin. Operation id listPolicies.
| Status | Meaning | Body |
|---|---|---|
200 | Policy versions | array of PolicyVersion |
401 | Problem details with a stable code | |
403 | Problem details with a stable code |
POST /v1/policies
Create a DRAFT policy version from template parameters or raw Cedar; validated against the Cedar schema
Roles: admin. Operation id createPolicy.
Request body (JSON, required): PolicyCreate
| Status | Meaning | Body |
|---|---|---|
201 | DRAFT version | PolicyVersion |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
422 | Problem details with a stable code |
POST /v1/policies/{version}/publish
Publish; immutable afterwards. Rejected if a permit rule references signals
Roles: admin. Operation id publishPolicy.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
version | path | yes | integer (minimum 1) |
| Status | Meaning | Body |
|---|---|---|
200 | Now the active version | PolicyVersion |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code | |
409 | Problem details with a stable code | |
422 | Problem details with a stable code |
evidence
GET /v1/evidence
Roles: admin. Operation id listEvidence.
| Name | In | Required | Type | Description |
|---|---|---|---|---|
from_seq | query | no | integer (minimum 0) | |
limit | query | no | integer (minimum 1, maximum 1000, default 100) |
| Status | Meaning | Body |
|---|---|---|
200 | Evidence rows in sequence order | array of EvidenceRow |
401 | Problem details with a stable code | |
403 | Problem details with a stable code |
GET /v1/evidence/export
Bundle for a range - rows, JWS, chain hashes and JWKS - verifiable offline
Roles: admin. Operation id exportEvidence.
At most 10000 rows per export (422 RANGE_TOO_LARGE otherwise).
| Name | In | Required | Type | Description |
|---|---|---|---|---|
from_seq | query | no | integer (minimum 0) | |
to_seq | query | no | integer (minimum 0) |
| Status | Meaning | Body |
|---|---|---|
200 | Export bundle | EvidenceBundle |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
422 | Problem details with a stable code |
GET /.well-known/jwks.json
Public keys (authz-signing and evidence-signing, all versions)
No API key needed. Operation id getJwks.
| Status | Meaning | Body |
|---|---|---|
200 | JWKS | Jwks |
keys
GET /v1/keys
Keys of this tenant, active and revoked (never the secret)
Roles: admin. Operation id listApiKeys.
| Status | Meaning | Body |
|---|---|---|
200 | Keys, newest first | array of ApiKey |
401 | Problem details with a stable code | |
403 | Problem details with a stable code |
POST /v1/keys
Create an API key; the secret is returned once and stored hashed
Roles: admin. Operation id createApiKey.
Request body (JSON, required): ApiKeyCreate
| Status | Meaning | Body |
|---|---|---|
201 | Created | ApiKeyCreated |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
422 | Problem details with a stable code |
POST /v1/keys/{id}/revoke
Revoke a key; takes effect on the next request (well within 5 s). Idempotent
Roles: admin. Operation id revokeApiKey.
The last active admin key cannot be revoked (409 LAST_ADMIN_KEY).
| Name | In | Required | Type | Description |
|---|---|---|---|---|
| no |
| Status | Meaning | Body |
|---|---|---|
204 | Revoked | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
404 | Problem details with a stable code | |
409 | Problem details with a stable code |
webhook
GET /v1/webhook
The tenant's webhook URL, if any (role admin)
Roles: admin. Operation id getWebhook.
| Status | Meaning | Body |
|---|---|---|
200 | Webhook status | WebhookStatus |
401 | Problem details with a stable code | |
403 | Problem details with a stable code |
PUT /v1/webhook
Set the webhook URL and create a new signing secret, shown once (role admin)
Roles: admin. Operation id setWebhook.
Events: decision.resolved (an approval ended: ALLOWED with the authorization, or DENIED with a reason), authorization.reported
(an execution report or an admin release) and webhook.test. Each delivery is POST with the JSON body
{id, type, created_at, tenant_id, data} and the headers Polivor-Event-Id and Polivor-Signature: t=<unix seconds>,v1=<hex>, where
v1 is HMAC-SHA256 of <t>.<raw body> with the secret. Reject deliveries whose t is far from your clock. Any 2xx is success; other
results are retried 5 times with backoff (1 min, 5 min, 15 min, 1 h, 6 h) and the same event ID. The URL must be HTTPS and public.
Request body (JSON, required): WebhookSet
| Status | Meaning | Body |
|---|---|---|
200 | Configured. The secret is not shown again; setting the URL again creates a new one. | WebhookConfigured |
400 | Problem details with a stable code | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code | |
422 | Problem details with a stable code |
DELETE /v1/webhook
Stop sending events (role admin)
Roles: admin. Operation id removeWebhook.
| Status | Meaning | Body |
|---|---|---|
204 | Removed or none was set | |
401 | Problem details with a stable code | |
403 | Problem details with a stable code |
Schemas
WebhookSet
| Property | Type | Required | Description |
|---|---|---|---|
url | string (maxLength 2048) | yes | HTTPS |
WebhookStatus
| Property | Type | Required | Description |
|---|---|---|---|
configured | boolean | yes | |
url | string or null | no |
WebhookConfigured
| Property | Type | Required | Description |
|---|---|---|---|
url | string | yes | |
secret | string | yes | Shown once. Sign check: HMAC-SHA256(secret, " |
JsonRpcMessage
A JSON-RPC 2.0 request, notification, result or error object (https://www.jsonrpc.org/specification)
| Property | Type | Required | Description |
|---|---|---|---|
jsonrpc | "2.0" | yes | |
id | string or integer or null | no | |
method | string | no | |
params | object | no | |
result | object | no | |
error | object | no |
Uuid
Type: string, uuid
Currency
Type: string (pattern "^[A-Z]{3}$")
Country
Type: string (pattern "^[A-Z]{2}$")
Iban
Type: string (pattern "^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$")
MinorAmount
Integer minor units (cents); never a float
Type: integer, int64 (minimum 1)
Problem
| Property | Type | Required | Description |
|---|---|---|---|
type | string | yes | |
title | string | yes | |
status | integer | yes | |
detail | string | no | |
code | string | yes | Stable machine-readable code. Match on it, not on detail. New codes can be added, so treat an unknown code by its HTTP status.
Every code with its status and meaning is in the error codes guide (/docs/errors-limits.html); a test keeps that list equal to the codes the API can return.
|
errors | array of object | no |
Reason
| Property | Type | Required | Description |
|---|---|---|---|
policy_id | string | no | The Cedar policy that decided |
code | string | no | A pre-check or system reason, e.g. AGENT_SUSPENDED, MANDATE_REVOKED, NO_PERMIT, NO_ACTIVE_POLICY |
Check
| Property | Type | Required | Description |
|---|---|---|---|
id | string | yes | |
result | pass, fail, satisfied, not_satisfied | yes | |
detail | object | no |
Beneficiary_Ref
Unknown fields are ignored. Everything decisive about the beneficiary is computed by Polivor from the allowlist and the IBAN.
| Property | Type | Required | Description |
|---|---|---|---|
id | string (minLength 1, maxLength 100) | yes | |
iban | string (minLength 1, maxLength 42) | yes | |
country | string | no | Accepted for compatibility and never used |
Action
Unknown fields are ignored and never influence the decision.
| Property | Type | Required | Description |
|---|---|---|---|
type | "PayInvoice" | yes | |
amount_minor | MinorAmount | yes | |
currency | Currency | yes | |
debtor_account | string (minLength 15, maxLength 42) | yes | |
payment_type | SEPA_CT, SEPA_INST | yes | |
beneficiary | Beneficiary_Ref | yes | |
reference | string (minLength 1, maxLength 140) | yes |
Signals
Agent-supplied; may only be used in forbid rules (signals tighten, never loosen). Unknown fields are ignored.
| Property | Type | Required | Description |
|---|---|---|---|
origin | string (maxLength 100) | no | |
risk_flags | array of string (maxItems 50) | no |
AuthorizeRequest
Unknown fields are ignored. Flags such as iban_changed or beneficiary_allowlisted have no effect, Polivor computes those facts itself.
SimulateRequest
Combines: AuthorizeRequest and object
SimulateResponse
AuthorizationArtifact
| Property | Type | Required | Description |
|---|---|---|---|
id | Uuid | yes | |
jws | string | yes | Compact JWS, typ polivor-authz+jwt, alg EdDSA |
expires_at | string, date-time | yes |
AuthorizeResponse
| Property | Type | Required | Description |
|---|---|---|---|
decision_id | Uuid | yes | |
simulated | boolean | no | |
outcome | ALLOW, DENY, REQUIRE_APPROVAL | yes | |
reasons | array of Reason | yes | |
checks | array of Check | yes | |
mandate | object | no | |
policy_version | integer (minimum 0) | yes | |
evidence | object | yes | Absent on simulate |
authorization | AuthorizationArtifact | no |
DecisionStatus
| Property | Type | Required | Description |
|---|---|---|---|
decision_id | Uuid | yes | |
outcome | ALLOW, DENY, REQUIRE_APPROVAL | yes | |
status | ALLOWED, DENIED, PENDING_APPROVAL | yes | |
reasons | array of Reason | no | |
authorization | AuthorizationArtifact | no |
ExecutionReport
| Property | Type | Required | Description |
|---|---|---|---|
status | EXECUTED, REJECTED, FAILED | yes | |
external_ref | string (maxLength 200) | no |
AuthorizationStatus
| Property | Type | Required | Description |
|---|---|---|---|
id | Uuid | yes | |
status | ISSUED, EXECUTED, REJECTED, FAILED, NOT_EXECUTED | yes | |
reported_at | string or null, date-time | no | |
external_ref | string or null | no |
PrincipalCreate
| Property | Type | Required | Description |
|---|---|---|---|
legal_name | string (minLength 1, maxLength 200) | yes | |
country | Country | yes | |
lei | string (pattern "^[A-Z0-9]{20}$") | no |
Principal
AgentCreate
| Property | Type | Required | Description |
|---|---|---|---|
name | string (minLength 1, maxLength 200) | yes | |
principal_id | Uuid | yes | |
owner_email | string, email | yes | |
version | string (minLength 1, maxLength 64) | yes |
Agent
MandateBody
Native Financial Mandate body. The authoritative definition is docs/schema/financial-mandate.v0.json; validated against it on write. A DRAFT imported from AP2 holds only the mapped fields until a complete version is added.
| Property | Type | Required | Description |
|---|---|---|---|
schema | "polivor.financial-mandate/v0" | yes |
TrustedIssuer
| Property | Type | Required | Description |
|---|---|---|---|
id | Uuid | yes | |
name | string | yes | |
format | "AP2" | yes | |
key_ids | array of string | yes | Ids of the keys registered by hand |
jwks_url | string or null | no |
Ap2ImportResult
| Property | Type | Required | Description |
|---|---|---|---|
mandate | Mandate | yes | |
report | object | yes |
Mandate
| Property | Type | Required | Description |
|---|---|---|---|
id | Uuid | yes | |
principal_id | Uuid | yes | |
agent_id | Uuid | yes | |
status | DRAFT, ACTIVE, SUSPENDED, REVOKED | yes | |
current_version | integer (minimum 1) | yes | The version in force (a DRAFT's current_version is the one activation will put in force) |
latest_version | integer (minimum 1) | yes | Highest version created; takes effect only when activated |
version | integer (minimum 1) | yes | The version whose body is returned |
source | NATIVE, AP2 | yes | |
body | MandateBody | yes |
BeneficiaryCreate
| Property | Type | Required | Description |
|---|---|---|---|
external_id | string (minLength 1, maxLength 100) | yes | The ID the agent sends in an authorize request; letters, digits and . _ : @ / - |
name | string (minLength 1, maxLength 200) | yes | |
iban | string (minLength 15, maxLength 42) | yes | Spaces and lowercase are accepted and normalised; the checksum is verified |
country | Country | yes | |
status | APPROVED, BLOCKED (default "APPROVED") | no |
BeneficiaryUpdate
| Property | Type | Required | Description |
|---|---|---|---|
name | string (minLength 1, maxLength 200) | no | |
iban | string (minLength 15, maxLength 42) | no | |
country | Country | no | |
status | APPROVED, BLOCKED | no |
Beneficiary
TemplateParams
Which rules the generated Cedar contains. The mandate's own limits, scope and threshold are facts in the Cedar context; the template only chooses which rules apply. Omitted properties take their default.
| Property | Type | Required | Description |
|---|---|---|---|
scope | boolean (default true) | no | permit requires debtor account, currency, beneficiary country and payment type inside the mandate scope |
per_transaction_limit | boolean (default true) | no | |
daily_limit | boolean (default true) | no | |
monthly_limit | boolean (default true) | no | |
approval_threshold | boolean (default true) | no | forbid with approval when the amount exceeds the mandate's threshold |
beneficiary_allowlist | boolean (default true) | no | forbid with approval when the beneficiary is not on the allowlist |
blocked_beneficiary | boolean (default true) | no | Hard deny for an explicitly blocked beneficiary; never payable by approval |
iban_mismatch | boolean (default true) | no | forbid with approval when an allowlisted beneficiary's IBAN differs |
risk_signals | array of string (maxItems 20, default ["prompt_injection_suspected"]) | no | Agent-reported risk flags that escalate to approval. Empty turns the rule off. Signals only ever tighten. |
PolicyCreate
One of: any or any
| Property | Type | Required | Description |
|---|---|---|---|
template_params | TemplateParams | no | |
cedar | string (maxLength 65536) | no | Raw Cedar. Validated against the Cedar schema; context.signals is rejected in permit rules. |
PolicyVersion
| Property | Type | Required | Description |
|---|---|---|---|
id | Uuid | no | |
version | integer (minimum 1) | yes | |
status | DRAFT, ACTIVE, RETIRED | yes | |
cedar | string | yes | |
cedar_sha256 | string | yes | Hex |
template_params | TemplateParams or null | no | |
published_at | string or null, date-time | no |
EvidenceRow
| Property | Type | Required | Description |
|---|---|---|---|
seq | integer (minimum 1) | yes | |
event_type | string | yes | |
subject_id | Uuid | yes | |
payload | object | yes | RFC 8785 canonicalised before hashing |
prev_hash | string | yes | Hex |
hash | string | yes | Hex |
jws | string | yes | |
key_version | integer | yes | |
created_at | string, date-time | yes |
EvidenceBundle
Everything needed to verify a range of evidence offline (cli/verify or the console verifier): rows with canonical payloads, hashes and signatures, all public keys, and the authorization artifacts issued for the decisions in the range. A range that does not start at row 1 verifies internally; its first row's prev_hash is the anchor to compare with the previous row you hold.
| Property | Type | Required | Description |
|---|---|---|---|
format | "polivor.evidence-bundle/v1" | yes | |
tenant_id | Uuid | yes | |
exported_at | string, date-time | yes | |
from_seq | integer (minimum 0) | yes | |
to_seq | integer (minimum 0) | yes | |
rows | array of EvidenceRow | yes | |
jwks | Jwks | yes | |
authorizations | array of object | yes |
Jwk
| Property | Type | Required | Description |
|---|---|---|---|
kty | "OKP" | yes | |
crv | "Ed25519" | yes | |
x | string | yes | |
kid | string | yes | |
alg | "EdDSA" | no | |
use | authz, evidence | yes | |
revoked_at | string or null, date-time | no |
Jwks
| Property | Type | Required | Description |
|---|---|---|---|
keys | array of Jwk | yes |
ApiKeyCreate
agent_id is required if and only if role is agent
| Property | Type | Required | Description |
|---|---|---|---|
role | admin, agent, enforcer | yes | |
agent_id | Uuid | no |
ApiKey
| Property | Type | Required | Description |
|---|---|---|---|
id | Uuid | yes | |
role | admin, agent, enforcer | yes | |
agent_id | string or null | no | |
prefix | string | yes | The non-secret part (pv_test_ |
created_at | string, date-time | yes | |
revoked_at | string or null, date-time | no |
ApiKeyCreated
| Property | Type | Required | Description |
|---|---|---|---|
id | Uuid | yes | |
role | admin, agent, enforcer | yes | |
key | string | yes | Plaintext |