> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ergoly.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# List Slack channels

> Every public room in the workspace — including the ones none of your Workers is in, which is what makes it a directory rather than a roster — plus the private rooms a Worker has been invited into. `?query=` ranks by name with an exact match first, so "#ops" never resolves to "#ops-archive". `memberWorkerIds` is empty for a room no bot is in; that is the normal state of a public channel and the reason `inviteWorkerBot` exists. `seenAt` says when Slack last confirmed the room: the directory is re-read from Slack when it goes stale, so the answer is current rather than live. A workspace that has never been read and cannot be reached now is a 502, never an empty list — "we could not find out" and "you have no channels" are opposite answers.



## OpenAPI

````yaml /openapi.json get /api/v1/channels
openapi: 3.1.0
info:
  title: Ergoly platform API
  version: 1.0.0
  description: >-
    Read and change one organization's own Ergoly environment. Every route is
    scoped to the organization the presented credential resolves to; there is no
    parameter that widens it. The human-readable reference is served from the
    same namespace at `/api/v1/docs`, behind the same credential.


    The namespace's front door is `GET /api/v1`, and it is deliberately absent
    from `paths` below. It answers without a credential — what this API is, how
    an organization admin mints a key, and where the reference lives — so it is
    the way in to this contract rather than a part of it: it has no scope, takes
    no parameters, and there is nothing about it for a generated client to call.
    Every `unauthorized` refusal carries that same URL as `error.docs`.
servers:
  - url: https://control.ergoly.ai
security:
  - orgApiKey: []
tags:
  - name: auth
    description: How to present a key, what it is scoped to, and what a 401 means.
  - name: organization
    description: Which organization your credential resolves to.
  - name: workers
    description: The Slack apps and bot identities in your organization.
  - name: eworks
    description: The runtime instances under a Worker — one core, one per bound Client.
  - name: clients
    description: The customers a Worker can be scoped to, and how to bind one.
  - name: channels
    description: Which Slack rooms a Worker answers in, and who it answers as.
  - name: tasks
    description: >-
      Tasks handed between Workers and people, scheduled jobs, their targets,
      and their run history.
  - name: jobs
    description: How a provisioning run is going — the other half of every 202.
  - name: memory
    description: Read and write the memory tiers an ework mounts.
  - name: connections
    description: The credentials your agents use, and the hosts they are injected on.
  - name: webhooks
    description: Inbound URLs an outside system can POST to, each of which starts a turn.
  - name: activity
    description: Your organization's audit feed.
  - name: usage
    description: Cost, turn outcomes and a per-day pulse over a window you choose.
  - name: errors
    description: The closed set of refusal codes, and what to do about each.
paths:
  /api/v1/channels:
    get:
      tags:
        - channels
      summary: List Slack channels
      description: >-
        Every public room in the workspace — including the ones none of your
        Workers is in, which is what makes it a directory rather than a roster —
        plus the private rooms a Worker has been invited into. `?query=` ranks
        by name with an exact match first, so "#ops" never resolves to
        "#ops-archive". `memberWorkerIds` is empty for a room no bot is in; that
        is the normal state of a public channel and the reason `inviteWorkerBot`
        exists. `seenAt` says when Slack last confirmed the room: the directory
        is re-read from Slack when it goes stale, so the answer is current
        rather than live. A workspace that has never been read and cannot be
        reached now is a 502, never an empty list — "we could not find out" and
        "you have no channels" are opposite answers.
      operationId: listWorkspaceChannels
      parameters:
        - name: query
          in: query
          required: false
          description: >-
            Narrow to rooms whose name matches. A leading `#` is ignored and
            case is folded. An exact match always comes first, then names that
            start with the text, then names that contain it. Omit it to list the
            whole workspace.
          schema:
            type: string
            description: >-
              Narrow to rooms whose name matches. A leading `#` is ignored and
              case is folded. An exact match always comes first, then names that
              start with the text, then names that contain it. Omit it to list
              the whole workspace.
        - name: limit
          in: query
          required: false
          description: >-
            How many rooms to return. Defaults to 50, clamped at 200. A value
            that is not a positive integer is a 400.
          schema:
            type: integer
            description: >-
              How many rooms to return. Defaults to 50, clamped at 200. A value
              that is not a positive integer is a 400.
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/WorkspaceChannel'
                    description: The page.
                  page:
                    $ref: '#/components/schemas/PageInfo'
                required:
                  - data
                  - page
                additionalProperties: false
              example:
                data:
                  - id: C0A1B2C3D4E
                    name: acme-support
                    isPrivate: false
                    isArchived: false
                    memberWorkerIds:
                      - 8f1c2d3e-9a4b-4c5d-8e6f-1a2b3c4d5e6f
                    seenAt: '2026-02-28T16:44:12.000Z'
                page:
                  limit: 50
                  hasMore: true
                  nextCursor: null
        '400':
          description: '`invalid_request`'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: '`unauthorized`'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: '`rate_limited`'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: '`upstream_error`'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - orgApiKey:
            - channels:read
