> For the complete documentation index, see [llms.txt](https://developer.celigo.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.celigo.com/cli/getting-started/profiles.md).

# Profiles & regions

A **profile** is a named set of credentials — a token plus a base URL, plus per-profile defaults. One binary, many accounts.

Profiles live in `~/.celigo/config.json`:

```json
{
  "active_profile": "prod",
  "profiles": {
    "prod": {
      "api_token": "abc…xyz",
      "base_url": "https://api.integrator.io",
      "default_format": "table"
    },
    "eu": {
      "api_token": "def…qrs",
      "base_url": "https://api.eu.integrator.io"
    },
    "au": {
      "api_token": "ghi…tuv",
      "base_url": "https://api.au.integrator.io"
    },
    "qa": {
      "api_token": "jkl…wxy",
      "base_url": "https://api.integrator.io",
      "default_format": "json"
    }
  }
}
```

`prod` and `qa` share a base URL because environments do not get their own hostname. Every environment has its own token, so give each one its own profile.

File mode is `0600` on Unix. Tokens are redacted on any CLI output.

## Managing profiles

All profile management happens through `celigo profile <subcommand>`. Full syntax and flags for each subcommand live in the [command reference](/cli/commands/profile.md). In short: `profile add` creates one, `profile use` switches the active profile, `profile list` shows them, and `profile rename` / `profile delete` rename and delete them.

There is no `profile edit`. To change a field on an existing profile, either `celigo config set <key> <value>` against it (see the [`config` command reference](/cli/commands/config.md)) or `profile delete` + `profile add` to rebuild it.

## Selecting a profile

A command resolves its profile in three levels: `--profile` > `CELIGO_PROFILE` > the active profile.

```bash
# Per-command, overrides everything
celigo --profile eu integrations list

# Per-session: bind THIS shell, agent session, or CI job to a profile
export CELIGO_PROFILE=eu
celigo integrations list

# Machine-wide default
celigo profile use eu
celigo integrations list
```

The active profile is one machine-wide value in `~/.celigo/config.json`, read fresh by every invocation — so `celigo profile use` in one terminal redirects every un-pinned command in every other terminal and agent session on the machine. Since celigo-cli 2026.9.1 the command says so on stderr and prints the `export CELIGO_PROFILE=<name>` line that binds one session instead. `CELIGO_PROFILE` is the per-session binding (the `AWS_PROFILE` / `KUBECONFIG` model): a session that must stay on one account sets it once. The `config` commands and `profile show` read and write the selected profile, whichever level selected it.

A `--profile` or `CELIGO_PROFILE` value that names no profile is an error before any request — `Profile 'x' does not exist. Available: a, b (run 'celigo profile list').` — even when `CELIGO_API_TOKEN` or `--token` is set. Until celigo-cli 2026.9.1 an unknown name resolved to an empty profile and failed later with a hint that, followed, wrote the token into the active profile or created the misspelled one. The commands that manage local state never check (`profile`, `config`, `skills`) and neither do the offline tree verbs (`status`, `lint`, `resolve`), so `config set … --profile new` can still create a profile; `profile whoami` does check.

Every command that writes to the account first says which one, on stderr: `celigo: profile 'acme-sandbox' → api.integrator.io` (profile name and API host). Structural commands (`create`/`update`/`delete`/`set`, clone and install, `push` — a `push --dry-run` included) print it before running; operational actions such as `flows run` or `jobs cancel` print it right before their first write. Reads print nothing, and so do `profile`, `config`, `skills`, `docs`, and `feedback`. Stdout is untouched, so `--jq` and JSON piping see only the response; confirmation prompts carry the same label (`[profile 'acme-sandbox' → api.integrator.io] Delete flow 123? [y/N]`). There is no opt-out.

### Rules for agents driving the CLI

An agent once carried a stale `--profile` for a day and wrote to the wrong account. Four rules prevent that:

1. **Check the target before the first mutating command of a session.** Run `celigo profile whoami`, and read the `celigo: profile '…' → …` stderr line every write prints. If it is not the account you mean, stop.
2. **Bind the session once** with `export CELIGO_PROFILE=<name>` instead of repeating `--profile` on every call — a repeated flag is exactly how a stale value survives.
3. **Never run `config set api_token` in response to an error.** `Profile 'x' does not exist` means the NAME is wrong, not the token; writing a token "fixes" it by creating the misspelled profile or overwriting another profile's token.
4. **`celigo profile list` shows what exists.** Pick from it rather than guessing a name.

## Regions

| Region | API base URL                   |
| ------ | ------------------------------ |
| US     | `https://api.integrator.io`    |
| EU     | `https://api.eu.integrator.io` |
| AU     | `https://api.au.integrator.io` |
| CA     | `https://api.ca.integrator.io` |

Create one profile per region:

```bash
celigo profile add us --api-token "$US_TOKEN" --api-base-url https://api.integrator.io
celigo profile add eu --api-token "$EU_TOKEN" --api-base-url https://api.eu.integrator.io
celigo profile add au --api-token "$AU_TOKEN" --api-base-url https://api.au.integrator.io
celigo profile add ca --api-token "$CA_TOKEN" --api-base-url https://api.ca.integrator.io
```

Tokens are **not** interchangeable — a token from one region authenticating against another region's base URL will return `401 Unauthorized`.

See [Environments & regions](https://developer.celigo.com/api/getting-started/environments) in the API section for the full context.

## Per-profile config keys

| Field            | Typical use                                                                              |
| ---------------- | ---------------------------------------------------------------------------------------- |
| `api_token`      | Bearer token.                                                                            |
| `base_url`       | API base URL; defaults to `https://api.integrator.io`.                                   |
| `default_format` | `json` for CI, `table` for humans.                                                       |
| `mode`           | Permission mode: `read`, `operate`, or `full` (default).                                 |
| `account_alias`  | This account's MCP alias, for the local tree (`profile add --account-alias`).            |
| `list_fields`    | `default` or `all`: whether `list` commands return the projection or complete documents. |

Edit any of these with `--profile <name> config set <key> <value>` (`config` writes the selected profile: `--profile`, else `CELIGO_PROFILE`, else active):

```bash
celigo --profile ci config set default_format json
celigo --profile ci config set mode read
```

## Permission modes

* **`full`** (default) — create/update/set/delete all resources.
* **`operate`** — read + operational actions (run flows, retry and resolve errors, cancel jobs, toggle debug, invoke) + `set` on a narrow allow-list of fields (`disabled`, `debugUntil`, `debugDate`, `schedule`, `autoResolveAt`, `logging.debugUntil`). Useful for operational profiles that can pause flows but not change their configuration. A dotted sub-path is allowed only under `schedule` (for example `schedule.cron`) — the one allowed root that is an object; `disabled.foo=1` is refused rather than turning the boolean into an object.
* **`read`** — read only. `list`, `get`, `account`, `config`, `profile` are allowed; any mutation is rejected before the request leaves your machine.

A few operations use `POST` but only read or transform data, so `read` mode allows them: marketplace browsing, export previews and `exports invoke`, connection pings, lookup-cache reads, execution-log and EDI transaction queries, signed download URLs, multi-select audit queries, and every [processors](/cli/commands/processors.md) transform. None of them create, run, or change anything on the account.

The mode is the profile's `mode` unless `CELIGO_MODE` is set, which overrides it for the session. Since celigo-cli 2026.9.1 a refusal names where the mode came from and the switch that works:

```
Current mode: read. Switch with 'celigo config set mode full' or use a different profile.
Current mode: read (from CELIGO_MODE). Set CELIGO_MODE=full (the environment variable overrides the profile's mode) or unset it.
```

The second form matters because `celigo config set mode full` changes nothing while `CELIGO_MODE` is exported. The HTTP client's refusal follows the same rule: `Read mode: blocked PUT v1/flows/<id>. Switch with 'celigo config set mode operate' (or 'full'), or use a different profile.` for a profile-set mode, `Read mode (from CELIGO_MODE): blocked …` when the environment set it.

## CI recipes

### GitHub Actions

```yaml
- name: Celigo deploy
  env:
    CELIGO_API_TOKEN: ${{ secrets.CELIGO_PROD_TOKEN }}
    CELIGO_BASE_URL: https://api.integrator.io
  run: |
    npx --yes @celigo/celigo-cli@latest integrations list --format json > integrations.json
```

No profile file needed — pass the env vars. The same holds for a pulled local tree: a token plus `CELIGO_BASE_URL` is a complete identity for `pull`, `diff`, and `push`, because a tree is bound to its account (host and token owner), not to a profile name. See [Workflow](/cli/local-tree/workflow.md).

### GitLab CI

```yaml
deploy-celigo:
  image: node:22
  variables:
    CELIGO_BASE_URL: https://api.integrator.io
  script:
    - npm install -g @celigo/celigo-cli
    - celigo integrations list
```

Set `CELIGO_API_TOKEN` as a masked CI variable.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developer.celigo.com/cli/getting-started/profiles.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
