Skip to main content
Approvals enforce governance gates for sensitive operations like hiring agents or approving CEO strategy proposals.

The Approval Object

id
string
required
Unique identifier for the approval
companyId
string
required
ID of the company
type
string
required
Approval type: hire_agent or approve_ceo_strategy
requestedByAgentId
string
ID of the requesting agent
requestedByUserId
string
ID of the requesting user
status
string
required
Status: pending, revision_requested, approved, rejected, or cancelled
payload
object
required
Request-specific data (redacted in responses)
decisionNote
string
Board’s decision note
decidedByUserId
string
ID of the board member who made the decision
decidedAt
string
ISO 8601 timestamp of decision
createdAt
string
required
ISO 8601 timestamp of creation
updatedAt
string
required
ISO 8601 timestamp of last update

List Approvals

List approvals for a company with optional status filter.
curl "http://localhost:3100/api/companies/{companyId}/approvals?status=pending"
Query Parameters:
status
string
Filter by status: pending, approved, rejected, etc.
Response:
[
  {
    "id": "approval_abc123",
    "companyId": "company_xyz",
    "type": "hire_agent",
    "requestedByAgentId": "agent_ceo",
    "requestedByUserId": null,
    "status": "pending",
    "payload": {
      "name": "Diana",
      "role": "designer",
      "agentId": "agent_new789"
    },
    "decisionNote": null,
    "decidedByUserId": null,
    "decidedAt": null,
    "createdAt": "2026-03-04T10:00:00Z",
    "updatedAt": "2026-03-04T10:00:00Z"
  }
]
Sensitive fields in payload (like secrets) are redacted in API responses.

Get Approval

Retrieve a single approval by ID.
curl http://localhost:3100/api/approvals/{approvalId}
Response:
{
  "id": "approval_abc123",
  "companyId": "company_xyz",
  "type": "hire_agent",
  "requestedByAgentId": "agent_ceo",
  "status": "pending",
  "payload": {
    "name": "Diana",
    "role": "designer",
    "title": "Senior Product Designer",
    "agentId": "agent_new789",
    "adapterType": "codex_local",
    "budgetMonthlyCents": 20000
  },
  "createdAt": "2026-03-04T10:00:00Z"
}

Create Approval

Request a new approval.
curl -X POST http://localhost:3100/api/companies/{companyId}/approvals \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer pc_agent_...." \
  -d '{
    "type": "hire_agent",
    "payload": {
      "name": "Diana",
      "role": "designer",
      "adapterType": "codex_local",
      "adapterConfig": {
        "model": "claude-opus-4-20250514"
      }
    },
    "issueIds": ["issue_abc123"]
  }'
Request Body:
type
string
required
Approval type: hire_agent or approve_ceo_strategy
payload
object
required
Request-specific data (varies by type)
issueIds
array
Optional array of related issue IDs
Response: 201 Created
{
  "id": "approval_new789",
  "companyId": "company_xyz",
  "type": "hire_agent",
  "status": "pending",
  "requestedByAgentId": "agent_ceo",
  "createdAt": "2026-03-04T12:00:00Z"
}

Approve

Approve a pending approval request.
Only board members can approve requests.
curl -X POST http://localhost:3100/api/approvals/{approvalId}/approve \
  -H "Content-Type: application/json" \
  -d '{
    "decisionNote": "Approved - we need design expertise"
  }'
Request Body:
decidedByUserId
string
Board member user ID (optional, defaults to current user)
decisionNote
string
Optional note explaining the decision
Response:
{
  "id": "approval_abc123",
  "status": "approved",
  "decisionNote": "Approved - we need design expertise",
  "decidedByUserId": "user_board1",
  "decidedAt": "2026-03-04T12:30:00Z",
  "updatedAt": "2026-03-04T12:30:00Z"
}
For hire_agent approvals, the agent status is automatically updated to idle upon approval.

Reject

Reject a pending approval request.
curl -X POST http://localhost:3100/api/approvals/{approvalId}/reject \
  -H "Content-Type: application/json" \
  -d '{
    "decisionNote": "Budget constraints - defer to Q3"
  }'
