Skip to Content
RiskEvidence sources

Risk evidence sources

You can use external facts and Korala verification results in a risk policy. Korala retains evidence from both paths. Each receipt identifies the source of the fact. You choose which sources your policy accepts and remain responsible for deciding whether their claims provide enough evidence.

All endpoints below are relative to /api/v1. See the risk API overview for authentication, subjects, idempotency and limits.

External and internal evidence

PathHow facts arriveSource identity
Registered external systemAn authorized API key submits a declared factregistered:<source-registration-id>
Native Korala verificationThe risk engine reads policy-selected fields from a linked sessionSource ID returned by the verification input catalog

You register sources for external systems. Native verification sources do not have a registration or sourceRegistrationId: select their source ID from the verification input catalog.

Register an external source

In the dashboard, open Risk → Sources, choose the test or live environment, then select Register source. Enter a source key, declare the facts it may submit and select its permitted API keys. Owners and administrators can register sources; other workspace members can inspect their configuration and history. Create API keys in Settings → API keys first. Korala does not display key secrets on the source page.

An organization owner/admin uses a dashboard JWT to register a source. An API key cannot create registrations or change their key bindings. For test resources, the JWT request includes X-Risk-Mode: test; otherwise it uses live mode.

POST /api/v1/risk/sources Authorization: Bearer <owner-or-admin-jwt> Idempotency-Key: register-purchase-system-001 Content-Type: application/json { "key": "purchase_system", "facts": [{ "key": "purchase.amount", "type": "number" }], "apiKeyIds": ["<active-api-key-id>"] }

Replace placeholders with your UUIDs. For apiKeyIds, use the id from the API-key record, rather than the keyId used in HMAC headers. Keys must belong to the same organization and test/live mode, and must not be revoked or expired. The source starts enabled. The response wraps the registration as { id, resource: "sources", data }. Use its id for submissions and registered:<id> for policy acceptance.

Declare 1–100 unique facts with type string, number, boolean or list. A list also requires a scalar itemType, for example { "key": "account.channels", "type": "list", "itemType": "string" }. Source and fact keys use lowercase letters, digits, underscores, dots and hyphens, start with a letter, and are at most 80 characters. The key and fact schema are immutable; register a new source to change them. A source binds at most 50 keys.

Submit a fact for a subject

Use a bound API key and the standard HMAC authentication. The subject must belong to that organization and environment.

POST /api/v1/risk/subjects/<subject-id>/evidence Idempotency-Key: purchase-123-amount Content-Type: application/json { "sourceRegistrationId": "<source-registration-id>", "fact": "purchase.amount", "status": "available", "value": 1000, "observedAt": "2026-10-10T12:00:00Z", "providerRef": "purchase-123" }

Use the observation time, which cannot be in the future. expiresAt is optional. An available value must match the registered fact type; lists must match their declared item type. unavailable and revoked require value: null. Keep structured payloads and document images in your evidence storage and use an opaque providerRef; Korala accepts scalar values and scalar lists here.

Korala retains the fact and assigns its source and submission history. Provenance records the registration ID, binding revision, submitting API key, adapter version and assertion evidence class. You cannot set this attribution by supplying source or provenance in the request.

The SDK exposes client.risk.addEvidence(subjectId, body, idempotencyKey). Repeat the same request with the same key to retry. A changed request or principal with the same key returns 409. A new receipt supersedes the previous receipt for that subject, fact and source; Korala retains the previous record.

Submit several facts together

Use a batch when an external system sends several properties for one subject, for example country, account age and email verification. Declare each property as a source fact first. Send 1–100 distinct facts from that source in one request:

POST /api/v1/risk/subjects/<subject-id>/evidence/batch Idempotency-Key: profile-123-revision-2 Content-Type: application/json { "sourceRegistrationId": "<source-registration-id>", "items": [ { "fact": "profile.country", "status": "available", "value": "US", "observedAt": "2026-10-10T12:00:00Z" }, { "fact": "profile.email_verified", "status": "available", "value": false, "observedAt": "2026-10-10T12:00:00Z" } ] }

