---
title: "Stage an action proposal for the coach to approve"
method: POST
path: "/api/copilot/threads/{threadId}/actions"
tags: ["Copilot"]
---

# Stage an action proposal for the coach to approve

`POST /api/copilot/threads/{threadId}/actions`

## Request

- Base URL: `https://api.setluca.com`
- URL: `https://api.setluca.com/api/copilot/threads/{threadId}/actions`
- Auth: API key in cookie `luca.session_token`

Ask Luca's own call. It stores a plan of catalog operations with a card, a diff, and side effects. Nothing runs until the coach confirms. Only a copilot turn on this thread may call it, and a retry within the turn returns the first proposal.

**Session-only.** This endpoint isn't on the API-key allowlist. An organization API key gets a 403 here, whatever scopes it holds.

## Path parameters

- `threadId` string, uuid, required

## Headers

- `Luca-API-Version` '1'

## Request body

- CopilotProposalCreateRequest
  - `plan` union, required
    - object
      - `kind` 'steps', required
      - `steps` object[], required
        - `operationId` string, required
        - `input` unknown
    - object
      - `kind` 'batch', required
      - `operationId` string, required
      - `items` unknown[], required
        - unknown
  - `card` object, required
    - `title` string, required
    - `text` string, required
    - `fields` object[]
      - `name` string, required
      - `label` string, required
      - `kind` 'string' | 'text' | 'number' | 'enum' | 'list', required
      - `options` object[]
        - `value` string, required
        - `label` string, required
  - `diff` object[]
    - `label` string, required
    - `before` string
    - `after` string
    - `index` integer
  - `sideEffects` string[]
  - `clientKey` string

## Response `200`

ok

- CopilotProposal
  - `id` string, uuid, required
  - `threadId` string, uuid, required
  - `operationId` string, nullable, required
  - `planKind` string, nullable, required
  - `revision` integer, required
  - `payload` object, required
    - `steps` object[]
      - `operationId` string, required
      - `input` unknown
    - `items` unknown[]
      - unknown
  - `payloadHash` string, nullable, required
  - `diff` object[], required
    - `label` string, required
    - `before` string
    - `after` string
    - `index` integer
  - `sideEffects` string[], required
  - `card` object, required
    - `title` string, required
    - `text` string, required
    - `warning` string
    - `fields` object[]
      - `name` string, required
      - `label` string, required
      - `kind` 'string' | 'text' | 'number' | 'enum' | 'list', required
      - `options` object[]
        - `value` string, required
        - `label` string, required
      - `value` unknown
  - `outcomes` object[], required
    - `index` integer, required
    - `status` string, required
    - `httpStatus` integer, nullable, required
    - `message` string, nullable, required
    - `resultRef` string, nullable, required
    - `result` unknown
    - `resultOmitted` 'too_large': Set when a step that spends AI credits succeeded but its answer was too large to keep. Absent otherwise.
  - `status` string, required
  - `expiresAt` string, required
  - `stuck` boolean, required: The run ended short, failed, or stopped showing progress, so the coach may retry or discard it.
  - `toolName` string, nullable, required

## Other responses

- `400`: bad request
- `401`: unauthorized
- `403`: forbidden
- `404`: not found
- `409`: conflict
- `410`: gone
- `429`: rate limited
- `500`: internal error
- `503`: service unavailable

---

[API](https://skmtc.dev/setluca/apis/luca-api.md) · [All operations](https://skmtc.dev/setluca/apis/luca-api/llms.txt) · [OpenAPI document](https://skmtc.dev/setluca/apis/luca-api/revisions/90a200e4100b?raw)
