> ## Documentation Index
> Fetch the complete documentation index at: https://docs.openlayer.com/llms.txt
> Use this file to discover all available pages before exploring further.

# init

> Set up Openlayer in your project with a single guided command

The `openlayer init` command is a guided setup flow. It signs you in, creates or links an
[Openlayer project](https://docs.openlayer.com/workspace-and-projects/creating-and-loading-projects.md), and then sets up
development mode, monitoring, or both — all in your current directory.

Because `init` creates and links the project itself, the recommended first-run flow is
[`install`](https://docs.openlayer.com/api-reference/cli/commands/install) → `init` →
[`push`](https://docs.openlayer.com/api-reference/cli/commands/push). You do not need a separate
[`openlayer login`](https://docs.openlayer.com/api-reference/cli/commands/login) or
[`openlayer link`](https://docs.openlayer.com/api-reference/cli/commands/link) step.

> [!NOTE]
>
> `openlayer init` requires Openlayer CLI **v1.13.0** or later. Check your
> version with `openlayer --version` and upgrade with [`openlayer
>     update`](https://docs.openlayer.com/api-reference/cli/commands/update.md).

## Usage

```bash theme={null}
openlayer init [flags]
```

Run it from the root of the project you want to connect to Openlayer:

```bash theme={null}
cd my-ai-app
openlayer init
```

## What init does

Every run begins with the same three steps, then asks what you want to set up:

**1. Check repository**

`init` writes and edits files, so it first checks that you are in a Git repository with a
clean working tree. If the working tree has local changes, it lists them and asks whether
to continue. If the directory is not a Git repository at all, it warns you that its edits
will not be easy to revert.

**2. Sign in**

`init` authenticates you, so you do not need to run `openlayer login` first. See
[Authentication](#authentication) for the order of preference and the on-prem prompt.

**3. Link project**

If the directory is already linked to a project that still exists, this step is skipped.

Otherwise `init` lists the projects in your workspace and asks whether to link to an
existing one or create a new one. Creating a new project asks for a name (defaulting to
the directory name) and a [project type](#project-types).

Either way, `init` writes `.openlayer/config.json` with the project and workspace ids and
adds `.openlayer` to your `.gitignore`.

**4. Choose what to set up**

Finally, `init` asks which track to run — see
[Choosing what to set up](#choosing-what-to-set-up).

If a step fails, `init` asks whether to **retry** it, **skip** it, or **quit**, so one failed
step does not discard the work already done.

## Choosing what to set up

| Choice | What it sets up |
| - | - |
| **Development mode** | Writes `openlayer.json`, then pushes your first commit |
| **Monitoring mode** | Instruments your app with tracing, then verifies traces arrive |
| **Both** | Runs monitoring first, then development mode |

**Both** runs monitoring before development mode on purpose: the live traces monitoring
captures can later be pulled into development-mode datasets. If you pick a single track,
`init` offers to continue into the other one when it finishes.

### Development mode track

**1. Set up evaluations**

Choose how your `openlayer.json` gets written: with a coding agent that `init` detects on
your machine (Claude Code, Codex, Copilot CLI, or Gemini CLI), with a deterministic
[starter scaffold](#project-types), with a prompt copied to your clipboard for your own
coding agent, or manually by following the
[openlayer.json guide](https://docs.openlayer.com/development/openlayer-json.md).

Skipped when an `openlayer.json` already exists.

**2. Push first commit**

Asks before running [`openlayer push`](https://docs.openlayer.com/api-reference/cli/commands/push) with the commit
message `Initial commit from openlayer init`. Skipped when there is no `openlayer.json`
to push.

**3. Automate in CI**

Optionally writes a starter `.github/workflows/openlayer.yml` that pushes to Openlayer on
your pull requests, then reminds you to add `OPENLAYER_API_KEY` and `OPENLAYER_PROJECT_ID`
as repository secrets. See the [GitHub Actions guide](https://docs.openlayer.com/guides/gh-actions.md). Skipped when
that workflow file already exists.

### Monitoring mode track

**1. Create monitoring pipeline**

Pick an existing inference pipeline to receive your traces, or create a new
one (named `production` by default).

**2. Write local credentials**

Writes `.env.openlayer` with your API key and inference pipeline id, and
adds it to your `.gitignore`.

**3. Instrument application**

Adds Openlayer tracing to your application — with a detected coding agent,
with a prompt copied to your clipboard for your own agent, or manually by
following the [instrumentation guide](https://docs.openlayer.com/monitoring/instrument.md).

**4. Verify traces**

Asks you to run your application, then polls the pipeline until a new trace
actually arrives, so your setup is confirmed rather than assumed. It then
reminds you to add the API key to your production environment.

> [!WARNING]
>
> The coding-agent option installs the Openlayer skill into the agent and runs
> it with permission to edit your code. `init` always asks for confirmation
> before doing so, and the "Check repository" step warns you first if your
> working tree is dirty. If you would rather not hand over write access, choose
> the starter scaffold, the copy-a-prompt option, or the manual path.

## Project types

When `init` creates a new project it asks what kind of AI task it is. The choice is recorded
as the project's `taskType` and determines the shape of the scaffolded `openlayer.json`:

| Project type | `taskType` value |
| - | - |
| LLM | `llm-base` |
| Tabular Classification | `tabular-classification` |
| Tabular Regression | `tabular-regression` |
| Text Classification | `text-classification` |

The prompt only appears when you create a new project. Linking to an existing project reuses
that project's type.

### Scaffolded configuration

If you choose the starter scaffold in the "Set up evaluations" step, `init` writes an
`openlayer.json` seeded for your project type plus a matching `validation_dataset.csv`:

```json LLM theme={null}
{
  "taskType": "llm-base",
  "model": null,
  "datasets": [
    {
      "label": "validation",
      "name": "validation",
      "path": "validation_dataset.csv",
      "groundTruthColumnName": "",
      "inputVariableNames": ["input"],
      "metadata": null,
      "outputColumnName": "output"
    }
  ],
  "metrics": {
    "settings": null,
    "custom": null
  }
}
```

```json Tabular Classification theme={null}
{
  "taskType": "tabular-classification",
  "model": null,
  "datasets": [
    {
      "label": "validation",
      "name": "validation",
      "path": "validation_dataset.csv",
      "groundTruthColumnName": "label",
      "inputVariableNames": [],
      "metadata": null,
      "outputColumnName": "prediction"
    }
  ],
  "metrics": {
    "settings": null,
    "custom": null
  }
}
```

```json Tabular Regression theme={null}
{
  "taskType": "tabular-regression",
  "model": null,
  "datasets": [
    {
      "label": "validation",
      "name": "validation",
      "path": "validation_dataset.csv",
      "groundTruthColumnName": "target",
      "inputVariableNames": [],
      "metadata": null,
      "outputColumnName": "prediction"
    }
  ],
  "metrics": {
    "settings": null,
    "custom": null
  }
}
```

```json Text Classification theme={null}
{
  "taskType": "text-classification",
  "model": null,
  "datasets": [
    {
      "label": "validation",
      "name": "validation",
      "path": "validation_dataset.csv",
      "groundTruthColumnName": "label",
      "inputVariableNames": ["text"],
      "metadata": null,
      "outputColumnName": "prediction"
    }
  ],
  "metrics": {
    "settings": null,
    "custom": null
  }
}
```

The accompanying `validation_dataset.csv` is a two-row placeholder using the same column
names — for example `input,output` for LLM projects and `feature_1,feature_2,label,prediction`
for tabular classification.

> [!NOTE]
>
> The scaffold deliberately leaves `"model": null`, which is valid: it describes
> a project that only uploads datasets. Replace the placeholder dataset with
> your own, and add a `model` section if you want Openlayer to run your model
> and generate outputs. See [openlayer.json](https://docs.openlayer.com/development/openlayer-json.md) and
> [Configuring output generation](https://docs.openlayer.com/development/configuring-output-generation.md).

If you use a coding agent instead of the scaffold, it writes an `openlayer.json` tailored to
your codebase rather than this placeholder.

## Authentication

`init` handles sign-in itself — a separate [`openlayer login`](https://docs.openlayer.com/api-reference/cli/commands/login)
is not required. It tries these in order:

1. **`OPENLAYER_API_KEY` from your environment.** If this variable is set, every API call uses
   it, overriding both saved profiles and browser sign-in. `init` verifies the key, tells you
   which account and workspace it belongs to, and asks whether to continue.
2. **Credentials from a previous sign-in.** If your CLI profile still works, `init` shows the
   account and asks whether to keep using it.
3. **A fresh sign-in.** `init` asks whether you are on Openlayer SaaS or a self-hosted /
   on-prem deployment — prompting for your server URL in the on-prem case — then offers
   browser sign-in (recommended) or pasting an
   [API key](https://docs.openlayer.com/workspace-and-projects/find-your-api-key.md). Browser sign-in shows a verification
   code and opens your browser, where you can also create a new Openlayer account. The
   resulting credentials are saved to your CLI profile.

In [non-interactive mode](#non-interactive-use) there is no sign-in prompt: you must provide
`OPENLAYER_API_KEY` or already have a working profile, or `init` fails.

## Files created

| Path | Created by | Notes |
| - | - | - |
| `.openlayer/config.json` | Link project (every run) | Records the project and workspace ids. Added to `.gitignore`. |
| `.gitignore` | Link project, local credentials | Entries are appended under an `# Openlayer` header. |
| `openlayer.json` | Development mode track | Your development-mode configuration. |
| `validation_dataset.csv` | Development mode track | Placeholder dataset, written with the starter scaffold. |
| `.env.openlayer` | Monitoring mode track | Contains your API key and pipeline id. Gitignored — never commit it. |
| `.github/workflows/openlayer.yml` | Development mode track | Starter GitHub Action. Only written if you opt in. |

## Re-running init

`init` is safe to re-run: each step checks whether it is already satisfied and skips itself,
reporting why. It will not create a duplicate project or overwrite an existing configuration.

* Already linked to a project → the "Link project" step is skipped.
* `openlayer.json` already exists → the "Set up evaluations" step is skipped, so your config
  is never clobbered.
* `.github/workflows/openlayer.yml` already exists → the "Automate in CI" step is skipped.

To regenerate one of those files, delete it and re-run `init`. There is no `--force` flag.

The monitoring track's pipeline step is the one exception: interactive runs ask which pipeline
to use, but see the [non-interactive caveat](#non-interactive-use) before re-running it in CI.

## Flags

| Flag | Default | Description |
| - | - | - |
| `--project-id` | `""` | Project id to link. Required in non-interactive mode. |
| `--mode` | `""` | Which track(s) to set up non-interactively: `dev`, `monitoring`, or `both`. |
| `--agent` | `""` | Coding agent to use non-interactively: `claude`, `codex`, `copilot`, or `gemini`. |
| `--scaffold` | `false` | Legacy shorthand for `--mode both`. Only has an effect when `--mode` is unset. |
| `--push` | `false` | Run `openlayer push` in the dev track non-interactively. |
| `--github-action` | `false` | Write a GitHub Action in the dev track non-interactively. |

All flags exist to drive `init` without prompts. In an interactive terminal you can ignore
them — `init` asks about each of these instead.

> [!WARNING]
>
> `--scaffold` predates `--mode` and is only consulted when `--mode` is **not** given, where it
> means "monitoring **and** dev" rather than "dev". So:
>
> * `--scaffold` on its own runs **both** tracks — including monitoring, which writes
>   `.env.openlayer`.
> * `--mode monitoring --scaffold` is **monitoring only**; the `--scaffold` flag is silently
>   ignored and no `openlayer.json` is written.
> * `--mode dev` already writes `openlayer.json` on its own, so adding `--scaffold` changes
>   nothing.
>
> Prefer `--mode dev`, `--mode monitoring` or `--mode both` and leave `--scaffold` alone.

[Global options](https://docs.openlayer.com/api-reference/cli/global-options.md) such as `--api-key`, `--profile-name` and
`--output-mode` also apply.

## Non-interactive use

`init` decides whether to prompt by looking at its environment rather than at a flag. It runs
interactively only when `--output-mode` is `terminal` (the default) **and** its standard output
is a terminal.

> [!WARNING]
>
> Passing `--output-mode ci`, piping `init` into another command, or redirecting
> its output to a file all switch it to non-interactive mode, where it never
> prompts and fails instead of asking.

In non-interactive mode:

* **Credentials are required up front.** Set `OPENLAYER_API_KEY` (or use `--api-key`), or have
  a profile from a previous `openlayer login`.
* **`--project-id` is required.** `init` will not create a project for you without prompts.
* **`--mode` defaults to `monitoring`.** This is the biggest difference from an interactive
  run. If you want development-mode setup, pass `--mode dev` (or `--mode both`) explicitly —
  otherwise no `openlayer.json` is written. See the
  [`--scaffold` caveat](#flags) if you are using that flag instead.
* **Everything that edits code or changes your account is opt-in.** Instrumentation only runs
  with `--agent`, the first push only runs with `--push`, and the GitHub Action is only written
  with `--github-action`.
* **Monitoring runs are not fully idempotent.** The pipeline step reuses an existing inference
  pipeline only when the project has exactly one. With two or more and no prompt available, it
  creates another pipeline named `production` on every run. Interactive runs always ask.

Missing either of the first two is a hard failure, reported on standard output:

```bash theme={null}
Init failed: no valid credentials: set OPENLAYER_API_KEY or run `openlayer login`
Init failed: non-interactive mode requires --project-id
```

> [!NOTE]
>
> The monitoring track writes `.env.openlayer`, containing your API key, into
> the working directory. That means `--mode monitoring`, `--mode both`, a bare
> `--scaffold`, and passing no track flag at all. In shared CI runners, prefer
> `--mode dev` — or make sure the workspace is not archived as a build artifact.

### Example: bootstrapping development mode in CI

```yaml theme={null}
name: Openlayer
on: pull_request
jobs:
  openlayer:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install the Openlayer CLI
        run: curl -o- "https://downloads.openlayer.com/cli/install/linux_64.sh" | sh
      - name: Set up development mode and push
        env:
          OPENLAYER_API_KEY: ${{ secrets.OPENLAYER_API_KEY }}
          OPENLAYER_PROJECT_ID: ${{ secrets.OPENLAYER_PROJECT_ID }}
        run: |
          openlayer init \
            --output-mode ci \
            --mode dev \
            --project-id "$OPENLAYER_PROJECT_ID" \
            --push
```

> [!TIP]
>
> For a repository that is already configured — `openlayer.json` committed and
> `OPENLAYER_PROJECT_ID` set — you do not need `init` in CI at all. Just run
> [`openlayer push`](https://docs.openlayer.com/api-reference/cli/commands/push). Reach for `init` in
> automation when you are bootstrapping a project that has no configuration yet.
> See the [GitHub Actions guide](https://docs.openlayer.com/guides/gh-actions.md) for the standard CI setup.

## Exit codes

| Code | Meaning |
| - | - |
| `0` | Setup completed. |
| `1` | Setup failed, or you quit the wizard before it finished. |

Quitting and failing share exit code `1`, so scripts cannot distinguish them. The message on
standard output does: `Init aborted.` for a deliberate quit, `Init failed: <reason>` for an
error.

## init vs link

Both commands connect a directory to an Openlayer project and both write
`.openlayer/config.json`. The difference is the order of operations:

* `init` **asks** for the project type, then writes an `openlayer.json` to match. Use it when
  you have nothing set up yet.
* `link` **reads** the task type from an `openlayer.json` that is already in the directory. Use
  it when your configuration exists and you only need the link.

| Situation | Use |
| - | - |
| Setting up Openlayer in a project for the first time | `openlayer init` |
| You only want to link a directory, or re-point it to another project | [`openlayer link`](https://docs.openlayer.com/api-reference/cli/commands/link) |
| CI/CD against a project that already exists | Set `OPENLAYER_PROJECT_ID` — see [global options](https://docs.openlayer.com/api-reference/cli/global-options.md) |

## Related guides

* [Push and poll using the Openlayer CLI](https://docs.openlayer.com/guides/cli-push.md)
* [How can I use GitHub Actions with Openlayer?](https://docs.openlayer.com/guides/gh-actions.md)
* [openlayer.json](https://docs.openlayer.com/development/openlayer-json.md)
* [Instrumenting your app for monitoring](https://docs.openlayer.com/monitoring/instrument.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.