Findings export
Endpoint
GET /v1/projects/{projectId}/findings/export
The endpoint accepts a Better Auth browser session or bearer token that can read the project. Tenant scoping and PostgreSQL row-level security apply before the export query runs.
The web application calls this endpoint from Findings → Export JSON and downloads thespider-findings-project-{projectId}.json.
Query parameters
| Parameter | Type | Description |
|---|---|---|
campaignId | integer | Include live findings sighted in this campaign. |
status | string | Match one persisted finding status. |
severity | string | Match one canonical severity or impact value. |
bucket | string | Match a bucket code. |
category | string | Match findings with a report in this category. |
branch | string | Match findings sighted on this branch. |
q | string | Case-insensitive title, fingerprint, or bucket search. |
sort | string | priority (default), updated_desc, updated_asc, or title. |
Filters combine with AND. The endpoint ignores list pagination fields and returns the complete filtered set up to the export safety limit.
Response
{
"schemaVersion": 1,
"exportedAt": "2026-07-22T12:00:00.000Z",
"project": {
"id": 42,
"slug": "payments-api",
"name": "Payments API",
"mode": "security"
},
"filters": {
"campaignId": "81",
"severity": "high"
},
"mergedFindingsIncluded": false,
"total": 1,
"findings": [
{
"id": 501,
"canonical_title": "Authorization missing on refund",
"canonical_severity": "high",
"status": "new",
"fingerprint": "…",
"bucket_code": "auth",
"reports": [
{
"id": 702,
"model_code": "sonnet",
"pass_code": "http",
"categories": ["authz"],
"cwes": ["CWE-862"],
"files": [
{ "path": "src/refunds.ts", "line": 88 }
],
"evidence": "…",
"impact": "…",
"recommendation": "…"
}
]
}
]
}
The export includes finding columns plus every attached report and its category, Common Weakness Enumeration (CWE), and file provenance. Model-derived strings remain plain JSON strings.
Identity and merge behavior
The export includes live keeper findings only. Soft-merged tombstones are excluded, and mergedFindingsIncluded is always false in schema version 1. Reports absorbed by a keeper appear under that keeper.
Campaign filtering uses finding sightings. It does not filter by the campaign where a finding was first created.
Size behavior
A filtered export can contain at most 20,000 findings. A larger result returns:
413 export_too_large
Narrow the request with campaignId, severity, status, bucket, category, branch, or search filters. The endpoint returns one JSON document and does not paginate or create an asynchronous export job.
Errors
| Status | Error | Meaning |
|---|---|---|
400 | invalid_project_id | The path identifier is not an integer. |
401 | authentication error | No valid session or bearer token. |
404 | project_not_found | The project does not exist in the authenticated tenant or token scope. |
413 | export_too_large | More than 20,000 findings match. |
429 | rate_limited | Request budget exhausted. |
Use the triage guide for finding lifecycle behavior and the concepts glossary for keeper, merge, and sighting definitions.