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

# Bugs API: list, retrieve, and triage Detail bug findings

> List, retrieve, and triage Detail bug findings programmatically. Filter by status, paginate results, and resolve or dismiss bugs via the API.

The bugs endpoints give you full programmatic access to Detail's findings. You can list all pending bugs for a repository, fetch a single bug's details, and update a bug's review state — all without leaving your own tooling.

***

## GET /public/v1/bugs

Returns a paginated list of bugs for a repository, filtered by review status.

```bash theme={null}
curl "https://api.detail.dev/public/v1/bugs?repo_id=repo_abc123&status=pending" \
  -H "Authorization: Bearer dtl_live_YOUR_KEY"
```

### Query parameters

<ParamField query="repo_id" type="string" required>
  The repository ID to fetch bugs for. Repository IDs are prefixed with `repo_` and can be retrieved from [GET /public/v1/repos](/api/repos). Example: `repo_abc123`.
</ParamField>

<ParamField query="status" type="string" required>
  Filter bugs by review state. One of:

  * `pending` — bugs that have not yet been reviewed
  * `resolved` — bugs marked as fixed
  * `dismissed` — bugs marked as not actionable
</ParamField>

<ParamField query="limit" type="integer">
  Number of results to return. Between `1` and `100`. Defaults to `50`.
</ParamField>

<ParamField query="offset" type="integer">
  Number of results to skip for pagination. Defaults to `0`.
</ParamField>

<ParamField query="workflow_request_id" type="string">
  Filter bugs to those surfaced by a specific scan. Workflow request IDs are prefixed with `wr_` and are returned by [GET /public/v1/scans](/api/scans).
</ParamField>

### Response

<ResponseField name="bugs" type="Bug[]">
  Array of bug objects matching the query.

  <Expandable title="Bug fields">
    <ResponseField name="id" type="string">
      Unique bug identifier, prefixed with `bug_`.
    </ResponseField>

    <ResponseField name="title" type="string">
      Short title describing the finding.
    </ResponseField>

    <ResponseField name="summary" type="string">
      Detailed description of the bug and its potential impact.
    </ResponseField>

    <ResponseField name="filePath" type="string | null">
      Path to the file where the bug was found, relative to the repository root.
    </ResponseField>

    <ResponseField name="commitSha" type="string | null">
      The commit SHA at which this bug was identified.
    </ResponseField>

    <ResponseField name="isSecurityVulnerability" type="boolean | null">
      Whether Detail has classified this finding as a security vulnerability.
    </ResponseField>

    <ResponseField name="repoId" type="string">
      ID of the repository this bug belongs to.
    </ResponseField>

    <ResponseField name="createdAt" type="integer">
      Unix timestamp (milliseconds) when the bug was first found.
    </ResponseField>

    <ResponseField name="introducedIn" type="object | null">
      Attribution data for the commit that introduced the bug.

      <Expandable title="introducedIn fields">
        <ResponseField name="sha" type="string">
          Full commit SHA.
        </ResponseField>

        <ResponseField name="date" type="string">
          Date the commit was made, in `YYYY-MM-DD` format.
        </ResponseField>

        <ResponseField name="author" type="string">
          GitHub username or name of the commit author.
        </ResponseField>

        <ResponseField name="prNumber" type="integer">
          Pull request number that introduced the bug, if applicable.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="review" type="object | null">
      The current review record for this bug. Present when the bug has been reviewed.

      <Expandable title="review fields">
        <ResponseField name="state" type="string">
          One of `pending`, `resolved`, or `dismissed`.
        </ResponseField>

        <ResponseField name="createdAt" type="integer">
          Unix timestamp (milliseconds) when the review was created.
        </ResponseField>

        <ResponseField name="dismissalReason" type="string">
          Reason for dismissal. One of `not_a_bug`, `wont_fix`, `duplicate`, or `other`. Only present when `state` is `dismissed`.
        </ResponseField>

        <ResponseField name="notes" type="string">
          Free-text note left during review.
        </ResponseField>

        <ResponseField name="source" type="string">
          How the review was created. One of `review`, `linear`, `jira`, `asana`, `github_issue`, or `bug_fix_check`.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="linkedIssues" type="LinkedIssue[]">
      Issues in external trackers linked to this bug.

      <Expandable title="LinkedIssue fields">
        <ResponseField name="tracker" type="string">
          One of `linear`, `jira`, `github`, `slack`, or `asana`.
        </ResponseField>

        <ResponseField name="issueId" type="string">
          The issue identifier in the external tracker.
        </ResponseField>

        <ResponseField name="url" type="string | null">
          Direct URL to the issue in the external tracker.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="total" type="integer">
  Total number of bugs matching the query, regardless of `limit` and `offset`.
