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

# Quickstart: your first run from the command line

> Run a complete OCPI conformance run against the deployed service from the command line with curl, jq and an evrt_ API key.

This walks one complete loop against the deployed service: authenticate, pick a target,
run the compliance suite, read the verdict. It uses the built-in **sandbox** target, a
working OCPI peer that every account can run against, so you do not need a partner
endpoint yet.

## Prerequisites

* An API key in `EVRT_KEY`. See [Create an API key](/docs/guide/create-an-api-key).
* `curl` and `jq`.

## One complete run

```bash theme={null}
#!/usr/bin/env bash
set -euo pipefail

BASE="https://evsim.synergyboat.com"
AUTH="Authorization: Bearer $EVRT_KEY"

# 1. Pick the built-in sandbox connection. One is available per OCPI version,
#    already registered; this filter takes the 2.2.1 one.
CONNECTION_ID=$(curl -fsS "$BASE/api/v1/connections" -H "$AUTH" \
  | jq -r '[.data[] | select(.kind == "sandbox" and .ocpiVersion == "2.2.1")][0]._id')

# 2. Start the full compliance suite and wait up to 60 seconds for the report.
RESPONSE=$(curl -fsS -w '\n%{http_code}' -X POST "$BASE/api/v1/testing/runs?wait=60" \
  -H "$AUTH" -H "Content-Type: application/json" \
  -d "{\"connectionId\": \"$CONNECTION_ID\"}")

STATUS=$(printf '%s' "$RESPONSE" | tail -n1)
BODY=$(printf '%s' "$RESPONSE" | sed '$d')

# 3. A 202 means the run is still going: your wait expired, not the run.
#    Poll the report by id until it reaches a terminal state.
if [ "$STATUS" = "202" ]; then
  REPORT_ID=$(printf '%s' "$BODY" | jq -r '.data.reportId')
  BODY=$(curl -fsS "$BASE/api/v1/testing/runs/$REPORT_ID?wait=120" -H "$AUTH")
fi

# 4. Read the verdict.
printf '%s' "$BODY" | jq '.data.summary'
```

The output is the run summary: how many checks passed, failed and warned. The full
per-check report, including the recorded request and response behind every check, is at
`GET /api/v1/testing/runs/:id`.

<Note>
  A `202` is active work, not an outcome. The run did not fail and did not pass; it simply
  outlived your wait. Treat it as "poll again", never as a red build. The only failure
  signal for a conformance run is `failed` checks in the summary of a finished run.
</Note>

## What just happened

The sandbox is a real OCPI peer, not a recording. The run discovered its versions,
completed the credentials handshake, and made real HTTP calls to real module endpoints.
Every check in the report carries the exchange that produced it. A run against your
partner works exactly the same way; the only difference is the connection you pass.

## Next

<CardGroup cols={2}>
  <Card title="Connect a partner" icon="plug" href="/docs/guide/connect-a-partner">
    Point the tester at a real endpoint.
  </Card>

  <Card title="Run a suite in CI" icon="gears" href="/docs/guide/run-a-suite">
    Gate a build on the result, correctly.
  </Card>
</CardGroup>
