---
title: "Editor presence heartbeat"
method: POST
path: "/dashboards/{dashboard_id}/presence"
tags: ["Dashboard v3"]
---

# Editor presence heartbeat

`POST /dashboards/{dashboard_id}/presence`

## Request

- Base URL: `https://app.mammoth.io/api/v2`
- URL: `https://app.mammoth.io/api/v2/dashboards/{dashboard_id}/presence`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-KEY` and API key in header `X-API-SECRET` and API key in header `X-WORKSPACE-ID`

Each open editor tab beats every ~15s with its page, selected tile and the tile its assistant turn is changing, and gets back everyone else here (a tab that stops beating drops out after 45s), the board's status (moved to trash / archived while open), and — when `since` is sent — the same head summary as GET …/head. `leave` drops the tab at once. Nothing durable is written.

## Path parameters

- `dashboard_id` integer, required

## Request body

- PresenceSpec: Editor presence heartbeat
  - `params` PresenceParams, required
    - `client_id` string, required: This tab's random id
    - `page_id` string, nullable
    - `tile_id` string, nullable: The tile this tab has selected
    - `busy_tile_id` string, nullable: The tile this tab's assistant turn is changing
    - `idle` boolean: No input for two minutes
    - `since` integer, nullable: The draft head this tab is based on: answers `head` like GET …/head
    - `leave` boolean: The tab is closing: drop it now, not on expiry

## Response `200`

Who else is here, the board's status, and the head

- PresenceResponse
  - `others` PresentEditor[]: Everyone else with the editor open
    - `user_id` integer, required
    - `user_name` string
    - `page_id` string, nullable
    - `tile_id` string, nullable
    - `busy_tile_id` string, nullable
    - `idle` boolean
  - `status` BoardStatusModel, required
    - `state` 'active' | 'archived' | 'trashed', required
    - `by_name` string
  - `head` DraftHeadResponse
    - `head_sequence` integer, required: The current draft head sequence
    - `base_sequence` integer, nullable: The `since` the moves are counted from
    - `count` integer, required: Versions written after `since` (uncapped)
    - `moves` DraftMove[]: Newest first, at most `limit`
      - `sequence` integer, required: The version this write produced
      - `user_id` integer, nullable: Who wrote it
      - `user_name` string: Their display name
      - `at` string, nullable: When (ISO 8601, UTC)
      - `kind` 'edit' | 'assistant' | 'sync', required: A manual/server edit, an assistant turn, or a data sync
      - `label` string, nullable: The timeline's own words for the change, if any

## Other responses

- `400`: Bad request syntax or unsupported method
- `403`: Request forbidden -- authorization will not help

---

[API](https://skmtc.dev/mammoth/apis/mammoth-analytics.md) · [All operations](https://skmtc.dev/mammoth/apis/mammoth-analytics/llms.txt) · [OpenAPI document](https://skmtc.dev/mammoth/apis/mammoth-analytics/revisions/17af8131167d?raw)
