Docs · v1.4

Build with Scovant.

Run scans, simulations, and showcase from the dashboard — or drive it all from your pipeline: the REST API, CI/CD trigger, webhooks, and the MCP interface are live today. Entries marked “Soon” are on the roadmap.

CI/CD · 1 of 1

GitHub Actions.

Wire Scovant into your deploy pipeline: trigger a scan after each deploy, poll for the result, gate the build on regressions, and attach a remediation plan as a build artifact. Everything below uses one scvt_ API token and plain curl — no CLI or marketplace action required.

1. Create an API token

Create the token in Settings → API tokens (workspace owner only). Tokens use the format scvt_ followed by 43 URL-safe characters and are shown once on creation — store the value immediately. Each workspace holds one active token at a time: creating a second returns 409 {"error": "token_already_exists"}; revoke the current token first.

Add the token as a GitHub repository secret (e.g. SCOVANT_API_TOKEN) and your site's UUID as a repository variable (e.g. SCOVANT_SITE_ID). Don't have the UUID handy? Call the MCP list_sites tool with the token (same curl shape as step 3; API-token callers can omit workspace_id — it defaults to the token's workspace) instead of copying it from the dashboard.

2. Trigger after deploy

POST /api/ci/trigger accepts the token as a bearer header. Full request body:

json
{
  "site_id": "<uuid>",
  "environment": "production",
  "branch": "main",
  "commit_sha": "<sha>",
  "release_tag": "v1.2.3",
  "run_scan": true,
  "run_simulation": false
}

Only site_id is required; run_scan defaults to true, run_simulation to false. Example workflow step:

yaml
- name: Trigger Scovant scan
  run: |
    curl -sf -X POST https://scovant.com/api/ci/trigger \
      -H "Authorization: Bearer ${{ secrets.SCOVANT_API_TOKEN }}" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: ${{ github.run_id }}-${{ github.run_attempt }}" \
      -d '{"site_id": "${{ vars.SCOVANT_SITE_ID }}", "environment": "production", "branch": "${{ github.ref_name }}", "commit_sha": "${{ github.sha }}"}'

The CI trigger requires a Monitor or Enterprise workspace — otherwise 403 {"error": "feature_not_available", "feature": "ci_webhooks", "required_plan": "monitor"}. Credits: 1 for the scan, plus 1 per agent in the site's ci_agents list when run_simulation is true. With an insufficient balance the endpoint returns 402 {"error": "insufficient_credits", "balance": ..., "required": ..., "packages": [...]} and nothing runs.

Success is 202:

json
{
  "scan_run_id": "<uuid>",
  "simulation_run_id": "<uuid or null>",
  "simulation_run_ids": ["<uuid>", "..."],
  "run_group_id": "<uuid or null>",
  "status": "triggered"
}

simulation_run_ids lists every agent run created (one per CI agent); simulation_run_id is the first of them, kept for back-compat.

Safe retries — send an Idempotency-Key header (any client-chosen string, as in the example). Retrying with the same key within 24 hours replays the original 202 body — marked with an Idempotency-Replayed: true response header — instead of creating and debiting new runs. A concurrent duplicate returns 409 {"error": "request_in_flight"}.

No token on your deploy host? Create an incoming webhook in Settings (Monitor or Enterprise) and call POST /api/ci/webhook/{webhook_id} with the webhook's secret in an X-Scovant-Secret header — same request body, same 202 response. See Webhook events.

3. Poll for the result

Reads for CI use the same scvt_ token over Scovant's MCP interface — a single stateless POST per call, no handshake, no SSE:

bash
curl -s -X POST https://scovant.com/mcp/ \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer scvt_YOUR_API_TOKEN' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_scan","arguments":{"scan_id":"SCAN_UUID"}}}'

The tool payload arrives as a JSON string in result.content[0].text — extract it with jq -r '.result.content[0].text' | jq .. Poll get_scan until status is completed, partial, or failed.

4. The pass/fail verdict

Regression comparison runs only when a prior completed run exists — when environment is set, the baseline is the latest completed run for that same environment, so the first run for an environment establishes its baseline and reports nothing. Once the scan completes, call list_regressions with your site_id (same curl shape, different tool name): an empty data array means no regressions were detected — that is your green build. For agent-run detail, call get_simulation with a simulation_run_id from the trigger response.

Prefer push? An outgoing webhook delivers two events: ci.completed fires on every CI run completion once a baseline exists — regressions_count: 0 is your green build, so silence no longer needs interpreting — and regressions.detected fires only when regressions were found. Subscribe to ci.completed for the definitive per-run verdict, or poll list_regressions as above; only the environment's first (baseline-establishing) run emits neither event.

5. Attach a Fix Plan (optional)

Call generate_fix_plan with the site_id (costs 1 credit; needs a completed scan), poll get_fix_plan until status is completed, then download the Markdown from the returned public_url — an unauthenticated GET /api/public/fix-plan/{token}.md you can fetch in a workflow step and upload as a build artifact.

Configuration

Which agents run when run_simulation is true is a per-site setting: PATCH /api/sites/{site_id} with {"ci_agents": ["claude"]} (default ["claude"]).