> For the complete documentation index, see [llms.txt](https://docs.tryterra.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tryterra.co/developer-tools/terra-cli/terra-cli.md).

# Terra CLI

Set up, manage, and debug your Terra integration from the terminal.

Set up and debug your Terra integration from the terminal: environments, credentials, providers, webhooks, users, and event replay. Your coding agent can run it too. See [Coding agents](/developer-tools/terra-cli/coding-agents.md).

## Before you begin

Open a terminal and have your [Terra account](https://dashboard.tryterra.co) ready.

## Step 1: Install Terra CLI

Choose an installation method:

{% tabs %}
{% tab title="Native Install (Recommended)" %}
**macOS and Linux:**

```bash
curl -fsSL https://cli.tryterra.co/install.sh | sh
```

Run the command shown under `For this terminal` in the installer output to make `terra` available in your current terminal.

On Windows, use the npm tab.
{% endtab %}

{% tab title="npm" %}
**macOS, Linux, and Windows:**

Requires Node.js 18 or later.

```bash
npm install -g @tryterra/cli
```

{% endtab %}

{% tab title="Homebrew" %}
**macOS:**

```bash
brew install tryterra/tap/terra
```

{% endtab %}
{% endtabs %}

Check the installation:

```bash
terra version
```

See [Installation](/developer-tools/terra-cli/installation.md) for updates, shell completion, and installation through a coding agent.

## Step 2: Log in

```bash
terra login
```

The CLI opens your browser and prints a pairing code. Approve it in the Terra dashboard to finish logging in.

To use Terra with a coding agent, also run:

```bash
terra agent setup
```

See [Coding agents](/developer-tools/terra-cli/coding-agents.md) for details. For CI, see [Authentication](/developer-tools/terra-cli/authentication.md).

## Step 3: Pick an environment

List your environments, then select one by name:

```bash
terra environments list
terra environments use Production
```

Replace `Production` with your environment's name. The CLI uses this environment for subsequent commands, so you don't need to pass `--env` each time.

## Step 4: Run your first command

```bash
terra users list
```

This lists users in the selected environment. Output is a table on a terminal and JSON when piped. See [Output and scripting](/developer-tools/terra-cli/output-and-scripting.md).

## Start from an example app

```bash
terra examples list
terra examples clone unified-api-web-app my-app
```

Downloads a complete app into a new directory and returns the next steps. No Terra login is required. Follow the app's README to install dependencies, configure credentials, and run it. See [Example apps](/developer-tools/example-apps/example-apps.md).

## Common tasks

The examples below use the selected environment. Credential reads and data API key lookup require `keys:read`, which default login leaves out. See [Authentication](/developer-tools/terra-cli/authentication.md) for choosing scopes and [Raw API requests](/developer-tools/terra-cli/raw-requests.md#the-data-api) for supplying a key directly.

### Set up an environment

```bash
terra unified-api sources enable GARMIN
# Garmin appears in the auth widget and starts syncing to your destinations

terra unified-api destinations create --type webhook --url https://example.com/hook
# prints the new destination's id

terra environments retrieve-api-key
# prints the dev-id, API key, and webhook signing secret
```

### Send a user through auth, then check it worked

Create a session with the [Terra widget](https://docs.tryterra.co/unified-api/user-authentication/implementation-terra-widget). The `generateWidgetSession` command below is for legacy integrations. Terra accounts created after 3 September 2026 receive HTTP 410 from that endpoint and must use `POST https://access.tryterra.co/api/widget/session` instead.

```bash
terra data-api /auth/generateWidgetSession -X POST -d reference_id=user-42
# returns a widget URL to open for the user

terra users list --reference-id user-42
# one row per connection: user id, provider, active, created at

terra events list --reference-id user-42 --data-type auth
# auth delivery metadata; retrieve the payload to inspect its contents
```

### Find out why a webhook never arrived, and resend it

```bash
terra events list --user-id 8f2a1c00-0000-4000-8000-000000000001 --outcome failed
# one row per failed delivery: event id, data type, provider, HTTP status, sent at

terra events retrieve-payload evt_123
# the body Terra tried to send

terra events resend --event-id evt_123 --event-type sleep --user-id 8f2a1c00-0000-4000-8000-000000000001
# queues the stored payload for redelivery

terra events retrieve evt_123
# inspect delivery metadata after the resend
```

Use the row's `event_id`, `user_id`, and `data_type` for the resend flags. Acceptance is asynchronous and does not mean the destination received it. `events list` defaults to the last 7 days, or 14 days with `--event-id`. Payload retrieval requires `payloads:read`, and stored payloads expire after about 14 days. Replace the sample identifiers in these examples with your own.

### Inspect connection and delivery statistics

```bash
terra users stats
terra users stats --view full
terra events stats
terra events stats --view full --granularity hour --compare previous_period
```

The default `basic` view returns summary metrics. `full` adds time buckets and breakdowns. User statistics default to the last three months; event statistics default to the last 24 hours. Use `--since` and `--until` to choose a window. Statistics use an inclusive start and exclusive end, and full views allow at most 1,500 buckets. See each command's help for its metrics and limits.

### Pull a user's data

```bash
terra data-api /sleep -q user_id=8f2a1c00-0000-4000-8000-000000000001 -q start_date=2026-08-01 -q to_webhook=false
# sleep sessions as JSON, printed here instead of sent to your destination
```

Drop `to_webhook=false` to send the data to your destination instead, which is how you backfill a new user's history.

### Rotate an API key

```bash
terra environments rotate-api-key
# prints the new key; the old one stops working immediately
```

### Turn on a health score and read the results

```bash
terra unified-api scores update readiness --active
# readiness scores appear in payloads for users with eligible data

terra unified-api scores history list --score readiness --user-id 8f2a1c00-0000-4000-8000-000000000001
# one row per computed score: value, time window, provider
```

### Push a planned workout to a user's calendar

```bash
terra data-api /workouts -X POST --body-file workout.json
# returns the workout_id

terra data-api /workouts/1024/plan -X POST -q user_id=8f2a1c00-0000-4000-8000-000000000001 -d planned_date=2026-09-15
# schedules it on the user's calendar at their connected provider; prints the planned workout id, the provider workout id, and any warnings
```

Use the numeric `workout_id` returned by creation in place of `1024`.

### List a user's planned workouts

```bash
terra data-api /plannedWorkouts -q user_id=8f2a1c00-0000-4000-8000-000000000001 -q start_date=2026-09-08 -q end_date=2026-09-30
# one item per planned workout: planned_date, provider_workout_id, the full workout body, and any warnings

terra data-api /plannedWorkouts -q user_id=8f2a1c00-0000-4000-8000-000000000001 -i
# with no window, provider-side workouts default to the trailing 30 days; -i shows X-Terra-Provider-Fetch
```

The list covers workouts you pushed through Terra and workouts the athlete created on the provider, in the same shape.

### Check where a lab report was delivered

```bash
terra data-api /lab-reports/297405620317847552
# the session's status and its parsed results

terra data-api /lab-reports/297405620317847552/deliveries
# one row per destination: status, attempt count, last error
```

### Ask the docs

```bash
terra docs ask --question "how do I verify a webhook signature?"
# an answer with links to the docs pages it came from
```

See [Ask the docs](/developer-tools/terra-cli/ask.md).

## Find a command

`terra --help` lists the groups, `terra <command> --help` describes one, and `terra reference` prints everything. See [Command reference](/developer-tools/terra-cli/command-reference.md).

## Safe by default

* `--dry-run` sends an authenticated preview request on supported commands, without committing the change.
* Credential endpoints print the secrets returned by the API; read scopes control access.
* Destructive commands confirm first, or need `--yes` without a terminal.

See [Guardrails](/developer-tools/terra-cli/guardrails.md).

## Get help

Open a [GitHub issue](https://github.com/tryterra/terra-cli/issues) with the output of `terra version` and the failing command run with `--show-headers`. Credentials are redacted. Account, billing, and contract questions go to your Terra support channel, not the public tracker.

{% hint style="danger" %}
Security issues: follow the [security policy](https://github.com/tryterra/terra-cli/security/policy), not a public issue.
{% endhint %}
