Portal Community
User Token required — Bot Tokens cannot search. The Slack search.messages API endpoint is restricted to User Tokens (xoxp-...) with the search:read scope. Bot Tokens (xoxb-) will receive an not_allowed_token_type error regardless of scopes. User Tokens carry broad workspace access — store them with the same care as admin credentials and rotate them regularly.

When to Use

Configuration

Connection

FieldRequiredDescription
botTokenRequiredUser Token in xoxp-... format with search:read scope. Despite the field name botToken, this operation requires a User Token. Store in BizFirst Credentials Manager under a distinct credential name (e.g. slackUserToken) separate from your Bot Token.

Operation

FieldRequiredDescription
queryRequiredFull-text search query string. Supports Slack search modifiers: in:#channel-name, from:@username, before:YYYY-MM-DD, after:YYYY-MM-DD, during:month. Example: database error in:#engineering after:2024-01-01.
sortOptionalSort field. Accepted values: score (default, relevance ranking) or timestamp (chronological order).
sortDirOptionalSort direction: desc (default — newest or most relevant first) or asc.
returnAllOptionalDefault true. When true, the node automatically paginates through all result pages and returns the complete match set. Set to false to return only a single page (use count and page for manual pagination).
countOptionalResults per page (1–100). Default 20. Only used when returnAll is false.
pageOptionalPage number (1-based). Default 1. Only used when returnAll is false.
Search modifier reference:

Sample Configuration

{
  "resource": "message",
  "operation": "search",
  "botToken": "{{ $credentials.slackUserToken }}",
  "query": "payment gateway error in:#engineering after:2024-05-01",
  "sort": "timestamp",
  "sortDir": "desc",
  "returnAll": false,
  "count": 50,
  "page": 1
}

Validation Errors

Error CodeCause
not_allowed_token_typeA Bot Token was used. Only User Tokens (xoxp-) can call search.messages.
missing_scopeThe User Token lacks the search:read OAuth scope. Re-authorize the app with the required scope.
not_authedThe User Token is invalid, expired, or has been revoked.
VAL_MISSING_QUERYThe query field is empty or not provided.

Output

Success Port

Fires with the complete search results. When returnAll is true, all pages are fetched before this port fires.

FieldTypeDescription
matchCountintegerNumber of matches returned in this response (may be less than totalCount when paginating).
totalCountintegerTotal number of messages matching the query across all pages.
pageCountintegerTotal number of pages available for the query.
matchesarrayArray of matched message objects. Each object contains: messageTs, channel (object with id and name), userId, text, permalink, previous (context), next (context).
statusstring"ok" on success.
errorCodestringEmpty on success.
payloadobjectFull raw Slack API response.

Error Port

Fires when authentication fails, the token type is wrong, or the API call fails.

FieldTypeDescription
statusstring"error"
errorCodestringSlack error code, e.g. not_allowed_token_type, missing_scope.
payloadobjectFull raw Slack error response.

Sample Output

{
  "matchCount": 3,
  "totalCount": 3,
  "pageCount": 1,
  "matches": [
    {
      "messageTs": "1716644812.033100",
      "channel": {
        "id": "C04ENGINEERI",
        "name": "engineering"
      },
      "userId": "U04DEV00001",
      "text": "Getting a payment gateway error on checkout — `PaymentGatewayException: connection timeout`",
      "permalink": "https://acmecorp.slack.com/archives/C04ENGINEERI/p1716644812033100"
    },
    {
      "messageTs": "1716648100.091200",
      "channel": {
        "id": "C04ENGINEERI",
        "name": "engineering"
      },
      "userId": "U04DEV00002",
      "text": "Same payment gateway error here. Looks like Stripe's webhook endpoint is unreachable.",
      "permalink": "https://acmecorp.slack.com/archives/C04ENGINEERI/p1716648100091200"
    },
    {
      "messageTs": "1716652200.017400",
      "channel": {
        "id": "C04INCIDENTS",
        "name": "incidents"
      },
      "userId": "U04OPS00001",
      "text": "P2 incident opened for payment gateway errors — tracking in INC-4421",
      "permalink": "https://acmecorp.slack.com/archives/C04INCIDENTS/p1716652200017400"
    }
  ],
  "status": "ok",
  "errorCode": "",
  "payload": {
    "ok": true,
    "messages": {
      "total": 3,
      "pagination": { "page": 1, "page_count": 1 },
      "matches": []
    }
  }
}

