> 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/raw-requests.md).

# Raw API requests

Reach any Terra admin API or data API endpoint by path with terra admin-api and terra data-api.

`terra admin-api <path>` sends a request to any endpoint on the admin API, including ones without a generated command. `terra data-api <path>` is the same command pointed at the data API, which has no generated commands at all.

```bash
terra admin-api /me
terra admin-api /environments -q limit=5
terra admin-api /environments -X POST -d dev_id=dev-new -d name=Staging
terra admin-api /company -X PATCH --body '{"display_name":"Acme"}'
terra admin-api /tokens/tok_123 -X DELETE
```

The path is relative to the configured base URL and must start with `/`.

Reach for a generated command first. It validates input before sending, formats output, and knows which operations are destructive. Use `terra admin-api` for endpoints with no command yet, or to see exactly what the API returns.

## Two APIs

|            | Admin API                                                                                           | Data API                                                 |
| ---------- | --------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| Covers     | Your account: environments, API keys, providers, destinations, users, webhook events, team, billing | Your users' health data and the flow that connects them  |
| Credential | Personal access token from `terra login`                                                            | Environment API key, fetched for you by `terra data-api` |
| Commands   | Generated commands such as `terra environments list`, plus `terra admin-api <path>`                 | `terra data-api <path>` only                             |

Most commands use the admin API. The two credentials are not interchangeable.

## Which endpoints have a command

```bash
terra admin-api list             # admin endpoints and their commands
terra admin-api list --uncovered  # only endpoints with no command
terra admin-api list --data-api   # the data API's endpoints
```

Name a path to see what one endpoint takes. With `--format json`, that is the full description: parameters, body fields, and response fields.

```bash
terra admin-api list /me --format json
terra admin-api list --data-api /sleep --format json
```

Endpoint discovery and completion use the API description bundled with your CLI version. They can lag the server; a path does not need to appear in this catalog for a raw request to reach it.

## Method

`-X`, `--method` takes GET, POST, PUT, PATCH, or DELETE, and defaults to GET. A body flag does not change the method. `terra admin-api /environments -d dev_id=x` is a usage error rather than an inferred POST, so a command that reads like a query cannot turn out to be a mutation.

## Body, query, and headers

Three ways to send a body. They are mutually exclusive.

```bash
-d key=value            # repeatable, builds a flat JSON object
--body '{"a":{"b":1}}'  # raw JSON, for anything nested
--body-file body.json   # from a file, or - for stdin
```

```bash
-q key=value    # query parameter, repeatable
-H name:value   # header, repeatable
```

## Validation

Raw commands send paths and methods without checking them against the bundled endpoint catalog. The server decides whether the route and supplied values are valid, so endpoints added after your CLI version are reachable too.

Request syntax is still checked: paths must start with `/`, and GET requests cannot carry a body. Neither command accepts `--no-verify` or `--dry-run`. For a preview, use a generated command that offers `--dry-run`. See [Guardrails](/developer-tools/terra-cli/guardrails.md#preview-a-request).

## Pagination and inspection

`--paginate` collects a cursor-paginated list and renders one document in the selected format. It buffers records before printing, including for `--format ndjson`. It needs `--method GET`. `--max-pages` caps it at 10 pages by default, and `0` removes the limit.

```bash
terra admin-api /environments --paginate
```

`-i` prints the status line and response headers to stderr, so the body stays pipeable. They print for a failed request too.

```bash
terra admin-api /me -i | jq .token_id
```

`--jq` filters the response. There is no `--select` on the raw commands, because the response fields are not known for every path.

A DELETE confirms before it is sent. Pass `--yes` to skip the prompt, which is required where there is no terminal.

## The data API

The data API is the other half of Terra: the wearable data your users' providers send (activity, sleep, body, daily, nutrition, workouts) and the flow that links a user to a provider.

```bash
terra data-api /integrations
terra data-api /userInfo -q user_id=8f2a1c00-0000-4000-8000-000000000001
terra data-api /sleep -q user_id=8f2a1c00-0000-4000-8000-000000000001 -q start_date=2026-08-01 -q to_webhook=false
terra data-api /auth/generateWidgetSession -X POST -d reference_id=user-42
```

The identifiers above are examples; replace them with your user's ID. `/auth/generateWidgetSession` is a legacy endpoint. Terra accounts created after 3 September 2026 receive HTTP 410 and must use `POST https://access.tryterra.co/api/widget/session` instead. See [Terra widget setup](https://docs.tryterra.co/unified-api/user-authentication/implementation-terra-widget).

Two things differ from `terra admin-api`.

**Requests target one environment.** The command takes `--env` and resolves it as any generated command does: the flag, then `TERRA_ENV`, then the configured default.

**The credential is the environment's API key**, not your personal access token. The CLI fetches the key for you, which needs the `keys:read` scope. The default `terra login` leaves that scope out, so either log in again with `terra login --scope keys:read`, or set `TERRA_API_KEY` to supply the key directly and skip the lookup. The key is only ever sent, never printed.

{% hint style="warning" %}
Reading data needs `-q to_webhook=false`. The API's default is to send the response to your configured webhook and answer with an acknowledgement. The CLI recognizes that acknowledgement and says so on stderr, but it does not add the parameter for you.
{% endhint %}

`TERRA_DATA_BASE_URL` points the data API somewhere else. Without it the address is derived from the configured base URL.
