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

# CI/CD

> Automatically run your Spur test plans on every pull request and block deployments when tests fail.

## Overview

Connecting Spur to your CI/CD pipeline adds an automated quality gate right before deployment. When a pull request is opened or code is pushed, Spur triggers your test plans and reports results directly in your repository. Failing tests block a merge before anything reaches production.

<Columns cols={3}>
  <Card title="GitHub" icon="github" href="/running-tests/cicd/github">
    Set up GitHub Actions to run test plans on every pull request.
  </Card>

  <Card title="GitLab" icon="gitlab" href="/running-tests/cicd/gitlab">
    Set up GitLab CI/CD to run test plans on every merge request.
  </Card>

  <Card title="Override URLs" icon="arrow-right-arrow-left" href="/running-tests/cicd/override-urls">
    Redirect tests to deploy previews or feature branch URLs at runtime.
  </Card>
</Columns>

## Triggering via webhook

As an alternative to the GitHub Actions or GitLab pipeline files, you can trigger Spur test plans directly using a curl request to the Spur webhook. This is useful if you use a CI/CD provider other than GitHub or GitLab, or if you want more control over when tests are triggered.

Send a POST request to the Spur webhook endpoint with your API key (found on the GitHub Integration Settings page in Spur):

```bash theme={null}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "SPUR_GITHUB_KEY: <YOUR_API_KEY>" \
  -d '{
    "override_urls": {
      "default": "https://my-app-pr-42.vercel.app"
    }
  }' \
  "https://app.spurtest.com/api/webhook"
```

The `override_urls` body is optional — include it to redirect tests to a different URL (such as a deploy preview) without changing your environment settings. See [Override URLs](/running-tests/cicd/override-urls) for the full configuration options.

<Tip>
  You can use this webhook in any CI/CD system, including Jenkins, CircleCI, Bitbucket Pipelines, or custom deployment scripts.
</Tip>

## Launching a specific test plan

If you need to trigger a single test plan by ID — for example, to run a specific regression suite as part of a deployment pipeline — use the `run_test_plan` endpoint instead of the general webhook.

Send a POST request to `https://app.spurtest.com/api/run_test_plan` with your authorization token and a JSON body specifying which test plan to run.

### Request fields

| Field           | Type    | Required | Notes                                                                                                                                                                        |
| --------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `test_plan_id`  | integer | Yes      | Must be a JSON number, not a string.                                                                                                                                         |
| `request_id`    | string  | Yes      | Non-empty string used as the workflow or run request ID.                                                                                                                     |
| `override_urls` | object  | No       | If present, must be a JSON object. Any other type (such as a string or array) is rejected. See [Override URLs](/running-tests/cicd/override-urls) for configuration details. |

### Example request

```bash theme={null}
curl -X POST https://app.spurtest.com/api/run_test_plan \
  -H "Authorization: <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "test_plan_id": 789,
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "override_urls": {
      "domains": {
        "staging.example.com": "https://preview-abc.example.com"
      },
      "default": "https://staging.example.com"
    }
  }'
```

<Note>
  The `test_plan_id` must be a number in the JSON body. Passing it as a string (e.g. `"789"`) will fail validation.
</Note>