Expression Reference

FieldExpressionNotes
Total result count{{ $output.searchMsgs.totalCount }}Use to assess scope of a keyword across the workspace before processing individual matches.
Match count returned{{ $output.searchMsgs.matchCount }}Number of items in the matches array. Iterate over this many items in a downstream Loop node.
First match text{{ $output.searchMsgs.matches[0].text }}Text content of the first search result.
First match permalink{{ $output.searchMsgs.matches[0].permalink }}Direct URL to the first result. Embed in downstream notifications or database records.
First match channel name{{ $output.searchMsgs.matches[0].channel.name }}Human-readable channel name for the first result.
All matches array{{ $output.searchMsgs.matches }}Pass to a Loop node to process each result individually (extract text, log permalinks, etc.).

Node Policies & GuardRails

Policy AreaRecommendation
User Token securityUser Tokens search as the authenticating user and can access all channels that user belongs to, including private channels. Store the token in BizFirst Credentials Manager under a distinct, clearly-named credential (e.g. slackUserTokenSearch). Do not share this credential across unrelated workflows.
Token rotationRotate User Tokens regularly. User Tokens do not expire by default, but should be invalidated and reissued if a team member who owns the token leaves the organization.
Compliance and privacySearch results may surface private channel messages visible to the authenticated user. Treat search results as sensitive — do not log full message text to general-purpose logging systems. Write only the minimum required fields (timestamps, permalinks) to audit databases.
returnAll paginationSetting returnAll: true on queries that match thousands of messages can result in many API calls and long execution times. Use targeted modifiers (in:#channel, date ranges) to narrow results before enabling returnAll.
Rate limitssearch.messages is subject to Tier 2 rate limits (20+ req/min) and is also subject to workspace-level search rate limiting. Avoid calling this in high-frequency loops.
Query scopingUse channel modifiers (in:#channel-name) to restrict searches to relevant channels. Broad unscoped queries return results from all channels the user can see, which may include channels outside the intended audit scope.
Error port handlingAlways connect the error port. Token type errors (not_allowed_token_type) are common when the configuration accidentally uses a Bot Token instead of a User Token.

Examples

Compliance Keyword Audit

{
  "resource": "message",
  "operation": "search",
  "botToken": "{{ $credentials.slackUserToken }}",
  "query": "\"social security\" OR \"SSN\" OR \"credit card number\" after:2024-01-01",
  "sort": "timestamp",
  "sortDir": "desc",
  "returnAll": true
}

A monthly compliance workflow searches for messages that may contain regulated PII terms. The matches array is passed to a Loop node that writes each result's channel, user, timestamp, and permalink to a compliance audit database table. The total count is included in a compliance summary report posted to the #legal-compliance channel.

Scoped Channel Search for Support Triage

{
  "resource": "message",
  "operation": "search",
  "botToken": "{{ $credentials.slackUserToken }}",
  "query": "{{ $input.errorCode }} in:#customer-support after:{{ $input.windowStart }}",
  "sort": "timestamp",
  "sortDir": "asc",
  "returnAll": false,
  "count": 100,
  "page": 1
}

When a new support ticket is opened referencing a specific error code, this search finds all recent #customer-support messages mentioning the same error. The results are analyzed to determine if multiple customers are hitting the same issue, and the count is used to set the incident priority level.

Knowledge Base Retrieval Before Kickoff

{
  "resource": "message",
  "operation": "search",
  "botToken": "{{ $credentials.slackUserToken }}",
  "query": "{{ $input.projectName }} in:#engineering in:#product during:{{ $input.lastQuarter }}",
  "sort": "score",
  "sortDir": "desc",
  "returnAll": false,
  "count": 20,
  "page": 1
}

Before a project kickoff meeting, this workflow searches engineering and product channels for the last quarter's discussions about the project. The top 20 most relevant results (sorted by relevance score) are formatted and posted as a "context brief" to the project kick-off channel, saving team members from manually searching Slack history.