Proposals
Approve a proposal, optionally promoting it to a new version
POST /v1/proposals/{id}/approve: Approve a proposal, optionally promoting it to a new version
POST /v1/proposals/{id}/approve
| Operation id | approveProposal |
| Key scope | run: keys that run jobs (and admin keys) |
| Section | Proposals |
#Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | pattern ^prp_[0-9a-hjkmnp-tv-z]{26}$ |
#Request body
| Field | Type | Required | Description |
|---|---|---|---|
promote | boolean | default false | |
remember | "none", "site" | default "none" | |
notes | string | max length 1000 |
#Example request
curl -X POST "https://api.kaab.ist/v1/proposals/{id}/approve" \
-H "Authorization: Bearer $KAAB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"promote":true,"remember":"site","notes":"verified against the snapshot"}'
#Responses
#200
Proposal
{
"id": "prp_01j9zqk3q7m4n5p6r7s8t9v0wx",
"object": "proposal",
"kind": "relocate",
"status": "pending",
"program": {
"id": "prg_01j9zqk3q7m4n5p6r7s8t9v0wx",
"name": "acme-report",
"version": 3,
"version_id": "pv_01j9zqk3q7m4n5p6r7s8t9v0wx"
},
"job_id": "job_01j9zqk3q7m4n5p6r7s8t9v0wx",
"target": "extract.rows[].amount",
"confidence": 0.91,
"source": "heuristic",
"payload": {
"old": {
"selector": "td:nth-child(3)"
},
"new": {
"candidates": [
{
"css": "td[data-col=amount]"
}
]
},
"samples": {
"old": "1.250,00",
"new": "1.250,00"
}
},
"created_at": "2026-09-18T10:00:00Z",
"expires_at": "2026-09-25T10:00:00Z",
"decided_at": null,
"decision": null
}
#Errors
Every error answers with the error envelope; its code is one of the error codes.
| Status | When |
|---|---|
| 400 | request_invalid: request validation failed |
| 401 | Missing or invalid API key |
| 402 | insufficient_credits: top up to continue |
| 403 | The key's scope does not cover this operation |
| 404 | Resource not found |
| 409 | Conflicting state (see error.code) |
| 422 | Semantically invalid request (see error.code) |
| 429 | Rate limited; see Retry-After |
| 500 | internal: unexpected server error |