components:
  schemas:
    WorkspaceChannel:
      type: object
      description: One room in your Slack workspace, as the channel directory knows it.
      properties:
        id:
          type: string
          description: The Slack channel id (`C…`/`G…`). What every channel call takes.
        name:
          type:
            - string
            - 'null'
          description: >-
            The channel name without the leading `#`; null when Slack did not
            say.
        isPrivate:
          type:
            - boolean
            - 'null'
          description: Null means Slack did not say — a different answer from `false`.
        isArchived:
          type:
            - boolean
            - 'null'
          description: Null means Slack did not say.
        memberWorkerIds:
          type: array
          items:
            type: string
            description: A Worker id.
          description: >-
            Which of your live Workers' bots are in the room. EMPTY IS THE
            NORMAL STATE of a public channel nobody has been invited into, and
            it is why `inviteWorkerBot` exists — routing a room to a Worker does
            not put its bot in it.
        seenAt:
          type: string
          format: date-time
          description: >-
            When Slack last confirmed this room. The directory is read from
            Slack when it goes stale, so this says how current the answer is
            rather than claiming it is live.
      required:
        - id
        - name
        - isPrivate
        - isArchived
        - memberWorkerIds
        - seenAt
      additionalProperties: false
    PageInfo:
      type: object
      description: Present on every list, even when there is nothing more to fetch.
      properties:
        limit:
          type: integer
          description: The page size actually applied, after clamping.
        hasMore:
          type: boolean
          description: True when another page exists.
        nextCursor:
          type:
            - string
            - 'null'
          description: >-
            Feed back as `?cursor=`. Null when `hasMore` is false — and always
            null on a list that takes no `cursor` parameter, which ranks its
            rows rather than paging them and says so on its own page. Narrow
            that list's `query` instead.
      required:
        - limit
        - hasMore
        - nextCursor
      additionalProperties: false
    Error:
      type: object
      description: The one error shape. Every refusal in this namespace has it.
      properties:
        error:
          type: object
          description: The refusal.
          properties:
            code:
              type: string
              enum:
                - unauthorized
                - not_found
                - invalid_request
                - conflict
                - quota_exceeded
                - rate_limited
                - upstream_error
                - gone
              description: The machine-stable half. Branch on this, never on `message`.
            message:
              type: string
              description: Prose for a human reading a terminal.
            docs:
              type: string
              description: >-
                Where to learn how to authenticate. Present on `unauthorized`
                and on nothing else — it is the one refusal a caller can reach
                with no credential at all, so it is the one that has to say
                where the way in is.
          required:
            - code
            - message
          additionalProperties: false
      required:
        - error
      additionalProperties: false
  securitySchemes:
    orgApiKey:
      type: http
      scheme: bearer
      description: >-
        An organization-scoped API key, minted in control under Settings → API
        keys. Every failure to authenticate answers one identical 401: "Provide
        a valid organization-scoped API key or an active session." Each
        operation names the one scope it is filed under,
        `<resource>:<read|write>`, where the resource is the first path segment
        after `/api/v1/`; a key minted today carries all 22 of them. Scopes are
        RECORDED — on the key and on every audit row — and are not yet enforced:
        no request is refused for want of one.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.