> For the complete documentation index, see [llms.txt](https://docs.akto.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.akto.io/api-reference/dast.md).

# DAST

<table data-full-width="true"><thead><tr><th width="430">API</th><th>Description</th></tr></thead><tbody><tr><td><strong>POST /api/fetchAllDastScans</strong></td><td>Retrieve all DAST scan/crawl runs in active or completed states (RUNNING, COMPLETED, STOP_REQUESTED, STOPPED).</td></tr><tr><td><strong>POST /api/fetchDastScan</strong></td><td>Retrieve all URLs discovered by the crawler for a specific DAST crawl run.</td></tr><tr><td><strong>POST /api/fetchAvailableDastModules</strong></td><td>Retrieve available external DAST modules that have sent a heartbeat within the last 5 minutes.</td></tr><tr><td><strong>POST /api/initiateCrawler</strong></td><td>Start a DAST crawler targeting the specified host with configured authentication, URL patterns, and crawl options.</td></tr><tr><td><strong>POST /api/uploadCrawlerData</strong></td><td>Push raw crawler traffic data for a collection to the ingestion pipeline (Kafka) for async processing.</td></tr><tr><td><strong>POST /api/updateCrawlerStatus</strong></td><td>Update the status of an existing crawl run (RUNNING, COMPLETED, FAILED, or STOPPED).</td></tr><tr><td><strong>POST /api/stopCrawler</strong></td><td>Send a stop request to the internal DAST crawler service and mark the crawl run as STOP_REQUESTED.</td></tr><tr><td><strong>POST /api/saveCrawlerUrl</strong></td><td>Record a URL discovered during a crawl, along with provenance information and whether it was within scope.</td></tr></tbody></table>

## List all DAST scan runs

> Returns all \`CrawlerRun\` documents that are in \`RUNNING\`, \`COMPLETED\`, \`STOP\_REQUESTED\`, or \`STOPPED\` state, plus legacy records that have no \`status\` field. \`PENDING\` and \`FAILED\` runs are excluded.\
> \
> Source: \`DastAction.fetchAllDastScans()\`

```json
{"openapi":"3.0.1","info":{"title":"AktoSwagger","version":"1.0.0"},"paths":{"/api/fetchAllDastScans":{"post":{"summary":"List all DAST scan runs","description":"Returns all `CrawlerRun` documents that are in `RUNNING`, `COMPLETED`, `STOP_REQUESTED`, or `STOPPED` state, plus legacy records that have no `status` field. `PENDING` and `FAILED` runs are excluded.\n\nSource: `DastAction.fetchAllDastScans()`","operationId":"fetchAllDastScans","tags":["DAST Scans"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"List of crawler run documents.","content":{"application/json":{"schema":{"type":"object","properties":{"crawlerRuns":{"type":"array","description":"All matching `CrawlerRun` documents.","items":{"$ref":"#/components/schemas/CrawlerRun"}},"actionErrors":{"type":"array","items":{"type":"string"}}}}}}}}}}}}
```

## Fetch URLs discovered in a DAST scan

> Returns all \`CrawlerUrl\` documents recorded by the crawler for the specified \`crawlId\`, representing every URL that was discovered (both in-scope and out-of-scope).\
> \
> Source: \`DastAction.fetchDastScan()\`

```json
{"openapi":"3.0.1","info":{"title":"AktoSwagger","version":"1.0.0"},"paths":{"/api/fetchDastScan":{"post":{"summary":"Fetch URLs discovered in a DAST scan","description":"Returns all `CrawlerUrl` documents recorded by the crawler for the specified `crawlId`, representing every URL that was discovered (both in-scope and out-of-scope).\n\nSource: `DastAction.fetchDastScan()`","operationId":"fetchDastScan","tags":["DAST Scans"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["crawlId"],"properties":{"crawlId":{"type":"string","description":"UUID of the crawl run whose discovered URLs to retrieve."}}}}}},"responses":{"200":{"description":"List of discovered crawler URL documents.","content":{"application/json":{"schema":{"type":"object","properties":{"crawlerUrls":{"type":"array","description":"All `CrawlerUrl` documents for the given crawl.","items":{"$ref":"#/components/schemas/CrawlerUrl"}},"actionErrors":{"type":"array","items":{"type":"string"}}}}}}},"400":{"description":"`crawlId` is null or empty."}}}}}}
```

## List active DAST modules

> Returns all external DAST modules that have sent a heartbeat within the last 5 minutes. An empty \`availableModules\` list means only the built-in internal Akto DAST crawler is available and \`selectedModuleName\` should be left null when calling \`initiateCrawler\`.\
> \
> Source: \`AktoJaxAction.fetchAvailableDastModules()\`

```json
{"openapi":"3.0.1","info":{"title":"AktoSwagger","version":"1.0.0"},"paths":{"/api/fetchAvailableDastModules":{"post":{"summary":"List active DAST modules","description":"Returns all external DAST modules that have sent a heartbeat within the last 5 minutes. An empty `availableModules` list means only the built-in internal Akto DAST crawler is available and `selectedModuleName` should be left null when calling `initiateCrawler`.\n\nSource: `AktoJaxAction.fetchAvailableDastModules()`","operationId":"fetchAvailableDastModules","tags":["DAST Scans"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"Available DAST modules returned.","content":{"application/json":{"schema":{"type":"object","properties":{"availableModules":{"type":"array","description":"DAST modules that sent a heartbeat within the last 5 minutes. Empty if only the built-in service is available.","items":{"type":"object","properties":{"name":{"type":"string","description":"Internal module name. Pass this as `selectedModuleName` to `initiateCrawler`."},"displayName":{"type":"string","description":"Display name (same as `name`)."},"lastHeartbeat":{"type":"integer","description":"Unix epoch of the last heartbeat received from this module."},"isDefault":{"type":"boolean","description":"Always `false` for external modules."}}}},"actionErrors":{"type":"array","items":{"type":"string"}}}}}}}}}}}}
```

## Start a DAST crawler run

> Creates or reuses an API collection named after the target hostname (tagging it DAST), then starts a crawl run. Supports multiple authentication strategies: username/password form auth, API key, and test role-based token extraction (via recorded login flow or login step builder). Custom HTTP headers, URL template patterns for path normalisation, and seed application pages are all supported.\
> \
> If \`selectedModuleName\` is set, the named DAST module must have sent a heartbeat within the last 5 minutes; otherwise the request returns an error. If null, falls back to the internal Akto DAST crawler service.\
> \
> \`crawlingTime\` must be between 600 (10 minutes) and 345600 (4 days) seconds.\
> \
> Source: \`AktoJaxAction.initiateCrawler()\`

```json
{"openapi":"3.0.1","info":{"title":"AktoSwagger","version":"1.0.0"},"paths":{"/api/initiateCrawler":{"post":{"summary":"Start a DAST crawler run","description":"Creates or reuses an API collection named after the target hostname (tagging it DAST), then starts a crawl run. Supports multiple authentication strategies: username/password form auth, API key, and test role-based token extraction (via recorded login flow or login step builder). Custom HTTP headers, URL template patterns for path normalisation, and seed application pages are all supported.\n\nIf `selectedModuleName` is set, the named DAST module must have sent a heartbeat within the last 5 minutes; otherwise the request returns an error. If null, falls back to the internal Akto DAST crawler service.\n\n`crawlingTime` must be between 600 (10 minutes) and 345600 (4 days) seconds.\n\nSource: `AktoJaxAction.initiateCrawler()`","operationId":"initiateCrawler","tags":["Crawler"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["hostname","crawlingTime"],"properties":{"hostname":{"type":"string","description":"Full URL of the target application (e.g. `https://app.example.com`). The hostname is used as the collection name unless `collectionName` is provided."},"crawlingTime":{"type":"integer","description":"Maximum crawl duration in seconds. Must be between 600 (10 min) and 345600 (4 days)."},"outscopeUrls":{"type":"string","description":"Comma-separated URL paths to exclude from the crawl."},"testRoleHexId":{"type":"string","description":"Optional ObjectId hex of the test role to use for cookie/token extraction. Used when neither username/password nor API key is provided."},"username":{"type":"string","description":"Optional username for basic/form authentication."},"password":{"type":"string","description":"Optional password for basic/form authentication."},"apiKey":{"type":"string","description":"Optional API key to pass to the crawler service."},"dashboardUrl":{"type":"string","description":"Optional Akto dashboard URL to pass to the internal crawler service."},"runTestAfterCrawling":{"type":"boolean","default":false,"description":"If `true`, automatically triggers security tests on all discovered endpoints after the crawl completes."},"selectedMiniTestingService":{"type":"string","description":"Name of the mini testing service to use for post-crawl tests. Only relevant when `runTestAfterCrawling` is `true`."},"selectedModuleName":{"type":"string","description":"Name of the external DAST module to use. The module must have sent a heartbeat within the last 5 minutes. Falls back to the internal Akto DAST service when null."},"collectionName":{"type":"string","description":"Custom collection name. Defaults to the extracted hostname when not provided."},"customHeaders":{"type":"object","additionalProperties":{"type":"string"},"description":"Additional HTTP headers to include in every crawl request."},"urlTemplatePatterns":{"type":"string","description":"Comma-separated URL template patterns used to normalise path parameters (e.g. `/users/{id},/orders/{orderId}`)."},"applicationPages":{"type":"string","description":"Comma-separated seed pages from which the crawl starts."}}}}}},"responses":{"200":{"description":"Crawler initiated. A `CrawlerRun` document is created in MongoDB."},"400":{"description":"`crawlingTime` is outside the 600–345600 range, the selected DAST module is not available, or authentication token extraction via the test role failed."}}}}}}
```

## Upload crawler-captured traffic

> Pushes raw crawler traffic data (in Akto HTTP sample format) for the given collection to Kafka (topic \`akto.api.logs\`) for async ingestion.\
> \
> Source: \`AktoJaxAction.uploadCrawlerData()\`

```json
{"openapi":"3.0.1","info":{"title":"AktoSwagger","version":"1.0.0"},"paths":{"/api/uploadCrawlerData":{"post":{"summary":"Upload crawler-captured traffic","description":"Pushes raw crawler traffic data (in Akto HTTP sample format) for the given collection to Kafka (topic `akto.api.logs`) for async ingestion.\n\nSource: `AktoJaxAction.uploadCrawlerData()`","operationId":"uploadCrawlerData","tags":["Crawler"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["apiCollectionId","crawlerData"],"properties":{"apiCollectionId":{"type":"string","description":"Numeric ID of the target API collection, passed as a string."},"crawlerData":{"type":"string","description":"Akto HTTP sample message JSON captured by the crawler."}}}}}},"responses":{"200":{"description":"Data queued for ingestion."},"400":{"description":"`apiCollectionId` does not match any known collection."}}}}}}
```

## Update crawl run status

> Updates the status of an existing crawl run identified by \`crawlId\`. Depending on the new status:\
> \- \`RUNNING\` — sets \`startTimestamp\` to now\
> \- \`COMPLETED\` — sets \`endTimestamp\` to now and optionally triggers post-crawl security tests if \`runTestAfterCrawling\` was set when the crawl was initiated\
> \- \`FAILED\` — sets \`endTimestamp\` to now and stores the \`errorMessage\`\
> \- \`STOPPED\` — sets \`endTimestamp\` to now\
> \
> Source: \`AktoJaxAction.updateCrawlerStatus()\`

```json
{"openapi":"3.0.1","info":{"title":"AktoSwagger","version":"1.0.0"},"paths":{"/api/updateCrawlerStatus":{"post":{"summary":"Update crawl run status","description":"Updates the status of an existing crawl run identified by `crawlId`. Depending on the new status:\n- `RUNNING` — sets `startTimestamp` to now\n- `COMPLETED` — sets `endTimestamp` to now and optionally triggers post-crawl security tests if `runTestAfterCrawling` was set when the crawl was initiated\n- `FAILED` — sets `endTimestamp` to now and stores the `errorMessage`\n- `STOPPED` — sets `endTimestamp` to now\n\nSource: `AktoJaxAction.updateCrawlerStatus()`","operationId":"updateCrawlerStatus","tags":["Crawler"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["crawlId","status"],"properties":{"crawlId":{"type":"string","description":"UUID of the crawl run to update."},"status":{"type":"string","enum":["RUNNING","COMPLETED","FAILED","STOPPED"],"description":"New status to set on the crawl run."},"errorMessage":{"type":"string","description":"Error details. Only stored when `status` is `FAILED`."}}}}}},"responses":{"200":{"description":"Status updated successfully."}}}}}}
```

## Stop a running crawl

> Sends a stop request to the internal AKTOJAX crawler service and sets the crawl run's status to \`STOP\_REQUESTED\`. The crawler service acknowledges the stop and will complete its current work before shutting down.\
> \
> Source: \`AktoJaxAction.stopCrawler()\`

```json
{"openapi":"3.0.1","info":{"title":"AktoSwagger","version":"1.0.0"},"paths":{"/api/stopCrawler":{"post":{"summary":"Stop a running crawl","description":"Sends a stop request to the internal AKTOJAX crawler service and sets the crawl run's status to `STOP_REQUESTED`. The crawler service acknowledges the stop and will complete its current work before shutting down.\n\nSource: `AktoJaxAction.stopCrawler()`","operationId":"stopCrawler","tags":["Crawler"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["crawlId"],"properties":{"crawlId":{"type":"string","description":"UUID of the crawl run to stop."}}}}}},"responses":{"200":{"description":"Stop request sent and crawl status set to `STOP_REQUESTED`."},"400":{"description":"`crawlId` is null/empty or the crawler service returned a non-success status."}}}}}}
```

## Record a URL discovered by the crawler

> Stores a single URL that was discovered during a crawl, along with provenance information (the source page, the XPath of the triggering element, and the button text) and whether it was accepted (within the crawl scope).\
> \
> Source: \`AktoJaxAction.saveCrawlerUrl()\`

```json
{"openapi":"3.0.1","info":{"title":"AktoSwagger","version":"1.0.0"},"paths":{"/api/saveCrawlerUrl":{"post":{"summary":"Record a URL discovered by the crawler","description":"Stores a single URL that was discovered during a crawl, along with provenance information (the source page, the XPath of the triggering element, and the button text) and whether it was accepted (within the crawl scope).\n\nSource: `AktoJaxAction.saveCrawlerUrl()`","operationId":"saveCrawlerUrl","tags":["Crawler"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","crawlId"],"properties":{"url":{"type":"string","description":"The discovered URL."},"crawlId":{"type":"string","description":"UUID of the crawl run that discovered this URL."},"accepted":{"type":"boolean","description":"Whether this URL was within the crawl scope."},"timestamp":{"type":"integer","description":"Unix epoch when the URL was discovered."},"sourceUrl":{"type":"string","description":"Page URL on which the link to this URL was found."},"sourceXpath":{"type":"string","description":"XPath of the element that triggered navigation to this URL."},"buttonText":{"type":"string","description":"Text content of the element that linked to this URL."}}}}}},"responses":{"200":{"description":"URL saved successfully."},"400":{"description":"`url` or `crawlId` is null/empty."}}}}}}
```