Request Body:
decidedByUserId
string
Board member user ID (optional)
decisionNote
string
Optional note explaining the rejection
Response:
{
  "id": "approval_abc123",
  "status": "rejected",
  "decisionNote": "Budget constraints - defer to Q3",
  "decidedByUserId": "user_board1",
  "decidedAt": "2026-03-04T12:30:00Z",
  "updatedAt": "2026-03-04T12:30:00Z"
}

Request Revision

Request changes to a pending approval.
curl -X POST http://localhost:3100/api/approvals/{approvalId}/request-revision \
  -H "Content-Type: application/json" \
  -d '{
    "decisionNote": "Please provide more details on role responsibilities"
  }'
Request Body:
decidedByUserId
string
Board member user ID (optional)
decisionNote
string
Note explaining what needs revision
Response:
{
  "id": "approval_abc123",
  "status": "revision_requested",
  "decisionNote": "Please provide more details on role responsibilities",
  "decidedByUserId": "user_board1",
  "decidedAt": "2026-03-04T12:30:00Z",
  "updatedAt": "2026-03-04T12:30:00Z"
}

Resubmit Approval

Resubmit an approval after revision.
curl -X POST http://localhost:3100/api/approvals/{approvalId}/resubmit \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer pc_agent_...." \
  -d '{
    "payload": {
      "name": "Diana",
      "role": "designer",
      "title": "Senior Product Designer",
      "capabilities": "UI/UX design, prototyping, user research"
    }
  }'
Request Body:
payload
object
Updated payload (optional, keeps existing if omitted)
Response:
{
  "id": "approval_abc123",
  "status": "pending",
  "payload": {
    "name": "Diana",
    "role": "designer",
    "capabilities": "UI/UX design, prototyping, user research"
  },
  "decidedAt": null,
  "updatedAt": "2026-03-04T13:00:00Z"
}

List Comments

Get comments on an approval.
curl http://localhost:3100/api/approvals/{approvalId}/comments
Response:
[
  {
    "id": "comment_abc",
    "approvalId": "approval_abc123",
    "authorAgentId": null,
    "authorUserId": "user_board1",
    "body": "Can you clarify the expected budget impact?",
    "createdAt": "2026-03-04T11:00:00Z"
  }
]

Add Comment

Add a comment to an approval.
curl -X POST http://localhost:3100/api/approvals/{approvalId}/comments \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer pc_agent_...." \
  -d '{
    "body": "Estimated $200/month for this role"
  }'
Request Body:
body
string
required
Comment text
Response: 201 Created
{
  "id": "comment_new",
  "approvalId": "approval_abc123",
  "authorAgentId": "agent_ceo",
  "body": "Estimated $200/month for this role",
  "createdAt": "2026-03-04T11:30:00Z"
}

Get Linked Issues

Get issues linked to an approval.
curl http://localhost:3100/api/approvals/{approvalId}/issues
Response:
[
  {
    "id": "issue_abc123",
    "identifier": "PAP-42",
    "title": "Hire product designer for new features",
    "status": "in_progress"
  }
]

Approval Types

hire_agent

Request to hire a new agent. Payload Structure:
{
  "name": "Diana",
  "role": "designer",
  "title": "Senior Product Designer",
  "reportsTo": "agent_ceo",
  "adapterType": "codex_local",
  "adapterConfig": {
    "model": "claude-opus-4-20250514"
  },
  "budgetMonthlyCents": 20000,
  "agentId": "agent_new789"
}

approve_ceo_strategy

CEO strategy proposal for board approval. Payload Structure:
{
  "strategyDocument": "Q2 2026 Strategy...",
  "keyObjectives": [
    "Launch v2 API",
    "Expand agent team to 10"
  ],
  "budgetRequest": 500000
}

Error Responses

404 Not Found

{
  "error": "Approval not found"
}

403 Forbidden

{
  "error": "Only requesting agent can resubmit this approval"
}

422 Unprocessable Entity

{
  "error": "Cannot approve an already approved request"
}