---
title: "Record an action in the logbook"
method: POST
path: "/projects/{id}/logbook"
tags: ["Logbook"]
---

# Record an action in the logbook

`POST /projects/{id}/logbook`

## Request

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

`occurred_at` is the date the action HAPPENED, past dates welcome: when the person says
"yesterday" or "last week", compute that date and pass it. The call is idempotent on
`(project, quest_id, label, occurred_at)`: send it again and you get the entry already
recorded, with `200` instead of `201`. When the twin is one that had been taken out, it comes
back rather than being written a second time, and `restored` is `true` in the answer.

## Request body

- object
  - `category` 'content' | 'technical' | 'translation' | 'canon' | 'press' | 'other', required
  - `label` string, required: A short wording: it is what the annotation shows.
  - `occurred_at` string: ISO 8601 date or datetime, read as UTC without an offset. Omitted, now.
  - `notes` string, nullable
  - `quest_id` string, uuid, nullable: The quest of the same project the action moves forward.

## Response `200`

The same entry was already recorded, or was brought back from the trash.

- LogbookEntryEnvelope
  - `entry` LogbookItem, required: One move of the timeline. `source` says where it comes from and `kind` what it is; the keys below the first four depend on the kind.
    - `source` 'tool' | 'manual', required
    - `kind` 'canon_version' | 'surface_aligned' | 'corroboration' | 'corroboration_archived' | 'entry', required
    - `occurred_at` string, date-time, required: The date of the action. On a `corroboration` item it is the PUBLICATION date when it is known, and the recording date otherwise, `published_on` sitting right next to it so you can tell which one you are reading.
    - `author` string, nullable, required
    - `id` string, uuid: Manual entries only.
    - `category` 'content' | 'technical' | 'translation' | 'canon' | 'press' | 'other'
    - `label` string: Manual entries only.
    - `notes` string, nullable
    - `recorded_at` string, date-time: The day the entry was recorded.
    - `quest_id` string, uuid, nullable
    - `quest` string, nullable: The title of the quest the action moves forward.
    - `deleted_at` string, date-time, nullable: The day the entry left the logbook.
    - `canon_version` integer, nullable
    - `changed` string[]: The canon keys that revision touched: the number says the registry has work waiting, `changed` says what the work is about. Version 1 lists everything it posted.
    - `surface_id` string, uuid
    - `surface` string
    - `corroboration_id` string, uuid
    - `corroboration` string
    - `url` string
    - `domain` string
    - `published_on` string, date, nullable
    - `archived` boolean
  - `restored` boolean: Present on a creation whose twin was an entry that had been taken out: it came back rather than being written a second time.

## Other responses

- `201`: The entry, recorded.
- `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.
- `422`: `invalid_category`, `invalid_date`, `invalid_entry` or `invalid_quest`.
- `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)
