# Tool run endpoints > List your organisation's security tool runs, read one run's full result, and run a scan through Vigilbase One, over the One API. Source: https://docs.vigilbase.com/one/api/tool-runs A tool run is one scan by a Vigilbase security tool, such as Website Security or Security headers. These endpoints list your organisation's runs and start new ones. Sign-in, permissions, rate limits and error shapes are on [Vigilbase One API](https://docs.vigilbase.com/one/api). These are v1 operations, on `https://api.vigilbase.com/one/v1`: | Method and path | Permission | CLI command | | --- | --- | --- | | `GET /tool-runs` | `read:services` | `vigilbase runs list` | | `GET /tool-runs/{runId}` | `read:services` | `vigilbase runs get ` | This one has no v1 operation yet, and is on `https://one.vigilbase.com`: | Method and path | Permission | CLI command | | --- | --- | --- | | `POST /api/tools/{tool}/execute` | `read:services` | `vigilbase run ` for the tools that need a sign-in, or `--via one` | Errors from `POST /api/tools/{tool}/execute` are `{ "success": false, "error": "…" }`, or the shared permission refusal; the v1 operations answer [problem details](https://docs.vigilbase.com/one/api#errors). ## Which runs you see You see your organisation's runs, whoever in the organisation started them. That includes runs started in One, through the CLI, and scans on vigilbase.com that One has linked to your organisation. When you list runs, One first links public scans from vigilbase.com in the last 365 days that used the email address of a verified member of your organisation, if no other organisation has them. Reading a single run tries the same for that run. You can pass `customerId`, but only your own customer's ID: any other gives `403`. Partners can't list their customers' runs here. ## List runs `GET /tool-runs` lists runs newest first, as a [cursor page](https://docs.vigilbase.com/one/api#pagination). | Parameter | Description | | --- | --- | | `toolName` | Only this tool, for example `website-security` | | `accountId` | Only runs for this Cloudflare account ID or target | | `limit` | 1 to 100; default 50 | | `cursor` | The previous page's `nextCursor` | ```json { "items": [ { "id": "8d0f…", "toolName": "security-headers", "target": "https://example.com", "targetType": "url", "status": "completed", "grade": "B", "gradeScore": 72, "sourceApp": "one", "email": "you@example.com", "createdAt": "2026-10-30T09:12:44.000Z", "startedAt": "2026-10-30T09:12:44.000Z", "completedAt": "2026-10-30T09:12:51.000Z" } ], "nextCursor": "…" } ``` `sourceApp` says where the run started: `one` or `com` (vigilbase.com). `email` is who ran it. A cursor from another set of filters answers `400`. ## Get a run `GET /tool-runs/{runId}` returns one run: the list fields plus `customerId`, `unlocked`, `errorMessage` and `results` (the tool's stored result). A run that doesn't exist or isn't your organisation's answers `404`. ## Run a scan `POST /api/tools/{tool}/execute` runs a scan as you, in your organisation, and saves it as a run. These tools can run this way: | `{tool}` | Target | | --- | --- | | `security-headers` | A public HTTPS URL or hostname on port 443 | | `email-security` | A public domain | | `website-security` | A public URL; no IP addresses or internal hosts | | `react2shell` | A public URL of a React Server Components app; no IP addresses or internal hosts | | `fortibleed-check` | A domain | Send the target as JSON: ```json { "target": "https://example.com" } ``` The request stays open until the scan finishes, then returns the result: ```json { "success": true, "data": { "toolRunId": "8d0f…", "status": "completed", "grade": "B", "gradeScore": 72, "result": { } } } ``` Scans through One don't spend the free daily scans on vigilbase.com or the [Agent API](https://docs.vigilbase.com/tools/developers/agent-api) scan quota. One's own [rate limits](https://docs.vigilbase.com/one/api#rate-limits) apply. A scan that runs but fails still creates a run, marked `failed`, and answers `422`: - **The scanner couldn't assess the target**, for example because the site answered with a bot challenge: `"code": "scan_unassessed"`, the scanner's explanation in `error`, and its result in `data.result`. - **Anything else**, including a target the scanner refuses: `"error": "Tool scan failed"`, with no `code`. ```json { "success": false, "error": "…", "code": "scan_unassessed", "data": { "toolRunId": "8d0f…", "status": "failed", "result": { "status": "error", "message": "…" } } } ``` | Status | When | | --- | --- | | `400` | The body isn't JSON or has no `target`, or the tool can't be started in One. Start Cloudflare Checkups with [their own endpoint](https://docs.vigilbase.com/one/api/cloudflare#start-a-checkup) | | `404` | Unknown tool | | `409` | Your customer record is changing; retry later | | `422` | The scan ran and failed, as above | | `503` | Scanning from One isn't available right now | Website Security refuses to scan vigilbase.com itself; that answers `422` with `scan_unassessed`. ## Older paths Each v1 operation here also answers at an older path on `https://one.vigilbase.com/api`: `GET /api/tool-runs` and `GET /api/tool-runs/{id}`. The older paths are deprecated aliases and will be retired with `410 Gone`. Each operation's page in the [API reference](https://docs.vigilbase.com/one/api/reference) names its older path. See [hosts](https://docs.vigilbase.com/one/api#hosts).