Files
fizzy/docs/api/sections/activities.md
T
Rob Zolkos 6a71856b3d Add JSON activities API endpoint (#2783)
* Add JSON events API endpoint

* Add regression test for event particulars defaults

* Move JSON events API to a dedicated ActivitiesController

The events endpoint served both the HTML day timeline and the JSON API
feed, but the two paths shared no data or behavior — the HTML side uses
DayTimelinesScoped while the JSON side built its own query. Splitting
into ActivitiesController gives the API its own home at
GET /:account/activities.json without dragging in the timeline
before_actions.

Also preloads comment creator in Event.preloaded to avoid an N+1 when
rendering comment eventables in the JSON feed.
2026-04-08 08:39:36 -04:00

6.7 KiB

Activities

Activities are the activity stream for an account — a record of significant actions like cards being published, assigned, closed, and commented on.

GET /:account_slug/activities

Returns a paginated flat list of activities the current user can access, sorted newest first.

Query Parameters:

Parameter Description
creator_ids[] Filter to activities created by specific user ID(s). Multiple values are ORed.
board_ids[] Filter to activities on specific board ID(s). Multiple values are ORed.

Different filter params are ANDed together: creator_ids[]=A&board_ids[]=X means activities created by A on board X.

To fetch activity for a specific user, use creator_ids[]=USER_ID.

Supported actions:

action eventable_type particulars shape
card_assigned Card { "assignee_ids": [USER_ID, ...] }
card_auto_postponed Card {}
card_board_changed Card { "old_board": STRING, "new_board": STRING }
card_closed Card {}
card_postponed Card {}
card_published Card {}
card_reopened Card {}
card_sent_back_to_triage Card {}
card_title_changed Card { "old_title": STRING, "new_title": STRING }
card_triaged Card { "column": STRING }
card_unassigned Card { "assignee_ids": [USER_ID, ...] }
comment_created Comment {}

particulars is always an object. It contains action-specific metadata in a normalized format intended for API clients. It does not necessarily mirror the internal event JSON stored by Fizzy. Unknown keys may appear in the future and should be ignored. For card_assigned and card_unassigned, assignee_ids is currently a single-element array in practice.

particulars examples:

{ "action": "card_assigned", "particulars": { "assignee_ids": ["03f5user123"] } }
{ "action": "card_unassigned", "particulars": { "assignee_ids": ["03f5user123"] } }
{ "action": "card_board_changed", "particulars": { "old_board": "Backlog", "new_board": "Mobile" } }
{ "action": "card_title_changed", "particulars": { "old_title": "Fix login", "new_title": "Fix mobile login" } }
{ "action": "card_triaged", "particulars": { "column": "In Progress" } }
{ "action": "card_closed", "particulars": {} }

The practical eventable_type values are Card and Comment. Clients should handle unknown future values conservatively.

Activities whose underlying Card or Comment has been deleted or is inaccessible to the current user are omitted from the feed. The endpoint never returns eventable: null.

The top-level board field reflects the activity's current board association. If a card moves boards, all its activities move with it for the purposes of this feed and board_ids[] filtering.

This endpoint is a paginated activity feed, not an immutable audit-log. description, eventable, board, and creator may reflect current resource state. Re-fetch recent pages to get fresh activity data.

Response:

[
  {
    "id": "03faevt004",
    "action": "card_closed",
    "created_at": "2026-03-25T15:11:04.000Z",
    "description": "David Heinemeier Hansson moved \"Fix mobile login\" to \"Done\"",
    "particulars": {},
    "url": "http://fizzy.localhost:3006/897362094/cards/42",
    "eventable_type": "Card",
    "eventable": {
      "id": "03f6card042",
      "number": 42,
      "title": "Fix mobile login",
      "status": "closed",
      "description": "Users cannot complete login on iOS.",
      "description_html": "<div>Users cannot complete login on iOS.</div>",
      "image_url": null,
      "has_attachments": false,
      "tags": ["ios", "auth"],
      "closed": true,
      "postponed": false,
      "golden": false,
      "last_active_at": "2026-03-25T15:11:04.000Z",
      "created_at": "2026-03-25T09:00:00.000Z",
      "url": "http://fizzy.localhost:3006/897362094/cards/42"
    },
    "board": {
      "id": "03f6abc123",
      "name": "Mobile",
      "all_access": true,
      "created_at": "2026-03-01T10:00:00.000Z",
      "auto_postpone_period_in_days": 14,
      "url": "http://fizzy.localhost:3006/897362094/boards/03f6abc123"
    },
    "creator": {
      "id": "03f5user123",
      "name": "David Heinemeier Hansson",
      "role": "owner",
      "active": true,
      "email_address": "david@example.com",
      "created_at": "2026-03-01T09:00:00.000Z",
      "url": "http://fizzy.localhost:3006/897362094/users/03f5user123",
      "avatar_url": "http://fizzy.localhost:3006/897362094/users/03f5user123/avatar"
    }
  },
  {
    "id": "03faevt003",
    "action": "comment_created",
    "created_at": "2026-03-25T14:17:22.000Z",
    "description": "David Heinemeier Hansson commented on \"Fix mobile login\"",
    "particulars": {},
    "url": "http://fizzy.localhost:3006/897362094/cards/42#comment_03facomment9",
    "eventable_type": "Comment",
    "eventable": {
      "id": "03facomment9",
      "created_at": "2026-03-25T14:17:22.000Z",
      "updated_at": "2026-03-25T14:17:22.000Z",
      "body": {
        "plain_text": "I found the regression in the callback flow.",
        "html": "<div>I found the regression in the callback flow.</div>"
      },
      "creator": {
        "id": "03f5user123",
        "name": "David Heinemeier Hansson",
        "role": "owner",
        "active": true,
        "email_address": "david@example.com",
        "created_at": "2026-03-01T09:00:00.000Z",
        "url": "http://fizzy.localhost:3006/897362094/users/03f5user123",
        "avatar_url": "http://fizzy.localhost:3006/897362094/users/03f5user123/avatar"
      },
      "card": {
        "id": "03f6card042",
        "url": "http://fizzy.localhost:3006/897362094/cards/42"
      },
      "reactions_url": "http://fizzy.localhost:3006/897362094/cards/42/comments/03facomment9/reactions",
      "url": "http://fizzy.localhost:3006/897362094/cards/42/comments/03facomment9"
    },
    "board": {
      "id": "03f6abc123",
      "name": "Mobile",
      "all_access": true,
      "created_at": "2026-03-01T10:00:00.000Z",
      "auto_postpone_period_in_days": 14,
      "url": "http://fizzy.localhost:3006/897362094/boards/03f6abc123"
    },
    "creator": {
      "id": "03f5user123",
      "name": "David Heinemeier Hansson",
      "role": "owner",
      "active": true,
      "email_address": "david@example.com",
      "created_at": "2026-03-01T09:00:00.000Z",
      "url": "http://fizzy.localhost:3006/897362094/users/03f5user123",
      "avatar_url": "http://fizzy.localhost:3006/897362094/users/03f5user123/avatar"
    }
  }
]

All url fields are opaque absolute URLs for the current Fizzy instance. Clients should not construct them.