Skip to content

List notifications ​

GET/api/v2/workspaces/{slug}/notifications/

Return your own notifications in the workspace as a paginated list, newest first. Each request sees only the caller's inbox.

The list covers every kind of record, not only work items. Pass ?entity_name=issue for work item notifications only. Archived notifications are left out unless you pass ?archived=.

Path Parameters ​

slug:requiredstring

The workspace slug. It appears in your Plane URLs. In https://app.plane.so/my-team/projects/, the slug is my-team.

Query Parameters ​

Filters combine with AND. A malformed value, such as an unknown trigger_type or an id that isn't a UUID, returns 400 invalid_request instead of an unfiltered page.

read:optionalboolean

true for notifications you've read, false for unread ones. Omit it for both.

archived:optionalboolean

true for archived notifications only, false for active ones only. When you omit it, archived notifications are left out.

snoozed:optionalboolean

true for notifications with a snoozed_till time, false for ones without.

is_mention:optionalboolean

true for @-mentions of you only, false to leave mentions out.

trigger_type:optionalstring

Filter by what triggered the notification. One of mention, assigned, created, or subscribed, the same values as v1's type filter. An unknown value returns 400.

entity_name:optionalstring

Return notifications about one kind of record, for example issue for work items, page, or initiative. Case-insensitive.

Use entity_name__in to match several kinds, comma-separated, for example ?entity_name__in=issue,intake. That variant is case-sensitive.

entity_id:optionalstring (uuid)

Return notifications about one record, for example every notification about one work item.

project_id:optionalstring (uuid)

Return notifications from one project.

project_identifier:optionalstring

Return notifications from the project with this identifier, for example ENG. Case-insensitive.

triggered_by_id:optionalstring (uuid)

Return notifications caused by one user's actions.

created_at__gte:optionalstring (date-time)

Return notifications created at or after this time. Pair it with created_at__lte for a window.

created_at__lte:optionalstring (date-time)

Return notifications created at or before this time.

search:optionalstring

A search term matched against the title and the plain-text message.

Ordering ​

order_by:optionalstring

Field to sort by. Prefix with - for descending. Defaults to -created_at.

  • created_at, -created_at
  • updated_at, -updated_at
  • read_at, -read_at
  • id, -id

Only created_at and id work with paginate=cursor. Another ordering with a cursor returns 400 ordering_not_cursor_eligible.

Pagination ​

per_page:optionalinteger

Page size. Defaults to 50, maximum 200.

offset:optionalinteger

Number of rows to skip from the start of the result set. Maximum 10000. Read the next value from the response rather than computing offsets yourself.

paginate:optionalstring

Set to cursor to opt into the COUNT-free keyset envelope, which returns next_cursor and has_more instead of next and total_count. Omit it for the default offset envelope.

count:optionalboolean

Defaults to true. Set to false to skip the COUNT(*) behind total_count. The field is then omitted from the response.

Response shaping ​

fields:optionalstring

Comma-separated list of fields to return on each row. Unrequested keys are omitted from the response, not returned as null, so absent means "not requested" and null means "actually null". id always comes back whether or not you name it.

Pass all for every requestable field. An unknown name is a 400 that lists the valid set and suggests the closest match, so a typo can't silently cost you the saving.

Requestable here: archived_at, created_at, data, entity_id, entity_name, id, is_mention, message, message_html, project_id, read_at, sender, snoozed_till, title, triggered_by_id, updated_at.

See Sparse fields.

expand:optionalstring

Comma-separated relations to embed alongside the ids: triggered_by (the user whose action produced the notification, with id, display_name, avatar_url, and email).

Expansion is separate-key. ?expand=triggered_by keeps triggered_by_id and adds a triggered_by object next to it, so an id is never replaced by an object. An unknown value is a 400. An expanded object survives field filtering, so ?fields=id,title&expand=triggered_by returns id, title, and triggered_by. See Expanding relations.

Scopes ​

notifications:read

Errors ​

