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

# Run a simulation

> Zero to a scored simulation with config as code: define an agent and a plan, apply, run it, read the result, and gate CI on it

The end-to-end path, on one page: define a simulation in your repo, apply it, run it, and read the pass/fail. Config as code defines the resources; running is a separate, deliberate step (so applying never places a surprise call).

> [!NOTE]
>
> You need the [CLI](https://docs.roark.ai/documentation/sdks/cli.md) (`npm install -g @roarkanalytics/cli`) and a Roark API key with **`config:apply`** and permission to **start simulations and read results**. Set it once: `export ROARK_API_BEARER_TOKEN="<key>"`.

## 1. Define an agent and a plan

The minimum to run something: an **agent** to call and a **simulation plan** that says which flows to run against it and which metrics grade the result. This plan runs a built-in (`system`) flow, so there's no persona or flow to author first.

```typescript roark.config.ts theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
import { defineAgent, defineSimulationPlan, defineConfig } from '@roarkanalytics/sdk/lib/config';

const frontdesk = defineAgent({
  name: 'frontdesk',
  endpoints: [{ value: '+15551234567', direction: 'OUTGOING' }],
});

const nightly = defineSimulationPlan({
  name: 'nightly-screener-suite',
  direction: 'OUTBOUND',
  agentEndpoints: [{ agent: 'frontdesk', value: '+15551234567' }],
  metrics: ['call_screening_encountered', 'call_screening_handling_score'],
  flows: [{ system: 'sf-screener-apple' }],
  maxDurationSeconds: 300,
});

export default defineConfig({ resources: [frontdesk, nightly] });
```

```yaml roark/simulation-plans/nightly.yaml theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
# yaml-language-server: $schema=https://roark.ai/roark-config.schema.json
# (plus roark/agents/frontdesk.yaml defining the agent)
kind: simulationPlan
name: nightly-screener-suite
direction: OUTBOUND
agentEndpoints:
  - agent: frontdesk
    value: '+15551234567'
metrics:
  - call_screening_encountered
  - call_screening_handling_score
flows:
  - system: sf-screener-apple
maxDurationSeconds: 300
```

Swap the `system` flow for your own [customer flows](https://docs.roark.ai/documentation/config-as-code/flows.md) and [personas](https://docs.roark.ai/documentation/config-as-code/personas.md) once you want to test your own scenarios. `roark simulation template list` prints every built-in flow slug.

## 2. Apply it

Create the resources (preview first, then apply):

```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
roark config diff roark.config.ts    # or ./roark for a YAML directory
roark config apply roark.config.ts
```

This creates the agent and the plan. It does **not** run anything yet.

## 3. Run it

Running is a separate command. It takes the plan's **id**, not its config name, so look the id up once (or copy it from the plan's page in the dashboard):

```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
# find the plan's id by its name
roark simulation plan list | jq -r '.data[] | select(.name=="nightly-screener-suite") | .id'

# start a run
roark simulation run --data '{"planId":"<plan-id>"}'
```

`roark simulation run` returns a **job id** (the run). It places the calls, grades each against the plan's metrics, and the result settles when every call has been scored.

> [!TIP]
>
> Prefer not to leave your pipeline? The [GitHub Action](#5-gate-ci-on-it) starts the run and waits for it in one step, and the [Node SDK](https://docs.roark.ai/documentation/sdks/node-sdk.md) exposes the same via `client.simulation.run({ planId })`.

## 4. Read the result

```bash theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
roark simulation plan job result <job-id>
```

You get the per-check pass/fail against the plan's [success criteria](https://docs.roark.ai/documentation/simulation-testing/run-plans.md#success-criteria), plus a link to the full report in the dashboard. Roark decides pass vs. fail, so the CLI, the dashboard, and your CI pipeline never disagree.

## 5. Gate CI on it

For a pipeline, skip the manual run and let the [GitHub Action](https://github.com/roarkhq/simulation-action) start the run, wait, and fail the build when a check falls short:

```yaml .github/workflows/agent-regression.yml theme={"theme":{"light":"everforest-light","dark":"everforest-dark"}}
name: Agent regression
on:
  push:
    branches: [main]
jobs:
  simulate:
    runs-on: ubuntu-latest
    steps:
      # Optional: keep the plan itself in the repo and apply it first.
      - uses: actions/checkout@v4
      - run: npx -y @roarkanalytics/cli config apply roark.config.ts --yes
        env:
          ROARK_API_BEARER_TOKEN: ${{ secrets.ROARK_API_KEY }}
      # Start the run, wait for it, and gate the build on the result.
      - uses: roarkhq/simulation-action@v1
        with:
          api-token: ${{ secrets.ROARK_API_KEY }}
          plan-id: <your-plan-id>
```

See [CI/CD](https://docs.roark.ai/documentation/simulation-testing/ci-cd.md) for the full action reference.

## Or: run it on a schedule

To run without a trigger at all, add a [`schedule`](https://docs.roark.ai/documentation/config-as-code/simulation-plans#running-on-a-schedule) to the plan and apply, the plan runs itself on the cadence you set.

> **[Simulation plans reference](https://docs.roark.ai/documentation/config-as-code/simulation-plans.md)**
>
> Every field a plan takes: agents, flows, metrics, direction, scheduling, and knowledge checks.


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