List 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:requiredstringThe 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:optionalbooleantrue for notifications you've read, false for unread ones. Omit it for both.
archived:optionalbooleantrue for archived notifications only, false for active ones only. When you omit it, archived notifications are left out.
snoozed:optionalbooleantrue for notifications with a snoozed_till time, false for ones without.
is_mention:optionalbooleantrue for @-mentions of you only, false to leave mentions out.
trigger_type:optionalstringFilter by what triggered the notification. One of mention, assigned, created, or subscribed. An unknown value returns 400.
mention returns @-mentions of you, the same rows as is_mention=true. assigned, created, and subscribed look for sender values that Plane no longer writes, so today they return an empty list. To tell those notifications apart, read each one's sender, for example in_app:issue_activities:assigned.
entity_name:optionalstringReturn 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:optionalstringReturn 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:optionalstringA search term matched against the title and the plain-text message.
Ordering
order_by:optionalstringField to sort by. Prefix with - for descending. Defaults to -created_at.
created_at,-created_atupdated_at,-updated_atread_at,-read_atid,-id
Only created_at and id work with paginate=cursor. Another ordering with a cursor returns 400 ordering_not_cursor_eligible.
Pagination
per_page:optionalintegerPage size. Defaults to 50, maximum 200.
offset:optionalintegerNumber of rows to skip from the start of the result set. Maximum 10000. Use the next value from the response instead of computing offsets yourself.
paginate:optionalstringSet to cursor to switch to the keyset envelope, which skips the COUNT query and returns next_cursor and has_more instead of next and total_count. Leave it out to get the default offset envelope.
count:optionalbooleanDefaults to true. Set to false to skip the COUNT(*) behind total_count. The field is then omitted from the response.
Response shaping
fields:optionalstringComma-separated list of fields to return on each row. Fields you don't request are left out of the response instead of coming back as null, so a missing key means you didn't ask for it and null means the value is null. id is always included, whether or not you name it.
Pass all to get every requestable field. An unknown field name returns 400 with the list of valid names and the closest match, so a typo is caught instead of being silently ignored.
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:optionalstringComma-separated relations to embed alongside the ids: triggered_by (the user whose action produced the notification, with id, display_name, avatar_url, and email).
Expanded objects get their own 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 returns 400. Field filtering never removes an expanded object, so ?fields=id,title&expand=triggered_by returns id, title, and triggered_by. See Expanding relations.
Scopes
notifications:read
Errors
| Status | Code | Cause |
|---|---|---|
400 | invalid_request | A filter value is malformed, such as an unknown trigger_type, or ?fields= or ?expand= names something unknown. |
401 | unauthorized | Missing or invalid credentials. |
403 | forbidden | You aren't a member of the workspace, or your token scope doesn't allow this. |
404 | not_found | No such workspace. |
406 | not_acceptable | The Accept header asks for a representation the API can't produce. |
429 | rate_limited | Throttled. Honor the Retry-After header before retrying. |
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"import requests
response = requests.get(
"https://api.plane.so/api/v2/workspaces/my-team/notifications/",
headers={"X-Api-Key": "your-api-key"},
params={
"read": "false",
"entity_name": "issue",
"created_at__gte": "2026-01-14T09:00:00Z",
},
)
print(response.json())const params = new URLSearchParams({
read: "false",
entity_name: "issue",
created_at__gte: "2026-01-14T09:00:00Z",
});
const response = await fetch(
`https://api.plane.so/api/v2/workspaces/my-team/notifications/?${params}`,
{
headers: {
"X-Api-Key": "your-api-key",
},
},
);
const data = await response.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"
}
}{
"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."
}
]
}