StatusCodeCause
400invalid_requestA filter value is malformed, such as an unknown trigger_type, or ?fields= or ?expand= names something unknown.
401unauthorizedMissing or invalid credentials.
402payment_requiredThe feature this endpoint belongs to isn't enabled on your plan, or is switched off.
403forbiddenYou aren't a member of the workspace, or your token scope doesn't allow this.
404not_foundNo such workspace.
406not_acceptableThe Accept header asks for a representation the API can't produce.
429rate_limitedThrottled. Honor the Retry-After header before retrying.
List notifications
bash
curl -X GET \
  "https://api.plane.so/api/v2/workspaces/my-team/notifications/?read=false&entity_name=issue&created_at__gte=2026-01-14T09:00:00Z" \
  -H "X-Api-Key: $PLANE_API_KEY"
Response200
json
{
  "data": [
    {
      "id": "71f4c2a9-8e3b-4d56-a017-5c9e2b8d4f63",
      "entity_id": "8c3d1f72-4a9e-4b65-9d20-6e1f3b7a5c48",
      "entity_name": "issue",
      "project_id": "4af68566-94a4-4eb3-94aa-50dc9427067b",
      "title": "Priya Shah has mentioned you in a comment in issue Fix login redirect loop",
      "message": null,
      "message_html": "<p></p>",
      "sender": "in_app:issue_activities:mentioned",
      "is_mention": true,
      "read_at": null,
      "archived_at": null,
      "snoozed_till": null,
      "data": {
        "issue": {
          "id": "8c3d1f72-4a9e-4b65-9d20-6e1f3b7a5c48",
          "name": "Fix login redirect loop",
          "identifier": "ENG",
          "sequence_id": 142,
          "state_name": "In Progress",
          "state_group": "started",
          "type_id": "5b7e2d94-1a6c-4f38-9e02-8d4c3b6a1f57"
        },
        "issue_activity": {
          "id": "3f8b6d21-9c4e-4a73-b1d5-7e2a0c9f6b48",
          "verb": "created",
          "field": "comment",
          "actor": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
          "new_value": "@Ravi can you check the redirect on Safari?",
          "old_value": "None",
          "old_identifier": null,
          "new_identifier": null,
          "issue_comment": "@Ravi can you check the redirect on Safari?"
        }
      },
      "triggered_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
      "created_at": "2026-01-14T09:22:41.478363Z",
      "updated_at": "2026-01-14T09:22:41.478363Z"
    },
    {
      "id": "2a8e6c14-7d93-4f0b-b5e2-1c4a9f7d3e86",
      "entity_id": "8c3d1f72-4a9e-4b65-9d20-6e1f3b7a5c48",
      "entity_name": "issue",
      "project_id": "4af68566-94a4-4eb3-94aa-50dc9427067b",
      "title": "updated the priority to",
      "message": null,
      "message_html": "<p></p>",
      "sender": "in_app:issue_activities:assigned",
      "is_mention": false,
      "read_at": null,
      "archived_at": null,
      "snoozed_till": null,
      "data": {
        "issue": {
          "id": "8c3d1f72-4a9e-4b65-9d20-6e1f3b7a5c48",
          "name": "Fix login redirect loop",
          "identifier": "ENG",
          "sequence_id": 142,
          "state_name": "In Progress",
          "state_group": "started",
          "type_id": "5b7e2d94-1a6c-4f38-9e02-8d4c3b6a1f57"
        },
        "issue_activity": {
          "id": "c09a4e7b-2d61-4f85-93b8-6a1e5d2c7f40",
          "verb": "updated",
          "field": "priority",
          "actor": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
          "new_value": "urgent",
          "old_value": "medium",
          "old_identifier": null,
          "new_identifier": null
        }
      },
      "triggered_by_id": "16c61a3a-512a-48ac-b0be-b6b46fe6f430",
      "created_at": "2026-01-14T09:18:05.112874Z",
      "updated_at": "2026-01-14T09:18:05.112874Z"
    }
  ],
  "next": null,
  "previous": null,
  "total_count": 2,
  "pagination": {
    "style": "offset"
  }
}
Response400
json
{
  "type": "invalid_request",
  "code": "invalid_request",
  "detail": "One or more fields failed validation.",
  "errors": [
    {
      "field": "trigger_type",
      "code": "invalid_choice",
      "message": "Select a valid choice. telepathy is not one of the available choices."
    }
  ]
}