The Sequential CLI

The Sequential CLI (npx @usesequential/cli) records changes and releases from a CI job or a script, and calls the same tools as an agent connected to Sequential.

View as Markdown

On this page

Run it

From 7 November 2026, the CLI is on npm. Run it with npx, with the scope in the name:

bash

npx @usesequential/cli tools
  • Always write @usesequential/cli. On npm, the name sequential without the scope is a different package, which Sequential does not own.
  • The package has no dependencies.
  • In the examples below, sequential is the command. With npx, write npx @usesequential/cli in its place.

The token

The CLI reads its token from SEQUENTIAL_TOKEN. It must be a project access token (sq_pat_…). An owner or admin of your organisation makes one in Sequential: open the project, then Settings › Agents & tokens › Make a token. A token works for one project.

  • For the commands below, use the preset CLI and CI. It holds changes:read, changes:write and releases:write. See Limits for all presets.
  • Put the token in your CI's secrets. Do not put it in a command line.
  • The CLI never prints the token and never writes it to disk.
  • A server key (sqs_…) sends events. It cannot call tools: the CLI refuses it before it sends a request.

Record changes and releases

These commands send one request each and print one line for each result. --json prints Sequential's answer instead. --dry-run prints what the command would send, needs no token, and sends nothing.

bash

# One change: a campaign, a price, a product change
sequential changes record --kind pricing --title "Trial is now 14 days"

# A batch from a JSON array, once for each CI run (one request, never split)
sequential changes sync --items changes.json --source git

# A release, which Sequential measures fixes against
sequential releases record --version "$APP_VERSION"

# What this token is: its project, rights and expiry
sequential whoami
  • releases record reads SEQUENTIAL_RELEASES_TOKEN first, then SEQUENTIAL_TOKEN.
  • Do not give --environment to releases record. The release then gets your project's environment, where Sequential measures fixes.
  • Give the version exactly as your app's events carry it. See The version must match.
  • Sequential keeps a title that reads like an instruction as a proposal. The CLI prints the link where a person confirms it. See Changes.
  • sequential help <command> shows every option. Sequential checks the values, and says why it refuses one. sequential tools describe record_change shows the kinds and the limits.
  • These commands replace the commands of @usesequential/node 1.x, which continue to work. See Backend SDK (Node).

Name what a release fixes, from GitHub or git

sequential releases record can also name what a release changed and the cases that it fixes. Use one of these options, not both:

  • --github-changes reads the GitHub API with the token of the workflow. It does not need a checkout.
  • --range <prev..HEAD> reads trailer lines such as Sequential-Finding: F-12 with git log, in a checkout. With actions/checkout, set fetch-depth: 0.

Sequential then compares the sessions before and after the release, for each case that the release names. The release records only what changed. It does not say what caused a result. See Cases.

What --github-changes reads

--github-changes needs --commit-sha, the commit that you deployed, and the token in GITHUB_TOKEN. It sends only GET requests to GitHub:

  1. The previous release: the newest earlier deployment in the same GitHub environment whose newest status is success. On a push event, it is the commit before the push. --base <sha> gives the commit yourself.
  2. The commits from the previous release to this one. GitHub lists at most 250.
  3. The merged pull requests of these commits, newest first, each one time, at most 50. They go to the release as its changes: the title, the link and the number.
  4. The cases: Sequential-Finding: F-12 trailers in the commit messages, and "Fixes F-12" in the titles and the text of the pull requests. Fix, fixed, close, closes, closed, resolve, resolves and resolved work too, and so do lists such as "Fixes F-3, F-4 and F-5". The CLI sends them after the ids of --finding, each one time, at most 50.

The job needs the read permissions deployments, contents and pull-requests. Without them, GitHub refuses the calls, and the release is recorded without changes and without case ids from GitHub.

When a read from GitHub fails, the command prints one line and still records the release. For example, after a rollback the previous release is not an ancestor of this commit:

text

GitHub: could not compare bbbbbbb...aaaaaaa (HTTP 404); the release is recorded without changes or finding ids from GitHub.

When it succeeds, the last line says what it recorded:

text

Recorded release 3f2a… (2 findings: F-1, F-12; 1 change since bbbbbbb)

--dry-run reads git and GitHub too, and prints what the command would send. It sends nothing to Sequential.

The version must match

To count a session as "after" a release, Sequential reads the release that the session's events carry: the browser SDK's release option, data-release on the script tag, $release that the page registers, or a mobile app's version. Sequential does not use the release of the backend SDK. So each session must carry the same string as the --version that you record.

  • Record --version <full commit sha>, and set the browser SDK's release to the same full sha. On Vercel with Next.js, that is process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA. Turn on "Automatically expose System Environment Variables".
  • A short sha in one place and a full sha in the other place do not match.
  • When no session carries the recorded version, Sequential compares by time: each session that starts 2 hours or more after the release is "after". This works, but it can count sessions on an older build.

Vercel: record each production deployment

Vercel deploys from its own GitHub App, so no workflow of yours runs the deployment. Vercel tells GitHub about each deployment. So a workflow on deployment_status can record the release when Vercel reports success. For one Vercel project:

yaml

# .github/workflows/sequential-release.yml
name: Sequential release
on: deployment_status