Korala accepts the whole batch or rejects it without recording any of its facts. The response contains { id, subjectId, items }, with evidence receipts in request order. Each receipt keeps its own source attribution and history. A batch supports one subject and one source; use separate requests for others. The limit is 16 KiB per item and 256 KiB for the batch, measured as UTF-8 JSON.

Use client.risk.addEvidenceBatch(subjectId, body, idempotencyKey) in the SDK. Keep the same key, API credential and body when retrying, including item order. Korala returns the original batch ID and receipt IDs, even if another request has since replaced those facts. A different body or submitting credential with the same key returns 409. Send corrections with a new key. If Korala rejects an uncommitted batch, you can correct it and reuse the key.

Korala requests a refresh for enabled monitoring after accepting the batch. An assessment reads all the committed facts together; acceptance itself does not approve the subject. Subscribers can receive individual risk.evidence.recorded events and a risk.evidence.batch_recorded event. Webhook delivery may repeat or arrive out of order; follow the risk push integration guide when processing it.

Accept the source in a policy

Add an entry to your policy’s inputs array:

{ "key": "purchase.amount", "type": "number", "acceptedSources": ["registered:<source-registration-id>"], "maxAgeSeconds": 3600 }

Copy the exact lowercase source identity. You must update the policy to accept it after registration. Korala records submissions as assertions by that source; it does not verify the purchase or obtain an attestation from a provider. The risk engine checks types, availability, conflicting values and freshness.

Rotate keys, disable a source and inspect history

Open a source in Risk → Sources to replace its permitted keys or pause new submissions. During rotation, add the replacement key, switch your integration, then remove the old key. Saving replaces the selected keys. Pausing does not invalidate evidence or assessments already recorded.

If another administrator changes the permissions while you edit, reload the bindings before saving your changes. Reload bindings and discard edits reads the current configuration and discards your unsaved selection. The source page also shows a paginated history of registration and permissions changes.

Read GET /risk/sources/{id} to obtain its current revision, then replace the bindings using an owner/admin JWT and a new idempotency key:

{ "expectedRevision": 1, "apiKeyIds": ["<replacement-api-key-id>"], "enabled": true }

Send this body to POST /risk/sources/{id}/bindings. The key list replaces the whole list. A stale revision returns 409. To disable submissions, set enabled: false; a disabled source may have an empty key list. An enabled source must have at least one key.

You can rotate keys without changing the source identity or policy acceptance. Korala retains historical receipts. Disabling a source blocks new submissions; it does not revoke existing evidence. Korala returns the original receipt for an identical retry after rotation or disabling if the caller can authenticate. Korala refuses authentication with revoked or expired credentials.

List registrations through GET /risk/sources. Inspect binding history through GET /risk/events?resourceId=<source-registration-id>. Follow nextOffset for both lists. Korala records the complete bindings and revision in the audit feed on source creation and binding changes. The SDK provides createSource and updateSourceBindings for the corresponding governance calls.

Korala KYC and POA sessions

For native evidence, link the session to the risk subject and select verification fields from GET /risk/verification-inputs when authoring the policy. Copy the returned binding and source; do not submit the session results again as external evidence.

Korala collects the selected fields as risk evidence before assessment and policy selection, including automatic reassessment. It retains references to the originating session, workflow run and step. You can retrieve original results and document references through the session and workflow APIs; risk receipts exclude raw images and complete step outputs. It reuses unchanged observations and writes a new revision when an observation changes. You choose the fields to synchronize through the policy’s verification bindings.

Extraction and enrichment facts require explicit approval of the completed attempt or completed session. Supported completed capture, check, validate and risk outputs can inform risk while review is pending; they do not approve the identity. Missing, failed, stale or unsupported evidence cannot satisfy an input. A newer linked attempt cannot fall back to an older favorable result.

Source identity pins the workflow definition revision and interpretation, while receipt references identify the actual attempt. Selecting a new workflow revision requires a new policy binding. Session changes request refreshes for enabled monitoring; background reconciliation also checks for missed updates. Neither path promises instantaneous evaluation. Assessment snapshots preserve the exact evidence used for the historical result.

Last updated on