Skip to content

Accept a learning proposal

POST/api/public/v1/learning-proposals/{public_id}/accept beta

Applies the proposal through its kind's own operation, with the input_digest the caller read. 409 PROPOSAL_STALE when its inputs moved since it opened (it is then superseded); 409 PROPOSAL_CLOSED when it is no longer open or has expired. A connected agent is refused 403 FORBIDDEN: a proposal is accepted by a person or an API key. The applied operation's own refusals (for example NOT_ATTACHED, INHERITED_HERE, INVALID_PATTERN, NOT_RATIFIED) leave the proposal open.

Terminal window
curl --fail-with-body -X POST 'https://app.openlatch.ai/api/public/v1/learning-proposals/<proposal_public_id>/accept' \
-H "Authorization: Bearer $OPENLATCH_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"input_digest":"<input_digest>"}'
Role in the organizationThis endpoint
ownerAllowed
adminAllowed
editorAllowed
viewerNot allowed

A key carries the role its owner holds in the organization. See Authentication.

API key scope: proposals:write

ParameterTypeDescription
public_idstringRequired.
ParameterTypeDescription
zone_idstring (uuid) or nullThe deciding zone: a proposal above it answers 404.
ParameterTypeDescription
Idempotency-Keystring or nullOptional. Makes the request safe to retry: the same key and the same request, within 24 hours, returns the stored response with Idempotent-Replayed: true and runs once.
FieldTypeDescription
input_digeststringRequired.
FieldTypeDescription
dataobjectRequired. One proposal: what would change, why, in which direction, and what was decided.
data.caseobject or null
data.case.action_lineobject or null
data.case.kindstringRequired.
data.case.outcome_todayobject or null
data.changedobject or null
data.changed.samplearray of object
data.changed.to_allowinteger
data.changed.to_askinteger
data.changed.to_blockinteger
data.decided_atstring (date-time) or null
data.decided_byobject or null
data.decided_by.kindstring — one of user, api_keyRequired.
data.decided_by.namestringRequired.
data.directionstring — one of tightens, neutral, widensRequired.
data.evidenceobject or null
data.evidence.actionobject or nullA regression case's reviewed action in plain words, scrubbed; null when a secret still matched.
data.expires_atstring (date-time)Required.
data.input_digeststringRequired.
data.intent_policyobject or null
data.intent_policy.idstringRequired.
data.intent_policy.sentencestringRequired.
data.kindstring — one of monitor_to_enforce, dictionary_value, decisive_declaration, regression_caseRequired.
data.opened_atstring (date-time)Required.
data.policyobject or null
data.policy.namestringRequired.
data.policy.public_idstringRequired.
data.policy.versionintegerRequired.
data.public_idstringRequired.
data.resultobject or null
data.statestring — one of open, accepted, dismissed, superseded, expiredRequired.
data.table_namestring or null
data.valuestring or null
data.zoneobject or null
data.zone.idstringRequired.
data.zone.namestringRequired.
{
"data": {
"case": {
"action_line": "string",
"kind": "string",
"outcome_today": "string"
},
"changed": {
"sample": [
{
"action": "string",
"action_line": "string",
"category": "string",
"decision_id": "3f6c1a2e-8b4d-4c1f-9a7e-0d5b2c8e4f10",
"occurred_at": "2026-01-15T14:32:05Z",
"verdict_after": "string",
"verdict_before": "string"
}
],
"to_allow": 0,
"to_ask": 0,
"to_block": 0
},
"decided_at": "2026-01-15T14:32:05Z",
"decided_by": {
"kind": "user",
"name": "release-bot"
},
"direction": "tightens",
"evidence": {
"action": "string"
},
"expires_at": "2026-01-15T14:32:05Z",
"input_digest": "string",
"intent_policy": {
"id": "3f6c1a2e-8b4d-4c1f-9a7e-0d5b2c8e4f10",
"sentence": "string"
},
"kind": "monitor_to_enforce",
"opened_at": "2026-01-15T14:32:05Z",
"policy": {
"name": "release-bot",
"public_id": "3f6c1a2e-8b4d-4c1f-9a7e-0d5b2c8e4f10",
"version": 3
},
"public_id": "3f6c1a2e-8b4d-4c1f-9a7e-0d5b2c8e4f10",
"result": {},
"state": "open",
"table_name": "release-bot",
"value": "string",
"zone": {
"id": "3f6c1a2e-8b4d-4c1f-9a7e-0d5b2c8e4f10",
"name": "release-bot"
}
}
}