Skip to content

Save the KYC policy editor draft for a programme and flow

PUT/v1/kyc/policy/draft

Requires an API client bearer token.

Upserts the SCRATCH policy-editor draft for a (tenant, mode, programme, flow) — no policy version is minted and no audit trail records draft activity; only `PolicyDraftStore`'s own row is upserted in place. Idempotent by overwrite (no Idempotency-Key required). Validation runs BEFORE the draft is stored, using the same compose-layer codes `POST /v1/kyc/policy` uses (`eligibility_rules_owned`, `unknown_detail_field`, `field_in_both_lists`, `invalid_rule`, `invalid_field_config`), plus `unknown_flow` for a `flow_key` naming no flow and `flow_archived` for one naming a retired flow — an invalid draft is never saved. One pair is judged only at publish: a nationality dropdown offering no nationality `rules.allowed_nationalities` accepts (400 `invalid_field_config`), because either half may carry forward from an active policy that moved after the draft was saved. The response includes `composed`/`flow`, a live preview of exactly what publishing this draft would mint against the current active policy. Send `expect_updated_at` (the `updated_at` you last saw) for optimistic concurrency: if the draft changed in another session since then the save is refused with 409 `draft_conflict`, whose body carries the CURRENT draft in `draft` (or `null` if it was discarded) so you can reload or overwrite deliberately. Omit it to keep the last-write-wins behaviour. Requires the programme_admin role.

Request body

programme_idstring (uuid)required
flow_keystring
definitionobjectrequired
+ show properties
required_signalsarray of stringrequired
selfie_capture"any" | "controlled_only"
accepted_document_typesarray of "passport" | "national_id" | "residence_permit" | "driving_licence"
step_orderarray of "details" | "document" | "selfie"
required_fieldsarray of string
optional_fieldsarray of string
field_orderarray of string
field_configobject
+ show properties

No properties.

rulesobject | null
+ show properties
min_ageinteger
allowed_nationalitiesarray of string
expect_updated_atstring (date-time)

Example

curl -X PUT https://api.rigid.fi/v1/kyc/policy/draft \
  -H "Authorization: Bearer $RIGID_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "programme_id": "uuid",
  "definition": {
    "required_signals": [
      "string"
    ]
  }
}'

Responses

200

The saved draft, composed against the current active policy.

programme_idstringrequired
flow_keystringrequired
definitionobjectrequired
+ show properties
required_signalsarray of stringrequired
selfie_capture"any" | "controlled_only"
accepted_document_typesarray of "passport" | "national_id" | "residence_permit" | "driving_licence"
step_orderarray of "details" | "document" | "selfie"
required_fieldsarray of string
optional_fieldsarray of string
field_orderarray of string
field_configobject
+ show properties

No properties.

rulesobject | null
+ show properties
min_ageinteger
allowed_nationalitiesarray of string
base_versionintegerrequired
latest_versionintegerrequired
updated_atstringrequired
composedobjectrequired
+ show properties
required_inputsarray of stringrequired
required_signalsarray of stringrequired
bandsobjectrequired
+ show properties
approve_at_or_abovenumberrequired
reject_belownumberrequired
weightsobjectrequired
+ show properties

No properties.

provenance_weightsobject
+ show properties
face_matchobjectrequired
+ show properties
controllednumberrequired
submittednumberrequired
selfie_capture"any" | "controlled_only"
accepted_document_typesarray of "passport" | "national_id" | "residence_permit" | "driving_licence"
refer_onarray of stringrequired
reject_onarray of stringrequired
ttl_secondsintegerrequired
retention_secondsintegerrequired
step_orderarray of "details" | "document" | "selfie"
required_fieldsarray of string
optional_fieldsarray of string
field_orderarray of string
field_configobject
+ show properties

No properties.

rulesobject
+ show properties
min_ageinteger
allowed_nationalitiesarray of string
flowobjectrequired
+ show properties
stepsarray of "details" | "document" | "selfie"required
fieldsarray of objectrequired
+ show properties
keystringrequired
requiredbooleanrequired
locked_byarray of string
input"text" | "dropdown" | "date"
hintstring
optionsarray of object
+ show properties
valuestringrequired
labelstring
rulesobjectrequired
+ show properties
min_ageinteger
allowed_nationalitiesarray of string
capabilitiesobjectrequired
+ show properties
controlled_capturebooleanrequired
document_extractionbooleanrequired
400

Validation error

typestringrequired
titlestringrequired
statusintegerrequired
detailstring
instancestring
401

Authentication required

typestringrequired
titlestringrequired
statusintegerrequired
detailstring
instancestring
403

Forbidden

typestringrequired
titlestringrequired
statusintegerrequired
detailstring
instancestring
409

The draft changed in another session since `expect_updated_at` (code `draft_conflict`; the body carries the current draft in `draft`, or `null` if it was discarded). On this path `draft.composed`/`draft.flow` may be absent — if the stored draft can no longer be composed the preview is omitted rather than the conflict being reported as something else

typestringrequired
titlestringrequired
statusintegerrequired
detailstring
instancestring
500

Internal server error

typestringrequired
titlestringrequired
statusintegerrequired
detailstring
instancestring