`POST /v1/orgs/{org}/proposals/{proposal_id}/approve`.
const url = 'https://api.updawg.net/v1/orgs/example/proposals/example/approve';const options = {method: 'POST'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.updawg.net/v1/orgs/example/proposals/example/approveTakes no body. The design document has this endpoint carrying an optional schedule and rollout override; the rollout override belongs to epic 09 and has nowhere to go today, and inventing a field that is accepted and ignored is worse than not having one.
The schedule half arrived with DAWG-92 and is not a field either, because
it is not the approver’s to choose: a proposal whose rule says
apply: asap_in_window and whose window is shut comes back scheduled,
with scheduled_for saying when it opens. Approving is agreeing to the
change, not to the hour.
Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Organization slug.
The prp_… id.
Responses
Section titled “Responses”Where it is now. scheduled with a scheduled_for when the rule wants a maintenance window — approving is agreeing to the change, not to the hour.
The body every one of the three answers with.
Named for what it is rather than for the endpoint, because all three return it and a portal that has just clicked a button wants the same three facts whichever button it was: where the proposal is now, and how the approval count stands.
object
Distinct people who have approved. A rejected proposal keeps the count it had: it is a record of who had agreed before somebody said no.
How many more approvals this needs before it can go ahead.
Zero once there are enough, and zero once there is nothing left to go
ahead with — see [ok].
What the policy asked for, via proposals.required_approvals.
When a proposal that is scheduled may start (DAWG-92).
Present only on that status, and omitted rather than null everywhere else: it is not “unknown”, it is “does not apply”, and a portal that renders a date field will render something for a null.
Examplegenerated
{ "approvals": 1, "id": "example", "outstanding": 1, "required": 1, "scheduled_for": "2026-04-15T12:00:00Z", "status": "example"}No session.
object
Examplegenerated
{ "detail": "example", "status": 1, "title": "example", "type": "example"}Not permitted for this role.
object
Examplegenerated
{ "detail": "example", "status": 1, "title": "example", "type": "example"}No such proposal here.
object
Examplegenerated
{ "detail": "example", "status": 1, "title": "example", "type": "example"}Already approved by you, no longer yours to decide, or its current preflight fails on a host (preflight-failed, DAWG-153), or it is a release upgrade no agent carries out yet: anything but Debian (not-executable).
object
Examplegenerated
{ "detail": "example", "status": 1, "title": "example", "type": "example"}Over the organization’s request limit. Retry-After says when to try again; RateLimit-Limit is the burst.
object
Examplegenerated
{ "detail": "example", "status": 1, "title": "example", "type": "example"}