Skip to Content
Extraction and verificationRisk policy authoring

Author risk policies with JSON

The visual editor and API use the same JSON policy definition. An agent can prepare a definition, validate it, test synthetic scenarios, and hand the draft to a reviewer in the visual editor.

Discover the contract

GET /api/v1/risk/policy-schema returns schemaVersion, schema and a short explanation. The schema property is a JSON Schema document suitable for editor validation; its identifier is urn:korala:risk-policy:1.

Set schemaVersion: "1" in new definitions. This is the format version, not the revision of a customer’s policy. Older definitions without this property are interpreted as format version 1. Unsupported versions are rejected.

JSON Schema describes the shape, allowed operators and bounds. The server also checks relationships between fields, such as matching input types, increasing band thresholds and references to real workspace verification fields. Always call the validation endpoint before treating generated JSON as valid.

GET /api/v1/risk/verification-inputs lists the current workspace’s configured Korala fields in the credential’s environment. The response contains items and nextOffset. Pass a non-null nextOffset as ?offset=... to load the next page, even when items is empty: a page can contain workflows with no supported fields. Use the returned workflow ID, version timestamp, step index, step type and field in a native input binding. Copy its source into acceptedSources; use ageSource when you set the age_years transform. These source IDs bind the exact workflow version, field and transform. Do not invent workflow IDs or use another workspace’s bindings. External input keys are defined by your integration; its authenticated API key is the source.

Validate without saving

POST /api/v1/risk/policies/validate Content-Type: application/json { "definition": { "schemaVersion": "1", "inputs": [], "factors": [], "bands": [] } }

The deliberately incomplete definition above returns valid: false and an errors array. Each error has a path and message. Structural errors identify a JSON Pointer; relationship checks may identify the whole definition or its inputs. Valid responses include the normalized definition, including defaults.

Validation creates no policy version. It requires authentication but no idempotency key. Native bindings are checked against the authenticated workspace and test/live environment. A changed workflow requires selecting its field again.

Simulate synthetic scenarios

POST /api/v1/risk/policies/simulate accepts the definition and up to 20 scenarios:

// `definition` is the policy JSON you want to test. const validation = await client.risk.validatePolicy({ definition }); if (!validation.valid || !validation.definition) { throw new Error(JSON.stringify(validation.errors)); } const simulation = await client.risk.simulatePolicy({ definition: validation.definition, scenarios: [{ name: 'Missing evidence', at: '2026-01-01T12:00:00Z', observations: [], }], });

Each scenario provides a fixed evaluation time and at most 200 observations. An observation contains fact, source, status, value, and observedAt; receivedAt and expiresAt are optional. Accepted statuses are available, unavailable and revoked. A boolean false is evidence; absent evidence is not. Supply only the latest receipt for each fact/source pair, as selected evidence would be supplied to a saved assessment. Duplicate pairs are rejected; use separate scenarios to simulate successive receipts or revocation.

The response has simulation: true. Each scenario includes applicability and an evaluation explaining input selection, missing evidence, factor contributions, matched rules, band, decision and requested action keys. Evaluate applicability alongside the result: a policy that does not apply must not authorize an action.

Simulation uses the same evaluator as saved assessments, but only on the supplied synthetic observations. It does not read a customer’s evidence, invoke verification providers, save assessments, create action requests, or send webhooks. Source strings in a simulation are hypothetical, not authenticated proof. These results must never be used to authorize customer activity.

Review and publish

Use Edit policy JSON in the policy editor to paste or copy a definition. Validate and apply updates the visual editor without saving or publishing. The setup order is Inputs, Risk bands, Scoring, Rules, Freshness, Review.

POST /api/v1/risk/policies saves a draft; publication remains a separate request to POST /api/v1/risk/policies/{id}/publish. Both require an owner/admin dashboard JWT and an idempotency key. API keys can discover, validate and simulate policies; they cannot create or publish policies. These endpoints do not add OAuth/MCP permissions: assistant access remains governed by the assistant scope policy.

The TypeScript client exposes risk.policySchema(), risk.verificationInputs(), risk.validatePolicy({ definition }) and risk.simulatePolicy({ definition, scenarios }). Use the existing draft and publication methods for governance. Test credentials remain confined to test mode.

Last updated on