</ResponseField>

### Example response

```json theme={null}
{
  "bugs": [
    {
      "id": "bug_abc123",
      "title": "SQL injection in user search",
      "summary": "User-controlled input is passed directly to a raw SQL query without sanitization, enabling SQL injection attacks.",
      "filePath": "src/db/users.ts",
      "commitSha": "abc1234567890abcdef",
      "isSecurityVulnerability": true,
      "repoId": "repo_xyz789",
      "createdAt": 1736899200000,
      "introducedIn": {
        "sha": "abc1234def5678",
        "date": "2024-12-10",
        "author": "alice",
        "prNumber": 42
      },
      "review": null,
      "linkedIssues": []
    }
  ],
  "total": 12
}
```

***

## GET /public/v1/bugs/\{bug\_id}

Returns a single bug by its ID. The response shape is identical to an individual item in the `bugs` array above.

```bash theme={null}
curl https://api.detail.dev/public/v1/bugs/bug_abc123 \
  -H "Authorization: Bearer dtl_live_YOUR_KEY"
```

### Path parameters

<ParamField path="bug_id" type="string" required>
  The bug ID to retrieve. Must match the pattern `bug_*`.
</ParamField>

### Example response

```json theme={null}
{
  "id": "bug_abc123",
  "title": "SQL injection in user search",
  "summary": "User-controlled input is passed directly to a raw SQL query without sanitization, enabling SQL injection attacks.",
  "filePath": "src/db/users.ts",
  "commitSha": "abc1234567890abcdef",
  "isSecurityVulnerability": true,
  "repoId": "repo_xyz789",
  "createdAt": 1736899200000,
  "introducedIn": {
    "sha": "abc1234def5678",
    "date": "2024-12-10",
    "author": "alice",
    "prNumber": 42
  },
  "review": null,
  "linkedIssues": [
    {
      "tracker": "linear",
      "issueId": "ENG-101",
      "url": "https://linear.app/team/issue/ENG-101"
    }
  ]
}
```

***

## POST /public/v1/bugs/\{bug\_id}/review

Creates or updates a review on a bug. Use this to resolve, dismiss, or reopen a finding programmatically.

```bash theme={null}
curl -X POST https://api.detail.dev/public/v1/bugs/bug_abc123/review \
  -H "Authorization: Bearer dtl_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "state": "dismissed",
    "dismissalReason": "not_a_bug",
    "notes": "Reviewed — this is expected behavior in the context of our auth middleware."
  }'
```

### Path parameters

<ParamField path="bug_id" type="string" required>
  The bug ID to review. Must match the pattern `bug_*`.
</ParamField>

### Request body

<ParamField body="state" type="string" required>
  The new review state for the bug. One of:

  * `resolved` — the bug has been fixed
  * `dismissed` — the bug is not actionable
  * `pending` — reopen a previously reviewed bug
</ParamField>

<ParamField body="dismissalReason" type="string">
  Required when `state` is `dismissed`. One of:

  * `not_a_bug` — the finding is a false positive
  * `wont_fix` — the team has decided not to address this
  * `duplicate` — already tracked elsewhere
  * `other` — any other reason
</ParamField>

<ParamField body="notes" type="string">
  Optional free-text note to record with the review. Useful for explaining triage decisions.
</ParamField>

### Response

Returns the created or updated `BugReview` object.

<ResponseField name="state" type="string">
  The review state: `pending`, `resolved`, or `dismissed`.
</ResponseField>

<ResponseField name="createdAt" type="integer">
  Unix timestamp (milliseconds) when this review was recorded.
</ResponseField>

<ResponseField name="dismissalReason" type="string">
  The dismissal reason, if `state` is `dismissed`.
</ResponseField>

<ResponseField name="notes" type="string">
  The note recorded with the review, if provided.
</ResponseField>

<ResponseField name="source" type="string">
  How the review was created. For API-created reviews this is `review`.
</ResponseField>

### Example response

```json theme={null}
{
  "state": "dismissed",
  "createdAt": 1736985600000,
  "dismissalReason": "not_a_bug",
  "notes": "Reviewed — this is expected behavior in the context of our auth middleware.",
  "source": "review"
}
```

<Note>
  Calling this endpoint on a bug that already has a review will overwrite the existing review with the new state.
</Note>
