---
slug: developer-api-actions-approvals
title: Messages, actions, and approvals
category: capability
status: published
tags: [approval, required action, action version, approve, reject, message, 审批, 决策, 版本冲突]
aliases: []
lastEditAt: 2026-08-02
---
## Add input while work is open

```bash
curl -sS https://tycoon.us/api/public/tasks/cm.../messages \
  -H "Authorization: Bearer $TYCOON_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: launch-research-followup-1" \
  -d '{"message":"Prioritize competitors selling to teams under 50 people."}'
```

`message` is required and limited to 20,000 characters. The first accepted
response is `202`. A same-body replay is `200` and does not create another
Comment or wake. A message to a terminal Task returns `409`.

## Resolve a required action from your backend

When `GET /tasks/{id}` or a `task.requires_action` webhook returns an action
with `api_resolvable: true`, resolve that exact version through the canonical
ApprovalRequest owner:

```bash
curl -sS https://tycoon.us/api/public/tasks/cm.../actions/apr.../resolve \
  -H "Authorization: Bearer $TYCOON_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: organic-growth-decision-1" \
  -d '{
    "action": "approve",
    "action_version": 7,
    "answers": [{
      "item_id": "cm...::q1",
      "value": "Technical SEO"
    }]
  }'
```

An accepted first decision returns `202`; a same-body replay returns `200`:

```json
{
  "task_id": "cm...",
  "approval_id": "apr...",
  "accepted": true,
  "status": "approved",
  "idempotent_replay": false
}
```

Use `action: "reject"` with no selection or answers to reject. For a choice or
free-text question, include one `answers` entry for each required item. A
choice that disallows custom input accepts only the safe option labels returned
by `GET`; use `selected_item_ids` for itemized approve/confirm decisions. The
client must send the current `action_version`: if the request was changed or
settled concurrently, Tycoon returns `409` and the caller should fetch the
Task again. The endpoint records the same canonical decision, action effects,
and durable wake as the authenticated app; it does not reveal its hidden
execution state.

An action with `api_resolvable: false` needs that interactive safe flow (for
example, encrypted browser credential entry) and cannot be bypassed by an API
key — follow the authenticated `action_url` in those cases. The endpoint does
not accept credentials. Actions raised by hidden child execution are projected
on the root Task, so callers do not need access to the child graph.

## Next steps

- [Webhooks](/help/developer-api-webhooks)
- [Idempotency, retries, errors, and limits](/help/developer-api-reliability-errors)
