Edit a policy: open its edit draft
POST/api/public/v1/policies/{public_id}/edit
Opens the next version of the AIP as its edit draft, on the same row and under the AIP's own public id: each ratified intent policy of the version named by version (default the current one) is copied in confirmed and grounded again from its stored sentence, its stored answers recommended; the AIP's zones and its strictest attachment mode are copied onto the draft. 202 with the grounding job ({public_id, job_id}); the draft is read with GET /aip/drafts/{public_id}. 200 with the draft when the caller already holds the open draft version. The live AIP keeps enforcing until the edit draft is ratified. 409 DRAFT_EXISTS names the holder in details[] (held_by).
curl --fail-with-body -X POST 'https://app.openlatch.ai/api/public/v1/policies/<policy_public_id>/edit' \ -H "Authorization: Bearer $OPENLATCH_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"version":1}'import jsonimport osimport urllib.request
body = '{"version":1}'request = urllib.request.Request( 'https://app.openlatch.ai/api/public/v1/policies/<policy_public_id>/edit', method='POST', data=body.encode(), headers={ 'Authorization': 'Bearer ' + os.environ['OPENLATCH_API_KEY'], 'Content-Type': 'application/json', },)with urllib.request.urlopen(request) as response: text = response.read().decode() print(json.dumps(json.loads(text), indent=2) if text else response.status)#!/usr/bin/env bashset -euo pipefail
curl -sS --fail-with-body -X POST 'https://app.openlatch.ai/api/public/v1/policies/<policy_public_id>/edit' \ -H "Authorization: Bearer $OPENLATCH_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"version":1}' | jq .$headers = @{ Authorization = "Bearer $env:OPENLATCH_API_KEY"}$body = '{"version":1}'Invoke-RestMethod -Method POST -Uri 'https://app.openlatch.ai/api/public/v1/policies/<policy_public_id>/edit' -Headers $headers -ContentType 'application/json; charset=utf-8' -Body $body | ConvertTo-Json -Depth 20Autorisation
Section intitulée « Autorisation »| Rôle dans l’organisation | Ce point de terminaison |
|---|---|
owner | Autorisé |
admin | Autorisé |
editor | Autorisé |
viewer | Non autorisé |
Une clé porte le rôle que son propriétaire détient dans l’organisation. Voir Authentification.
Portée de clé d’API : policies:write
Paramètres de chemin
Section intitulée « Paramètres de chemin »| Paramètre | Type | Description |
|---|---|---|
public_id | string | Obligatoire. |
Paramètres d’en-tête
Section intitulée « Paramètres d’en-tête »| Paramètre | Type | Description |
|---|---|---|
Idempotency-Key | string or null | Optional. Makes this request safe to retry. Depending on the request, the same key with the same request either joins the job the first one queued (409 JOB_ALREADY_EXISTS, the job id in details) or replays the first answer (Idempotent-Replayed: true; 409 IDEMPOTENCY_IN_PROGRESS while it runs). The same key with another request is 422 IDEMPOTENCY_KEY_REUSED. |
Corps de la requête
Section intitulée « Corps de la requête »| Champ | Type | Description |
|---|---|---|
version | integer or null |
- 200 OK — l’appel a réussi.
- 202 Accepted — l’appel a réussi.
- 400 Bad Request —
BAD_REQUEST - 401 Unauthorized —
UNAUTHORIZED - 402 Payment Required —
license_expired - 403 Forbidden —
FEATURE_DISABLED,FORBIDDEN,INSUFFICIENT_SCOPE - 404 Not Found —
NOT_FOUND - 409 Conflict —
AI_NOT_ENABLED,DRAFT_EXISTS,JOB_ALREADY_EXISTS,NOT_RATIFIED - 422 Unprocessable Content —
IDEMPOTENCY_KEY_REUSED,INVALID_ID,UNKNOWN_VERSION,VALIDATION_ERROR - 429 Too Many Requests —
TOO_MANY_REQUESTS - 500 Internal Server Error —
INTERNAL_SERVER_ERROR,tenant_isolation_violation - 503 Service Unavailable —
FEATURE_STATE_UNAVAILABLE,SERVICE_UNAVAILABLE
Champs de la réponse
Section intitulée « Champs de la réponse »| Champ | Type | Description |
|---|---|---|
data | object | Obligatoire. One draft: its intent policies, revision, zones, mode, preparation, replay and, for an edit draft, the live version it was opened from. |
data.ask_behaviour_override | string — one of pass_and_review, hold_until_validated or null | The AIP's own Ask behaviour ratify gives it; null follows the Autonomy Zone. |
data.ask_mode_override | string — one of platform, agent, both or null | The AIP's own Ask delivery ratify gives it; null follows the Autonomy Zone. |
data.edit_of | object or null | |
data.edit_of.version | integer | Obligatoire. |
data.from_framework_preset | boolean | Obligatoire. True when an intent policy of the draft holds a framework citation, edit drafts included. |
data.intent_policies | array of object | Obligatoire. |
data.intent_policies[].busy | object or null | What runs on the intent policy: grounding, cases (its stored cases checked again), fix, or topping_up (cases written for the values an answer added, appended when ready; it blocks nothing). |
data.intent_policies[].capability | object or null | |
data.intent_policies[].cards | array of object | Obligatoire. |
data.intent_policies[].cases | array of object | Obligatoire. |
data.intent_policies[].citation | object or null | Obligatoire. The framework preset rule this intent policy came from, edited when its sentence differs; null for anything not drawn from a framework preset. |
data.intent_policies[].confirmed | object or null | |
data.intent_policies[].deferred | object or null | The deferred part's gap class and fallback; null when it has none. |
data.intent_policies[].dimension | string — one of quality, economics, security, safety, compliance | Obligatoire. |
data.intent_policies[].fallback | object or null | |
data.intent_policies[].fix | object or null | |
data.intent_policies[].id | string | Obligatoire. |
data.intent_policies[].job_id | object or null | |
data.intent_policies[].language | string | Obligatoire. |
data.intent_policies[].passage | object or null | |
data.intent_policies[].refusal | object or null | |
data.intent_policies[].request_rule | object or null | |
data.intent_policies[].sentence | string | Obligatoire. The intent policy. Empty while the drafting job still prepares it (busy is grounding and it holds no grounding yet): a sentence is served only once it is final. |
data.intent_policies[].steer | object or null | |
data.intent_policies[].validate | object or null | |
data.language | string | Obligatoire. |
data.mode | string — one of disabled, monitor, enforce or null | |
data.mode_advice | string or null | Obligatoire. The Monitor line on a draft newly made from a framework preset; null otherwise and on edit drafts. |
data.preparation | object | Obligatoire. |
data.preparation.error | object or null | |
data.preparation.remaining | array of string — one of ground, test, pack, replay | Obligatoire. |
data.preparation.revision | integer or null | |
data.preparation.state | string — one of idle, running, ready, failed | Obligatoire. |
data.preparation.steps_done | integer | Obligatoire. |
data.preparation.steps_total | integer | Obligatoire. |
data.public_id | string | Obligatoire. |
data.replay | object or null | |
data.replay.rows | array of object | |
data.replay.state | string — one of running, done, engine_unavailable, empty | Obligatoire. |
data.replay.summary | object or null | The replay's figures over all total rows; null while it runs. |
data.replay.total | integer | |
data.revision | integer | Obligatoire. |
data.source_kind | string | Obligatoire. |
data.unavailable_zones | array of object | |
data.unavailable_zones[].name | object or null | |
data.unavailable_zones[].reason | string — one of deleted, cannot_take_policy | Obligatoire. |
data.unavailable_zones[].since | object or null | |
data.unavailable_zones[].zone_id | string | Obligatoire. |
data.zone_ids | array of string | Obligatoire. |
Exemple de réponse
Section intitulée « Exemple de réponse »{ "data": { "ask_behaviour_override": "pass_and_review", "ask_mode_override": "platform", "edit_of": { "version": 3 }, "from_framework_preset": false, "intent_policies": [ { "busy": "string", "capability": "string", "cards": [ { "answer": {}, "key": "string", "kind": "dictionary_values", "question": "string", "recommended": {} } ], "cases": [ {} ], "citation": { "edited": false, "entries": [ {} ], "items": [ {} ], "license_url": "https://app.openlatch.ai/", "preset_key": "string", "preset_title": "string", "rule_id": "3f6c1a2e-8b4d-4c1f-9a7e-0d5b2c8e4f10", "source_commit": "string", "source_date": "string", "source_sentence": "string", "version": 1 }, "confirmed": false, "deferred": { "class": "string", "fallback": "Ask" }, "dimension": "quality", "fallback": "Ask", "fix": { "attempts_left": 3, "available": false, "diff": {}, "fix_id": "3f6c1a2e-8b4d-4c1f-9a7e-0d5b2c8e4f10", "reason": "Never push to main without a review.", "requested": false }, "id": "3f6c1a2e-8b4d-4c1f-9a7e-0d5b2c8e4f10", "job_id": "3f6c1a2e-8b4d-4c1f-9a7e-0d5b2c8e4f10", "language": "string", "passage": { "end": 3, "start": 3 }, "refusal": { "class": "nothing_observable", "reason": "Never push to main without a review." }, "request_rule": { "lever": "effort_clamp", "params": {} }, "sentence": "string", "steer": "string", "validate": { "example": "string", "fires_on_every_action": false, "never_fires": false } } ], "language": "string", "mode": "disabled", "mode_advice": "string", "preparation": { "error": { "code": "NOT_FOUND", "message": "Never push to main without a review." }, "remaining": [ "ground" ], "revision": 3, "state": "idle", "steps_done": 3, "steps_total": 3 }, "public_id": "3f6c1a2e-8b4d-4c1f-9a7e-0d5b2c8e4f10", "replay": { "rows": [ { "event_id": "evt_01jbwa2k1vfrn9y42xhgxhmzj2", "occurred_at": "2026-01-15T14:32:05Z", "platform": "string", "readable": false, "recorded_verdict": "string", "verdict": "string" } ], "state": "running", "summary": {}, "total": 0 }, "revision": 3, "source_kind": "string", "unavailable_zones": [ { "name": "release-bot", "reason": "deleted", "since": "2026-01-15T14:32:05Z", "zone_id": "3f6c1a2e-8b4d-4c1f-9a7e-0d5b2c8e4f10" } ], "zone_ids": [ "3f6c1a2e-8b4d-4c1f-9a7e-0d5b2c8e4f10" ] }}