> ## 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.

# Get Results

> Retrieve scan results and check scan status

## GET /api/static/scan

Check the status of a scan and retrieve results once completed.

### Request

**Headers:**

* `x-api-key` (required): Your Rafter API key

**Query Parameters:**

* `scan_id` (required): The scan request ID to check
* `format` (optional): Output format - `json` (default) or `md`

### Example Requests

**Check status (JSON format):**

```bash theme={null}
curl -H "x-api-key: RFabc-your-api-key-here" \
  "https://rafter.so/api/static/scan?scan_id=b1b2c3d4-e5f6-7890-abcd-ef1234567890"
```

**Get results in Markdown format (format=md):**

```bash theme={null}
curl -H "x-api-key: RFabc-your-api-key-here" \
  "https://rafter.so/api/static/scan?scan_id=b1b2c3d4-e5f6-7890-abcd-ef1234567890&format=md"
```

### Response

#### Scan Pending/Processing

**Status: pending, queued, or processing**

```json theme={null}
{
  "status": "pending"
}
```

#### Scan Completed (JSON Format)

**Status: completed**

```json theme={null}
{
  "status": "completed",
  "repository_name": "myorg/myrepo",
  "branch_name": "prod",
  "scan_date": "2025-07-24T00:00:00.000+00:00",
  "scan_id": "abcdabcd-abcd-abcd-abcd-abcdabcd",
  "scan_mode": "fast",
  "vulnerabilities": [
    {
      "rule_id": "SEC001",
      "level": "error",
      "file": "src/auth.js",
      "line": 42,
      "column": 15,
      "message": "Hardcoded API key detected",
      "description": "API keys should be stored in environment variables",
      "suggestion": "Move the API key to an environment variable"
    },
    {
      "rule_id": "SEC002",
      "level": "warning",
      "file": "src/database.js",
      "line": 78,
      "column": 8,
      "message": "SQL injection vulnerability",
      "description": "User input is directly concatenated into SQL query",
      "suggestion": "Use parameterized queries or prepared statements"
    }
  ]
}
```

#### Scan Completed (Markdown Format - format=md)

**Status: completed with format=md**

When `format=md` is specified, the response includes a `markdown` field containing a structured security report designed for LLM-assisted remediation. The report uses role-priming, step-by-step instructions, and per-issue detail to produce high-quality analysis.

```json theme={null}
{
  "status": "completed",
  "repository_name": "myorg/myrepo",
  "branch_name": "prod",
  "scan_date": "2025-07-24T00:00:00.000+00:00",
  "scan_id": "abcdabcd-abcd-abcd-abcd-abcdabcd",
  "scan_mode": "fast",
  "markdown": "You are a senior application-security, web-application, and cloud-reliability engineer. Implement production-grade solutions that scale. Never mock data, suppress linter security rules, or shortcut the fix. Think step-by-step.\n\n# Security Issues and Vulnerabilities\n\n**Total Issues:** 2\n\nThis report contains 2 security issues found in the repository. Each issue requires attention and remediation. Proceed one-by-one, thinking step-by-step to understand and remediate each.\n\n## Issues Summary\n\n### Issue 1\n**Rule ID:** a1b2c3d4\n**File:** src/auth.js\n**Line:** 42\n**Description:** Hardcoded API key detected\n\n### Issue 2\n**Rule ID:** e5f6a7b8\n**File:** src/database.js\n**Line:** 78\n**Description:** User input is directly concatenated into SQL query\n\nPlease analyze these 2 security vulnerabilities and provide:\n1. A comprehensive analysis of the security risks\n2. Prioritized remediation steps\n3. Code examples for fixes\n4. Prevention strategies for future development"
}
```

<Note>
  Rule IDs in the markdown report are hashed for consistency. The report format is optimized for feeding into LLMs—it includes a security-engineer role prompt, structured issue metadata, and a trailing analysis request.
</Note>

#### Scan Failed

**Status: failed**

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

#### No Vulnerabilities Found

**Status: completed with no issues**

```json theme={null}
{
  "status": "completed",
  "repository_name": "myorg/myrepo",
  "branch_name": "prod",
  "scan_date": "2025-07-24T00:00:00.000+00:00",
  "scan_id": "abcdabcd-abcd-abcd-abcd-abcdabcd",
  "scan_mode": "fast",
  "vulnerabilities": []
}
```

### Error Responses

**Error (400 Bad Request):**

```json theme={null}
{
  "error": "Missing required parameter: scan_id"
}
```

**Error (401 Unauthorized):**

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

**Error (404 Not Found):**

```json theme={null}
{
  "error": "Scan not found."
}
```

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

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

### Response Fields

#### Common Fields

| Field    | Type   | Description                                                           |
| -------- | ------ | --------------------------------------------------------------------- |
| `status` | string | Scan status: `pending`, `queued`, `processing`, `completed`, `failed` |

#### Completed Scan Fields (JSON)

| Field             | Type   | Description                              |
| ----------------- | ------ | ---------------------------------------- |
| `repository_name` | string | Repository name in format "org/repo"     |
| `branch_name`     | string | Branch name that was scanned             |
| `scan_date`       | string | ISO 8601 timestamp when scan was created |
| `scan_mode`       | string | Scan mode used: `"fast"` or `"plus"`     |
| `vulnerabilities` | array  | Array of vulnerability objects           |

#### Vulnerability Object Fields

| Field         | Type    | Description                                |
| ------------- | ------- | ------------------------------------------ |
| `rule_id`     | string  | Unique identifier for the security rule    |
| `level`       | string  | Severity level: `error`, `warning`, `note` |
| `file`        | string  | File path where vulnerability was found    |
| `line`        | integer | Line number in the file                    |
| `column`      | integer | Column number in the line                  |
| `message`     | string  | Short description of the issue             |
| `description` | string  | Detailed explanation of the vulnerability  |
| `suggestion`  | string  | Recommended fix or mitigation              |

## 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}
async function getScanResults(scanId, format = 'json') {
  const response = await fetch(
    `https://rafter.so/api/static/scan?scan_id=${scanId}&format=${format}`,
    {
      headers: {
        'x-api-key': 'RFabc-your-api-key-here'
      }
    }
  );

  const data = await response.json();
  
  if (data.status === 'completed') {
    if (format === 'json') {
      console.log(`Found ${data.vulnerabilities.length} vulnerabilities`);
    } else {
      console.log('Markdown report generated');
    }
  } else {
    console.log(`Scan status: ${data.status}`);
  }
  
  return data;
}
```

#### Python

```python theme={null}
import requests
import time

def wait_for_scan_completion(scan_id, api_key, max_wait=300):
    start_time = time.time()
    
    while time.time() - start_time < max_wait:
        response = requests.get(
            f'https://rafter.so/api/static/scan?scan_id={scan_id}',
            headers={'x-api-key': api_key}
        )
        
        data = response.json()
        
        if data['status'] == 'completed':
            return data
        elif data['status'] == 'failed':
            raise Exception(f"Scan failed: {data.get('error', 'Unknown error')}")
        
        print(f"Scan status: {data['status']}")
        time.sleep(10)
    
    raise Exception("Scan timed out")


# Enhanced polling strategy with failure handling in Bash
#!/bin/bash

SCAN_ID="b1b2c3d4-e5f6-7890-abcd-ef1234567890"
API_KEY="RFabc-your-api-key-here"
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 
```