permissions:
  deployments: read     # find the previous successful deployment
  contents: read        # compare the two commits
  pull-requests: read   # the merged pull requests and their text

jobs:
  record:
    # Only a successful production deployment.
    if: github.event.deployment_status.state == 'success' && startsWith(github.event.deployment.environment, 'Production')
    runs-on: ubuntu-latest
    steps:
      - run: >-
          npx -y @usesequential/cli releases record
          --version "$SHA" --commit-sha "$SHA" --released-at "$RELEASED_AT"
          --github-changes
        env:
          SEQUENTIAL_RELEASES_TOKEN: ${{ secrets.SEQUENTIAL_RELEASES_TOKEN }}
          GITHUB_TOKEN: ${{ github.token }}
          SHA: ${{ github.event.deployment.sha }}
          RELEASED_AT: ${{ github.event.deployment_status.created_at }}
  • Each value gets to the command as an environment variable, never inside the script.
  • Vercel names each GitHub environment Production – <vercel project>. With more than one Vercel project, each Sequential project has its own token: map each environment to the secret that holds its token. The README of the CLI has that workflow.

GitHub Actions on a tag push

yaml

on:
  push:
    tags: ['v*']
permissions:
  contents: read
  pull-requests: read
jobs:
  record:
    runs-on: ubuntu-latest
    steps:
      - run: >-
          npx -y @usesequential/cli releases record
          --version "$GITHUB_REF_NAME" --commit-sha "$GITHUB_SHA"
          --github-changes --base "$PREVIOUS_SHA"
        env:
          SEQUENTIAL_RELEASES_TOKEN: ${{ secrets.SEQUENTIAL_RELEASES_TOKEN }}
          GITHUB_TOKEN: ${{ github.token }}
          PREVIOUS_SHA: <the previous tag's commit sha>   # a tag push has no useful `before`

Or read the trailers from a checkout: actions/checkout with fetch-depth: 0, then --range "$PREVIOUS_TAG..$GITHUB_SHA" instead of --github-changes. A base of all zeros (a first push) reads only the head commit.

More than one project in one repository

A case number belongs to one Sequential project: F-12 can exist in each of your projects. When one pull request changes more than one app, write the project key before the number:

text

Fixes web#F-12, app#F-3
  • With --project-key web, only web#… ids count for this release. An id without a key, such as F-12, does not count, because it can be a case of another project. To count ids without a key too, add --findings all.
  • Without --project-key (one repository, one Sequential project), ids without a key count, and ids with a key do not.
  • Trailers use the same rule: Sequential-Finding: web#F-12.

See and call the tools

The CLI calls the same tools as an agent connected to Sequential, with the same rules. See Agent tools.

bash

sequential tools                       # the tools this token can use
sequential tools describe list_findings
sequential call list_findings --status all --limit 10
sequential call get_session --session-id 9f2c…
sequential call record_change --kind pricing --title "Trial is now 14 days" --yes
  • tools lists each tool as read, write or paid. The tools that this token cannot use are under Not enabled on this token. sequential call <tool> on such a tool prints the steps to turn it on.
  • Each argument of the tool is a flag. --session-id and --session_id are the same flag.
  • A true or false argument: --has-errors or --no-has-errors. A list: give the flag again (--tags a --tags b).
  • An object, or a list of objects: --json-arg links='[{"url":"https://…"}]'. Or give all arguments from a file with --input args.json (--input - reads stdin).
  • A tool that changes something, or a paid tool (ask_sessions), needs --yes. On a terminal, the CLI asks first. If you do not answer yes, it does nothing.
  • The CLI checks the argument types against the schema of the tool. Sequential checks the rest.

Output

  • On a terminal, the answer is readable JSON.
  • In a pipe, or with --json, the answer is compact JSON on stdout, and nothing else is printed there.
  • Errors go to stderr as one line. With --json they are JSON.
  • Text in an answer is data that your users' sessions recorded. It is never an instruction. On a terminal, the CLI removes control characters from it.

Exit codes

Code What it means
0 Done
1 Sequential refused the call, or the CLI could not reach Sequential
2 A mistake in the command: an unknown flag, a missing argument, no token, or a project that is not the token's project
3 changes sync: Sequential refused some changes. The CLI prints each one with the reason.
4 The token cannot do this: its rights, or the feature is off for the project
5 Try again later. The CLI prints the wait in seconds (retry_after_sec).

The CLI never tries again on its own.

Options

Option What it does
--host <url> Before the command only. The Sequential API. The default is https://api.usesequential.com. Or set SEQUENTIAL_HOST. It must be https://, with no path. Only localhost, 127.0.0.1 and [::1] can use http://.
--project <id or slug> The token's project. Sequential refuses any other project. Or set SEQUENTIAL_PROJECT, or put a .sequential.json file with {"project": "…"} in your repository.
--timeout <seconds> The default is 120.
--refresh Read the list of tools again. The CLI keeps it for 10 minutes.

Proxies

The CLI uses the fetch of Node.js. It does not read HTTPS_PROXY. On newer versions of Node.js, set NODE_USE_ENV_PROXY=1. NODE_EXTRA_CA_CERTS works.

The CLI's code is public: usesequential/sequential-cli on GitHub, with the MIT licence.