Getting a Channel

The Get Channel API fetches a single channel by its type and ID without creating it. It is the read-only counterpart to creating a channel: when the channel does not exist (or has been deleted), the API responds with 404 Not Found instead of creating it. This makes the same call work as an efficient existence check.

GET /channels/{type}/{id}

Before this endpoint, the only ways to fetch or check one known channel were a Query Channels call with a single-CID filter, which runs the full filter and sort query path, or watching/querying the channel, which creates it when it is missing. Get Channel uses a cache-first lookup, so it can skip the database entirely when the channel is already cached.

SDK support: dedicated SDK methods for this endpoint are rolling out. Until your SDK exposes one, call the REST endpoint directly (examples below) or use your SDK's low-level request helper.

When to use it

You want toUse
Fetch one channel whose type and ID you already knowGet Channel
Check whether a channel exists, without creating itGet Channel (a 404 means it does not exist)
Fetch a channel, creating it when missingCreating a channel (channel.create() / channel.query())
Find channels by member set, filters, or sortingQuery Channels
Receive live events for a channelWatch the channel (channel.watch()), which also creates it when missing

Best practices

  • Prefer Get Channel over a single-CID Query Channels call. Querying with { "cid": { "$eq": ... } } (or a type + id filter) runs the full query machinery to return one known channel. Get Channel serves the same data from a cache-first path, which is cheaper for you (rate limits) and faster for your users.
  • Treat 404 as a normal outcome, not an error. For existence checks (for example, checking for a buyer-to-seller conversation before offering a "start chat" button), a 404 is the expected negative answer. Do not log it as a failure or retry it.
  • Stay on the cheap path unless you need messages. By default the response contains the channel, its configuration, and its members. Only pass state=true when you actually need messages, read state, or watchers hydrated.
  • Distinct channels are not covered. Channels created by member list get a generated ID, so their CID is not known up front. To find those, keep using Query Channels with a members filter, or create-or-get them with channel.create().

Making the request

Request options are passed JSON-encoded in the payload query parameter, like other Stream GET endpoints. The payload parameter is required: pass {} for the defaults.

Fetching a channel (cheap default path):

curl -G "https://chat.stream-io-api.com/channels/${CHANNEL_TYPE}/${CHANNEL_ID}" \
  --data-urlencode "api_key=${API_KEY}" \
  --data-urlencode 'payload={}' \
  -H "Authorization: ${TOKEN}" \
  -H "stream-auth-type: jwt"

Existence check (create only when missing):

status=$(curl -sG -o /dev/null -w "%{http_code}" \
  "https://chat.stream-io-api.com/channels/${CHANNEL_TYPE}/${CHANNEL_ID}" \
  --data-urlencode "api_key=${API_KEY}" \
  --data-urlencode 'payload={}' \
  -H "Authorization: ${TOKEN}" \
  -H "stream-auth-type: jwt")

if [ "$status" = "404" ]; then
  # channel does not exist; create it (or skip, depending on your flow)
  echo "channel is missing"
fi

Fetching full channel state (messages, read state, watchers):

curl -G "https://chat.stream-io-api.com/channels/${CHANNEL_TYPE}/${CHANNEL_ID}" \
  --data-urlencode "api_key=${API_KEY}" \
  --data-urlencode 'payload={"state": true, "messages_limit": 25, "watchers_limit": 10}' \
  -H "Authorization: ${TOKEN}" \
  -H "stream-auth-type: jwt"

The endpoint works with both authentication modes:

  • Server-side (API secret signed token): no user is required. Add "user_id": "<id>" to the payload to resolve membership and capabilities for a specific user.
  • Client-side (user token): the calling user needs the ReadChannel permission on the channel, typically granted through membership.

Request options

All options are optional.

OptionTypeDefaultDescription
statebooleanfalseWhen true, also hydrate messages, read state, watchers, and threads, like a channel query. When false, return only the channel, its config, and its members.
messages_limitinteger100Maximum number of messages to return. Applies only when state is true.
members_limitinteger100Maximum number of members to return. Applies only when state is true; the default path returns the channel's cached members without truncation.
watchers_limitinteger0Maximum number of watchers to return. Watchers are omitted unless this is set to a positive value together with state=true.

Response

The response has the same shape as a channel query response (channel, members, membership, messages, read, watchers, ...), so existing deserialization code can be reused. With state=false the messages, read, and watchers arrays are empty.

Because the endpoint performs no writes, it emits no events and does not affect unread counts, watchers, or presence.

Errors

StatusCondition
400The payload query parameter is missing or not valid JSON.
403The user lacks the ReadChannel permission, or the channel is disabled (client-side requests).
404The channel does not exist or has been deleted.

Rate limits

Get Channel shares the same high rate limit tier as Query Channels, so replacing single-CID Query Channels calls with Get Channel never lowers your available request budget.