How do I approve or reject an agent's proposal in agent.ceo?
List your organization's pending proposals. Decide one as an admin, approve or reject. Then read it back and confirm the decision was kept. Run two checks that must fail next to it: a made-up ID, and an organization you do not belong to.
Where a human should decide at all is a design question, covered in where should a human approve in an AI agent workflow? This page is the mechanics.
The calls, in order
| # | Call | What you get |
|---|---|---|
| 1 | GET /api/v1/approvals?org_id=ORG&status=pending | Proposals waiting for a decision |
| 2 | GET /api/v1/approvals/ID | One proposal, with what it asks for |
| 3 | POST /api/v1/approvals/ID/reject?org_id=ORG (or /approve) | The decision |
| 4 | GET /api/v1/approvals/ID again | The proposal, with the decision kept |
Deciding requires an admin credential, and filing a proposal does not grant one. Keep that credential with a person, not with the agent that proposes.
1. See what is waiting
curl -s "https://api.agent.ceo/api/v1/approvals?org_id=$ORG&status=pending" \
-H "X-API-Key: $ADMIN_KEY"
Read what each proposal asks for before you decide. An approvals queue that is always empty is not proof of good behaviour. It is also what you see when nothing is being filed.
2 and 3. Decide
curl -s -X POST \
"https://api.agent.ceo/api/v1/approvals/$APPROVAL_ID/reject?org_id=$ORG" \
-H "X-API-Key: $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"actor_id": "your-admin-id"}'
Name yourself as the actor. "Who decided this?" should have an answer later that does not depend on memory.
4. Confirm the decision was kept
Read the proposal again. It should show the decision and when it was made. A decision you cannot read back is not a record.
Rendering diagram…
The checks that must fail
| Check | Expected |
|---|---|
| Decide a proposal ID you made up, after a real one worked | 404 |
| List pending approvals for an organization you are not a member of | Refused with 403, not an empty list |
| Reject the same proposal a second time | The original decision stays, with its original time |
The second row matters most. An empty list for an organization you cannot see looks exactly like "nothing pending". A check that accepts it cannot tell the two apart.
curl -s -o /dev/null -w "%{http_code}\n" -X POST \
"https://api.agent.ceo/api/v1/approvals/zz-fabricated-id/reject?org_id=$ORG" \
-H "X-API-Key: $ADMIN_KEY" \
-H "Content-Type: application/json" -d '{"actor_id": "your-admin-id"}'
# expect 404
What we checked
The reject path above is part of our Approvals journey on staging. A harmless proposal waits, an admin rejects it, and the decision is kept. A nonexistent ID returns 404 and a non-member is refused with 403. A repeated rejection leaves the original decision and time unchanged. The approve action uses the same route. Patterns for where these decisions belong in a larger agent graph are in human junction patterns for agent graphs.
FAQ
How do I approve or reject an agent's proposal in agent.ceo?
List your organization's pending approvals with GET /api/v1/approvals?org_id=ORG&status=pending, then decide one with POST /api/v1/approvals/ID/approve or /reject as an organization admin. Read the approval again afterwards and confirm the decision is kept on it.
What happens if I reject the same proposal twice?
The decision already made stays as it was. A second rejection is either refused or returns the same decision record with its original resolution time. It never creates a new decision with a new timestamp.
Who can decide an agent's proposal?
An organization admin. Deciding a proposal requires an admin credential, and filing a proposal does not grant one. Keep the admin credential with a person, so the agent that proposes and the person who decides stay separate.
Related: Who is accountable when an AI agent makes a mistake? · Agent catalog