> ## 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](/workspace-and-projects/creating-and-loading-projects), 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`](/api-reference/cli/commands/install) → `init` →
[`push`](/api-reference/cli/commands/push). You do not need a separate
[`openlayer login`](/api-reference/cli/commands/login) or
[`openlayer link`](/api-reference/cli/commands/link) step.

<Info>
  `openlayer init` requires Openlayer CLI **v1.13.0** or later. Check your
  version with `openlayer --version` and upgrade with [`openlayer
      update`](/api-reference/cli/commands/update).
</Info>

## 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:

<Steps>
  <Step title="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.
  </Step>

  <Step title="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.
  </Step>

  <Step title="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`.
  </Step>

  <Step title="Choose what to set up">
    Finally, `init` asks which track to run — see
    [Choosing what to set up](#choosing-what-to-set-up).
  </Step>
</Steps>

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

<Steps>
  <Step title="Set up evaluations">
    Choose how your `openlayer.json` gets written: with a coding agent that `init` detects on
    your machine (Claude Code or Codex), 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](/development/openlayer-json).

    Skipped when an `openlayer.json` already exists.
  </Step>

  <Step title="Push first commit">
    Asks before running [`openlayer push`](/api-reference/cli/commands/push) with the commit
    message `Initial commit from openlayer init`. Skipped when there is no `openlayer.json`
    to push.
  </Step>

  <Step title="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](/guides/gh-actions). Skipped when
    that workflow file already exists.
  </Step>
</Steps>

### Monitoring mode track

<Steps>
  <Step title="Create monitoring pipeline">
    Pick an existing inference pipeline to receive your traces, or create a new
    one (named `production` by default).
  </Step>

  <Step title="Write local credentials">
    Writes `.env.openlayer` with your API key and inference pipeline id, and
    adds it to your `.gitignore`.
  </Step>

  <Step title="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](/monitoring/instrument).
  </Step>

  <Step title="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.
  </Step>
</Steps>

<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.
</Warning>

## 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`:

<CodeGroup>
  ```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
    }
  }
  ```
</CodeGroup>

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](/development/openlayer-json) and
  [Configuring output generation](/development/configuring-output-generation).
</Note>

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`](/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](/workspace-and-projects/find-your-api-key). 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` or `codex`.                    |
| `--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.
</Warning>

[Global options](/api-reference/cli/global-options) 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.
</Warning>

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.
</Note>

### 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`](/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](/guides/gh-actions) for the standard CI setup.
</Tip>

## 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`](/api-reference/cli/commands/link)                                 |
| CI/CD against a project that already exists                          | Set `OPENLAYER_PROJECT_ID` — see [global options](/api-reference/cli/global-options) |

## Related guides

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