---
title: "Set Action Step Completion"
method: POST
path: "/actions/steps/completion"
tags: ["Actions"]
---

# Set Action Step Completion

`POST /actions/steps/completion`

## Request

- Base URL: `https://api.peec.ai/customer/v1`
- URL: `https://api.peec.ai/customer/v1/actions/steps/completion`
- Auth: one of:
  - API key in header `X-API-Key`
  - API key in query parameter `api_key`
  - HTTP bearer

Record which of an action's steps are done. Each entry names one action and either sets `completed` for every step it holds, or lists the steps to write; a step in turn either sets `completed` for all of its options or names them individually, each with its own value, so one call can tick some and untick others. An action is all or nothing: anything Peec cannot apply leaves every step on it untouched and comes back under `skipped` or `rejected`, so a partly-written action is never a state you have to read back. Other actions in the same call are unaffected. The action's own status is never changed by this endpoint, including when every step on it is complete. An action that is already deleted reads as absent unless the key is a platform admin one. A content optimisation is reachable only on a project with content optimisation enabled; elsewhere its id is returned in `skipped`.

## Request body

- object
  - `project_id` string: Required if using a company api key
  - `actions` object[], required
    - `action_id` string, uuid, required: The action the steps belong to. Name it once and list every step written on it, rather than repeating the action per step.
    - `completed` boolean: Sets every option the action holds. Naming steps is how to write part of an action, and is also the only form that fails loudly on a step id Peec has regenerated — setting the whole action applies to whatever it holds at the time of the write.
    - `steps` object[]
      - `step_id` string, required: A step id from the action detail read. Steps are addressed by id rather than by position, so an action Peec has since regenerated fails as `step_not_found` instead of writing the wrong work.
      - `completed` boolean: Sets every option in the step at once, which is what the step's own checkbox does.
      - `options` object[]: Sets named options individually, each with its own value, so one call can tick some and untick others.
        - `option_id` string, required: An option id from the action detail read.
        - `completed` boolean, required: `true` marks this option done, `false` puts it back.

## Response `200`

Per-item completion results

- object: Per-item completion results
  - `updated` object[], required
    - `action_id` string, required
  - `skipped` object[], required
    - `action_id` string, required
    - `reason` 'not_found', required
  - `rejected` object[], required
    - `action_id` string, required
    - `reason` 'step_not_found' | 'option_not_found' | 'duplicate_id' | 'duplicate_step_id' | 'not_completable', required: `step_not_found` and `option_not_found` name a step or option the action does not hold — usually an id from before Peec regenerated it. `duplicate_id` and `duplicate_step_id` mean the same action, or the same step within one action, appeared more than once in this call. `not_completable` is a content brief, whose steps are the material the brief was written from rather than work to do.
    - `message` string, required

## Other responses

- `400`: Response for status 400

## Changes

- **2026-11-03** `9fdffdff48a5`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/peec/apis/peec-ai-customer-api/changes/actions/steps/completion/post.md)

---

[API](https://skmtc.dev/peec/apis/peec-ai-customer-api.md) - [All operations](https://skmtc.dev/peec/apis/peec-ai-customer-api/llms.txt) - [OpenAPI document](https://skmtc.dev/peec/apis/peec-ai-customer-api/revisions/9d774600c8eb?raw)
