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

# Trigger Scan

> Start a new security scan for your repository

## POST /api/static/scan

Trigger a new security scan for a specific repository and branch.

### Request

**Headers:**

* `x-api-key` (required): Your Rafter security API key
* `Content-Type: application/json`

**Body:**

```json theme={null}
{
  "repository_name": "myorg/myrepo",
  "branch_name": "main",
  "scan_mode": "fast",
  "github_token": "github_pat_..."
}
```

<Note>The `github_token` field is optional. When omitted, the scan uses the OAuth credentials linked to your Rafter account. Use this field for scanning private repositories without OAuth — the token only needs `Contents:Read` permission.</Note>

**Fields:**

| Field             | Type   | Required | Description                                                                                                                                                                                                                                                            |
| ----------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `repository_name` | string | Yes      | Repository name in format `org/repo`                                                                                                                                                                                                                                   |
| `branch_name`     | string | Yes      | Branch name to scan                                                                                                                                                                                                                                                    |
| `scan_mode`       | string | No       | Scan mode: `"fast"` (default) or `"plus"`. Fast uses industry-standard tooling and Rafter's proprietary analysis for SAST, secret detection, and dependency checks. Plus runs the full fast pipeline plus additional agent-driven analysis passes for deeper coverage. |
| `github_token`    | string | No       | Fine-grained GitHub PAT for scanning private repositories. Only needs `Contents:Read` permission. Can also be set via `RAFTER_GITHUB_TOKEN` environment variable when using the CLI.                                                                                   |

### Example Request

```bash theme={null}
curl -X POST \
  -H "Content-Type: application/json" \
  -H "x-api-key: RFabc-your-api-key-here" \
  -d '{
    "repository_name": "myorg/myrepo",
    "branch_name": "main",
    "scan_mode": "fast"
  }' \
  https://rafter.so/api/static/scan
```

### Response

**Success (200 OK):**

```json theme={null}
{
  "success": true,
  "scan_id": "b1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
```

**Error (400 Bad Request):**

```json theme={null}
{
  "error": "Missing required field: repository_name"
}
```

**Error (401 Unauthorized):**

```json theme={null}
{
  "error": "Invalid or inactive API key."
}
```

**Error (403 Forbidden — scan limit reached):**

```json theme={null}
{
  "error": "You have reached your Plus scan limit for this billing period.",
  "scan_mode": "plus",
  "used": 1,
  "limit": 1
}
```

**Error (403 Forbidden — insufficient scope):**

```json theme={null}
{
  "error": "API key does not have scan scope."
}
```

**Error (429 Too Many Requests):**

```json theme={null}
{
  "error": "Rate limit exceeded. Please try again later."
}
```

The CLI maps this to exit code 3 (quota exhausted).

**Error (404 Not Found):**

```json theme={null}
{
  "error": "Repository not found or access denied."
}
```

**Error (500 Internal Server Error):**

```json theme={null}
{
  "error": "An unexpected error occurred."
}
```

### Response Fields

| Field     | Type    | Description                                 |
| --------- | ------- | ------------------------------------------- |
| `success` | boolean | Whether the scan was successfully triggered |
| `scan_id` | string  | Unique identifier for the scan request      |

## Rate Limiting

The API implements rate limiting to ensure fair usage:

* **Rate Limit**: 100 requests per minute per IP address
* **Quota**: Based on your subscription plan

### Examples

#### JavaScript

```javascript theme={null}
const response = await fetch('https://rafter.so/api/static/scan', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': 'RFabc-your-api-key-here'
  },
  body: JSON.stringify({
    repository_name: 'myorg/myrepo',
    branch_name: 'main',
    scan_mode: 'fast'
  })
});

const data = await response.json();
console.log(`Scan ID: ${data.scan_id}`);
```

#### Python

```python theme={null}
import requests

response = requests.post(
    'https://rafter.so/api/static/scan',
    headers={
        'Content-Type': 'application/json',
        'x-api-key': 'RFabc-your-api-key-here'
    },
    json={
        'repository_name': 'myorg/myrepo',
        'branch_name': 'main',
        'scan_mode': 'fast'
    }
)

data = response.json()
print(f"Scan ID: {data['scan_id']}")
```

### Next Steps

After triggering a scan, you can:

1. **Check scan status** using the `scan_id` with the [Get Results endpoint](/api-reference/endpoint/static/get)
2. **Wait for completion** by polling the status endpoint
3. **Retrieve results** once the scan is complete

### Workflow Example

```bash theme={null}
# 1. Trigger scan
SCAN_ID=$(curl -X POST \
  -H "Content-Type: application/json" \
  -H "x-api-key: RFabc-your-api-key-here" \
  -d '{"repository_name": "myorg/myrepo", "branch_name": "main", "scan_mode": "fast"}' \
  https://rafter.so/api/static/scan | jq -r '.scan_id')

# 2. Wait for completion (polling)
MAX_ATTEMPTS=15

for i in $(seq 1 $MAX_ATTEMPTS); do
    RESPONSE=$(curl -fsS -H "x-api-key: $API_KEY" \
      "https://rafter.so/api/static/scan?scan_id=$SCAN_ID")
    
    STATUS=$(echo $RESPONSE | jq -r '.status')
    
    if [ "$STATUS" = "completed" ]; then
        echo "Scan completed!"
        echo $RESPONSE | jq '.vulnerabilities | length' | xargs echo "Found vulnerabilities:"
        break
    elif [ "$STATUS" = "failed" ]; then
        echo "Scan failed!"
        echo $RESPONSE | jq -r '.error'
        exit 1
    else
        echo "Attempt $i/$MAX_ATTEMPTS: Status is $STATUS"
        sleep 10
    fi
done

# 3. Get results
curl -H "x-api-key: RFabc-your-api-key-here" \
  "https://rafter.so/api/static/scan?scan_id=$SCAN_ID"
```
