---
title: "Verify, set aside or clear checklist cells"
method: PATCH
path: "/surfaces/{id}/checklist"
tags: ["Surfaces"]
---

# Verify, set aside or clear checklist cells

`PATCH /surfaces/{id}/checklist`

## Request

- Base URL: `https://api.epovest.com/v1`
- URL: `https://api.epovest.com/v1/surfaces/{id}/checklist`
- Auth: HTTP bearer

Three moves per cell. VERIFY (`done` true, or nothing sent): the item is constated on the
page, and a canon-kind item is stamped with the current version and wording. SET ASIDE
(`dismissed` true plus a short `reason`): the item does not apply on THIS surface; it leaves
the denominator, survives canon revisions, and is undone by sending `dismissed` false. CLEAR
(`done` false): the cell returns to blank. Only the cells you send change. The batch is all
or nothing, so a verification pass is never half recorded. The aligned status derives from
the cells of `checklist.required`. Manager or above.

## Request body

- object
  - `ticks` ChecklistTick[], required
    - `item` string, required: One of `checklist.items`, the template of the type plus the checks of the customer.
    - `language` string, nullable: One of the columns of `checklist.state`. A site-wide item is one cell for the whole site, so it goes without a language, and a surface with a single column can leave it out.
    - `done` boolean, nullable: True or omitted verifies the item; false clears the cell.
    - `dismissed` boolean, nullable: True sets the item aside, with a `reason` due; false brings it back.
    - `reason` string, nullable: The short wording of why the item does not apply on this surface.

## Response `200`

The surface, with the checklist as it now reads.

- SurfaceEnvelope
  - `surface` Surface, required
    - `id` string, uuid, required
    - `project_id` string, uuid, required
    - `type` 'website' | 'github' | 'linkedin' | 'x' | 'youtube' | 'wikidata' | 'directory' | 'app_store' | 'other', required: Derived from the address when a surface is registered: a page whose registrable domain is the canon website is `website`, a known place carries its own kind, and any other host is `other`, which carries the generic checklist.
    - `url` string, required
    - `label` string, nullable, required
    - `languages` string[], required: Short language codes. They ARE the columns of the checklist.
    - `notes` string, nullable, required
    - `status` 'aligned' | 'needs_update' | 'never_aligned', required: Derived on read from the checklist cells that hold it, the ones listed in `checklist.required`: `aligned` (every required cell not set aside is verified at the current wording), `needs_update` (a verification is missing or stale), `never_aligned` (none exists yet).
    - `alignment` object, nullable, required: The last journal line.
      - `canon_version` integer
      - `aligned_at` string, date-time
      - `author` string, nullable
    - `checklist` Checklist, required
      - `items` string[], required: The template of the type, with stable keys such as `title_tag` or `llms_txt`, followed by the checks the customer added of their own.
      - `site_items` string[], required: The items that are site-wide, one cell for the whole site, under the `site` column.
      - `kinds` object, required: The kind of each item.
      - `required` string[], required: What HOLDS the status: the canon items of the template plus every check of the customer, whatever its kind. Read this list rather than deducing from `kinds`.
      - `custom` CustomCheck[], required: The definitions of the checks of the customer, the ones taken out included.
        - `key` string, required
        - `label` string, required
        - `scope` 'language' | 'site', required: `language` is one cell per language of the surface, `site` one cell for the whole site.
        - `restates_canon` boolean, required
        - `deleted` boolean, required
        - `deleted_at` string, date-time, nullable, required
        - `created_at` string, date-time, required
      - `state` object, required: The flat view of the verified items, per column.
      - `cells` object, required: The detail of each cell, per column then per item.
      - `progress` object, required: What holds at the current wording, over the cells that are not set aside, with the set-aside ones counted apart.
        - `done` integer, required
        - `total` integer, required
        - `dismissed` integer, required
    - `domain_authority` DomainAuthority, required: The join with the Atlas: what the AIs grant the DOMAIN the page sits on. An AI absent from `engines` has not cited the domain lately, and a `source_id` of null says the domain is not on the map of this account, which grows as you measure more.
      - `domain` string, required: The registrable domain read from the address by the same normalisation as the map.
      - `source_id` string, uuid, nullable, required
      - `engines` EngineAuthority[], required
        - `engine` 'chatgpt' | 'claude' | 'gemini' | 'perplexity' | 'mistral' | 'grok', required: The AI assistants the questions are asked to.
        - `aa` integer, required
      - `last_detected_on` string, date, nullable, required
    - `deleted` boolean, required
    - `deleted_at` string, date-time, nullable, required
    - `created_at` string, date-time, required

## Other responses

- `401`: `unauthenticated`: missing, unknown or revoked key.
- `403`: `insufficient_scope`: the credential may not do this, either because the key lacks the scope, or, on a one-click connection, because the person lacks the role the action needs (manager, or owner to start, pause and top up). On that path, read it as "this person may not do this" and tell them which role the action needs.
- `404`: `not_found`: unknown for this account.
- `409`: `no_canon` (a canon cell has nothing to restate: set the canon, then tick again), `not_a_surface` (setting aside the last canon cell), or `surface_deleted` (bring the surface back first).
- `422`: `invalid_checklist`: unknown item, unknown language, a language on a site-wide item, or a set-aside without reason. The message says what to send, and not a single tick is written.
- `429`: `rate_limited`: 120 requests per minute per credential, sliding window. Retry after `Retry-After` seconds.

---

[API](https://skmtc.dev/epovest/apis/epovest-api.md) · [All operations](https://skmtc.dev/epovest/apis/epovest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/epovest/apis/epovest-api/revisions/7a78ee27ecbb?raw)
