---
title: "Logs"
description: "List, create, edit, and move logs on the daily board."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.loggo.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Logs

See [Canvas and Masonry](/features/canvas-and-masonry) for how logs are arranged on a board, and the [Markdown Editor](/features/markdown-editor) for what the `body` field can contain.

Every route on this page is under `/api/workspaces/:workspaceId/logs` and requires **Workspace Member**.

## `GET /api/workspaces/:workspaceId/logs`

Lists logs for a workspace. See [Conventions](/api/overview#conventions) for how `day` changes pagination.

**Query Parameters**

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `day` | string | No | Only logs on this date (`YYYY-MM-DD`) — unpaginated, capped at 100 |
| `from` | string | No | Only logs on or after this date |
| `to` | string | No | Only logs on or before this date |
| `tag` | string | No | Only logs carrying this tag |
| `page` | number | No | Page number, used when `day` is omitted |

**Response**

```json
{
  "logs": [
{ "id": "01HXYZ...", "workspaceId": "...", "authorId": "...", "day": "2026-09-06", "title": "Meeting notes", "body": "...", "createdAt": "...", "updatedAt": "...", "posX": 24, "posY": 24, "width": null, "height": null, "zIndex": 0, "authorName": "Demo", "tags": ["postgres"] }
  ],
  "hasMore": false,
  "page": 1,
  "limit": 10
}
```

## `POST /api/workspaces/:workspaceId/logs`

Creates a log. `day` is set once here and never changes afterward — that's what keeps a log's mirrored file in one place forever.

**Request body**

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `day` | string | Yes | `YYYY-MM-DD` |
| `body` | string | Yes | Markdown, up to 2,000,000 characters |
| `title` | string \| null | No | |
| `posX` | integer | No | Canvas X coordinate |
| `posY` | integer | No | Canvas Y coordinate |

**Response:** `201` with the log itself (not wrapped) — the author, workspace, parsed `tags`, and parsed `tasks` are included, same shape as [`GET /:logId`](#get-apiworkspacesworkspaceidlogslogid) below.

## `GET /api/workspaces/:workspaceId/logs/:logId`

**Response**

```json
{
  "id": "...", "workspaceId": "...", "authorId": "...", "day": "2026-09-06", "title": "...", "body": "...",
  "createdAt": "...", "updatedAt": "...", "posX": 24, "posY": 24, "width": null, "height": null, "zIndex": 0,
  "author": { "id": "...", "name": "Demo" },
  "workspace": { "id": "...", "slug": "personal-demo", "name": "Personal" },
  "tags": ["postgres", "perf"],
  "tasks": [{ "id": "...", "logId": "...", "text": "Ship the release notes", "done": false, "dueDate": "2026-09-07", "lineNo": 1, "completedAt": null }]
}
```

## `PATCH /api/workspaces/:workspaceId/logs/:logId`

Updates a log's content. Re-parses tags and tasks from the new `body` on save.

**Request body** — both optional:

| Field | Type | Notes |
| --- | --- | --- |
| `title` | string \| null | |
| `body` | string | |

**Response:** the updated log, same shape as `GET /:logId`.

## `PATCH /api/workspaces/:workspaceId/logs/:logId/position`

Moves a log on the infinite canvas. This is board-arrangement state, not content — it skips the markdown mirror and `updatedAt` entirely, so dragging a card never rewrites its file.

**Request body**

| Field | Type | Required |
| --- | --- | --- |
| `posX` | integer | Yes |
| `posY` | integer | Yes |

**Response:** `{ "ok": true }`

## `PATCH /api/workspaces/:workspaceId/logs/:logId/size`

Resizes a log's card on the canvas. Same board-arrangement treatment as position — no mirror write.

**Request body**

| Field | Type | Required |
| --- | --- | --- |
| `width` | integer | Yes |
| `height` | integer | Yes |

**Response:** `{ "ok": true }`

## `PATCH /api/workspaces/:workspaceId/logs/:logId/zindex`

Brings a log to front (or sends it back) on the canvas. Same board-arrangement treatment — no mirror write.

**Request body**

| Field | Type | Required |
| --- | --- | --- |
| `zIndex` | integer | Yes |

**Response:** `{ "ok": true }`

## `POST /api/workspaces/:workspaceId/logs/:logId/duplicate`

Copies a log onto the same day, offset 24px down and right, stacked above the original.

**Response:** `201` with the new log, same shape as `GET /:logId`.

## `POST /api/workspaces/:workspaceId/logs/:logId/move/:targetWorkspaceId`

Moves a log (and its attachments) to a different workspace, keeping its day and content. Requires membership in **both** `:workspaceId` and `:targetWorkspaceId` — checked separately, since they're two different workspaces.

**Response:** the log, now pointing at the target workspace.

## `DELETE /api/workspaces/:workspaceId/logs/:logId`

Soft-deletes a log (sets `deletedAt`) and removes its markdown mirror file.

**Response:** `{ "ok": true }`

Source: https://docs.loggo.dev/api/logs//index.md
