Skip to content

Use in CI

The browser login flow can't run in CI. Provide the app's credentials through the environment instead: when STREAM_API_KEY and STREAM_API_SECRET are both set, the app-scoped commands (api, token, env, import) run with no login and no linked project.

Store the credentials as secrets

You need the app's key and secret in CI. Get them from either place:

  • If you already linked the app locally, read them out of .stream/creds.yaml:

    cat .stream/creds.yaml
    key: <api key>
    secret: <api secret>
    ...
  • Otherwise, open the app in the Stream Dashboard and copy its key and secret.

Add STREAM_API_KEY and STREAM_API_SECRET to your CI provider's secret store.

Don't run getstream init in the pipeline - it opens an interactive picker so cannot be completed in a headless terminal. Linking a project is a one-time local step; CI only needs the key and secret.

Export the credentials in the pipeline

# GitHub Actions
env:
  STREAM_API_KEY: ${{ secrets.STREAM_API_KEY }}
  STREAM_API_SECRET: ${{ secrets.STREAM_API_SECRET }}

steps:
  - name: Install the Stream CLI
    run: curl -fsSL https://getstream.io/cli.sh | bash

  - name: Verify the credentials
    run: getstream api GetApp > /dev/null

With both variables set, getstream api and getstream token run with no login. The pair takes precedence over any .stream/creds.yaml the checkout happens to contain, and a --app-id flag beats both - see how credentials are resolved.

If a step has neither the variables nor a reachable .stream/creds.yaml, it fails with no app credentials and the error names the three fixes: run getstream init, pass --app-id, or set STREAM_API_KEY and STREAM_API_SECRET.

Verify the setup

The getstream api GetApp step above makes a real authenticated call, so a clean exit confirms the credentials work: 0 on success, 1 on failure with the reason on stderr, which fails the CI step. The redirect discards the response so the exit code alone gates the step. Don't verify with getstream token: it signs tokens locally without calling the API, so it succeeds even when the key and secret are wrong.