Query your Inbox

Page through the unified Inbox feed with the inbox query, check hasUnreadInboxThreads for the sidebar dot, and list pinned threads.


Three read paths cover the Inbox: inbox for the paginated, filterable feed; hasUnreadInboxThreads for a cheap existence check to drive an unread indicator; and pinnedInboxThreads for the threads you’ve pinned to the top. See Inbox & Messaging overview for the shared InboxThread type and its type/InboxFilter enums.

inbox

The paginated Inbox feed for the current organization, ordered by lastActivityAt descending (most recent first). Uses keyset (cursor) pagination.

Request

query MyInbox {
  inbox(filter: UNREAD, first: 20) {
    items {
      id
      type
      title
      preview
      isRead
      lastActivityAt
      lastActor {
        id
        fullName
      }
    }
    pageInfo {
      hasNextPage
      nextCursor
    }
  }
}

Parameters

ParameterTypeRequiredDefaultDescription
filterInboxFilterNoALLNarrow the feed to one slice. See InboxFilter.
typeInboxThreadTypeNoRestrict to one thread type (e.g. only DM_THREAD). Omit for all types.
afterStringNoCursor to page forward from — pass the previous page’s pageInfo.nextCursor.
firstIntNo20Maximum number of threads to return on this page.

Response

{
  "data": {
    "inbox": {
      "items": [
        {
          "id": "clm4n8qwx000008l0g4oxdqn7",
          "type": "DM_THREAD",
          "title": "Priya Shah",
          "preview": "Priya: Quick one, can you approve the vendor list?",
          "isRead": false,
          "lastActivityAt": "2026-07-15T09:41:02.000Z",
          "lastActor": { "id": "clm4n8qwx000108l0a1b2c3d4", "fullName": "Priya Shah" }
        }
      ],
      "pageInfo": {
        "hasNextPage": true,
        "nextCursor": "clm4n8qwx000008l0g4oxdqn7"
      }
    }
  }
}

Returns — InboxThreadList

FieldTypeDescription
items[InboxThread!]!The threads on this page.
pageInfoPageInfo!Cursor pagination metadata. There is no totalCount — an exact total would reintroduce the full-scan cost cursor pagination exists to avoid.

To fetch the next page, pass the current page’s pageInfo.nextCursor as the next call’s after, and stop when pageInfo.hasNextPage is false.

hasUnreadInboxThreads

A cheap existence check — whether any thread in your Inbox is unread. Use this to drive a sidebar unread dot without paginating the full feed.

Request

query InboxUnreadDot {
  hasUnreadInboxThreads
}

hasUnreadInboxThreads takes no arguments and returns a bare Boolean!.

Response

{
  "data": {
    "hasUnreadInboxThreads": true
  }
}

pinnedInboxThreads

Your pinned threads for the current organization, unpaginated (capped at 20 — see setInboxThreadPinned), most recently pinned first.

Request

query MyPinnedThreads {
  pinnedInboxThreads(type: DM_THREAD) {
    id
    type
    title
    preview
    lastActivityAt
  }
}

Parameters

ParameterTypeRequiredDescription
typeInboxThreadTypeNoRestrict to one thread type. Omit for all types.

Response

{
  "data": {
    "pinnedInboxThreads": [
      {
        "id": "clm4n8qwx000208l0e5f6g7h8",
        "type": "DM_THREAD",
        "title": "Launch crew",
        "preview": "Sarah: Works for me, I'll bring the customer feedback doc",
        "lastActivityAt": "2026-07-15T08:12:44.000Z"
      }
    ]
  }
}

pinnedInboxThreads returns [InboxThread!]! — see Inbox & Messaging overview for the field list.

Errors

None of the three queries throw beyond the standard authentication/authorization errors below — an unrecognized or omitted filter simply yields the default (ALL / all types).

CodeWhen
UNAUTHENTICATEDNo valid token was supplied.
COMPANY_NOT_FOUNDNo active organization for the request (missing/invalid blue-org-id).
PAYMENT_REQUIREDThe organization has no active license or subscription.

Permissions

All three require authentication and an active organization membership (isAuth, isAuthInCompany, isActiveCompany) — the same scoping as the record queries.