Skip to content

Build and debug

The CLI covers the everyday loop: configure the app, backfill data, debug and investigate. Run the commands from the terminal or a script, or ask your agent in plain language.

Call the Stream API

Every Stream endpoint available in the API and the SDKs is exposed in the CLI:

getstream api --help

For example:

getstream api UpdateChannelType --name messaging --request '{
  "polls": true
}'

Like every app-scoped command, api acts on the current project's app unless --app-id or the STREAM_API_KEY and STREAM_API_SECRET environment variables override it.

An endpoint's path parameters (like an id or a name) become flags. The request body and query parameters are passed as JSON with --request. Responses are JSON, and can be queried with --jq. In-depth help is available for every endpoint:

getstream api UpdateChannelType --help
getstream api UpdateChannelType --schema  # for full request schema

Examples

The api command is useful for configuring your app, backfills, debugging and investigation.

When working with an agent, just ask:

  • Has there been any chat activity in the past hour?
  • Are guest users allowed to send audio on livestreams?
  • Who follows the user alice?

Mint user tokens

To create a JWT user token for development purposes:

getstream token alice --ttl 1h

Like every app-scoped command, token acts on the current project's app unless --app-id or the STREAM_API_KEY and STREAM_API_SECRET environment variables override it.

The token lets you impersonate any user during development. Without --ttl the token never expires, so prefer setting a shorter one. This command doesn't replace setting up proper authentication in your app.

When working with an agent, just ask:

  • Give me a token for alice that expires in an hour.
  • Mint tokens for three test users.

Test webhooks locally

When building and testing apps that rely on Stream webhooks, it's often useful to temporarily route webhooks to your local dev server:

getstream webhook --port 3000 --path /webhooks/stream

Like every app-scoped command, webhook acts on the current project's app unless --app-id or the STREAM_API_KEY and STREAM_API_SECRET environment variables override it.

The command uses Cloudflare Quick Tunnels and cloudflared to proxy webhook events to your local server. A temporary webhook is set up in your app configuration, and it's automatically cleaned up when you exit the command with Ctrl-C or kill it.

You can set up multiple temporary webhooks listening for different events on different routes:

getstream webhook --port 3000 --path /webhooks/messages --event message.new &
messages=$!
getstream webhook --port 3000 --path /webhooks/users --event user.updated &
users=$!

# ...

kill "$messages" "$users"
wait

If the command is killed abruptly, it can leave a dangling webhook. To clean these up:

getstream webhook --prune

Webhook URLs include the unique id (?cliwebhook) for your CLI install. When pruning, all webhooks that were set up by your CLI are cleaned up, including the ones currently being proxied.

Warning:

Webhook event payloads will pass through the Cloudflare network. Be mindful when using this for production apps handling sensitive data.

When working with an agent, just ask:

  • Forward message.new webhooks to my dev server on port 3000.
  • Clean up any Stream webhooks left over from earlier sessions.

Livestream from the terminal

To test a livestream, video or audio call, you can use tools like ffmpeg and OBS to publish over RTMP, SRT, and WHIP. The CLI generates the signed ingress URL these tools need:

ffmpeg -re -i video.mp4 -c:v libx264 -c:a aac -f mpegts \
  "$(getstream ingress srt --cid livestream:my-stream --user alice --ttl 1h)"

Like every app-scoped command, ingress acts on the current project's app unless --app-id or the STREAM_API_KEY and STREAM_API_SECRET environment variables override it.

The call is created if it doesn't exist, and the specified user is the publisher. Without --ttl the signed URL never expires, so prefer setting a shorter one.

If you're using OBS (or other GUI software), the CLI can provide copyable values for stream settings:

getstream ingress srt --cid livestream:my-stream --user alice --ttl 1h --obs # or rtmp, whip

When working with an agent, just ask:

  • Start a test livestream into livestream:my-stream from sample.mp4.
  • Give me the OBS settings to stream into my call.

Import bulk data

To move a large dataset into your app, such as message history from another provider, use bulk import instead of calling the API record by record:

getstream import chat export.jsonl --watch

Like every app-scoped command, import acts on the current project's app unless --app-id or the STREAM_API_KEY and STREAM_API_SECRET environment variables override it.

For guidance on the import file format, see:

The import is processed in the background. Run with --watch to follow it until it finishes, or check on it later:

getstream import status <task-id>
getstream import list

Chat imports run in upsert mode, so re-importing a file updates existing objects instead of duplicating them.

When working with an agent, just ask:

  • Import export.jsonl into my chat app and tell me when it's done.
  • Did my last import finish, and did anything fail?

Look up the docs

The CLI gives your agent access to the latest Stream documentation, so it can answer questions about Stream for you. Your agent runs getstream docs under the hood, which keeps an up-to-date local copy of the documentation.

Just ask:

  • How do I enable message reminders, and which SDKs support them?
  • What's the difference between soft-deleting and hard-deleting a message?
  • How do I start a livestream in backstage mode and go live later?
  • How do listeners in an audio room request permission to speak?
  • How do I add reactions to an activity and show their counts?
  • How does ranking work for a personalized "for you" feed?
  • How do I block specific words in chat messages with a blocklist?
  • What happens to a message flagged by AI moderation, and where do I review it?