---
title: Report
kind: resource
slug: report
summary: "A bug, feature request, or question filed against Drop. Each Report is backed by a GitHub issue in `himarley/drop`; the case number is the issue number."
---

# Report

A bug, feature request, or question filed against Drop. Each Report is backed by a GitHub issue in `himarley/drop`; the case number is the issue number.

A **Report** is how anyone files a bug, feature request, or question about Drop. Filing a report opens a GitHub issue in `himarley/drop` (labeled by kind), and the **case number is that issue number**. A thin Postgres row bridges the reporter (a Drop user, not a GitHub account) to the issue — that's what powers "my reports" listing, attribution, and email notifications. GitHub stays the source of truth for the body, comment thread, and authoritative status, which are reconciled on read. The conversational AI **intake** (`drop report` interactively, or `POST /api/reports/intake`) and the inbound GitHub **webhook** are hand-written surfaces and are not listed among the methods below.

## The Report object

### Attributes

- **`caseNumber`** `number` — The case number — identical to the GitHub issue number in `himarley/drop`. Stable for the lifetime of the report; appears in every API path (`/api/reports/{caseNumber}`) and in `drop reports` commands.
- **`kind`** `enum` (enum: `BUG` / `FEATURE` / `QUESTION`) — **What kind of report this is.** Set at filing time and written to GitHub as a label. `BUG` — something is broken; `FEATURE` — a request for new behavior; `QUESTION` — a how-do-I / clarification.
- **`status`** `enum` (enum: `OPEN` / `TRIAGED` / `IN_PROGRESS` / `RESOLVED` / `WONT_FIX`) — **Triage status**, reconciled from the GitHub issue on read. `OPEN` at filing. Admins move it through `TRIAGED` → `IN_PROGRESS` → `RESOLVED` / `WONT_FIX` (each writes the matching GitHub label/state and emails the reporter). Reporters can `open`/`close` their own report via `state` but cannot set `status`.
- **`title`** `string` — Short title for the issue (4–160 characters). Becomes the GitHub issue title.
- **`appSlug`** `string · nullable` — Optional slug of the [Droplet](/docs/resources/droplet) this report is about. Lowercase letters, digits, and hyphens. Surfaced in the issue body so triagers know which Droplet is affected.
- **`githubUrl`** `string · nullable` — Direct link to the backing GitHub issue. Null only transiently if the issue link has not yet been resolved.
- **`commentCount`** `number` — Number of comments on the GitHub issue thread. Present on the detail shape (`get`), reconciled on read.
- **`body`** `string · nullable · less-common` — Full description (markdown), up to 20,000 characters. Returned on the detail shape (`get` / `create`); omitted from the list summary. Source of truth is the GitHub issue body.
- **`source`** `string · nullable · less-common` — Where the report was filed from: `cli` | `drop-bar` | `web` | `slack` | `mcp`. Provenance only — does not affect routing.
- **`reporterName`** `string · nullable · less-common` — Display name of the Drop user who filed the report. Used for attribution in the issue body and comments (Drop's bot identity writes to GitHub on their behalf).
- **`reporterEmail`** `string · nullable · less-common` — Email of the reporter. Used for SES status-change notifications. Only returned to the reporter themselves or an admin.
- **`closedAt`** `timestamp · nullable · less-common` — ISO 8601 timestamp the backing issue was closed, or null while open. Detail shape only.
- **`createdAt`** `timestamp · less-common` — ISO 8601 timestamp the report was filed.
- **`updatedAt`** `timestamp · less-common` — ISO 8601 timestamp of the last status / metadata change.

### JSON example

```json
{
  "caseNumber": 142,
  "kind": "BUG",
  "status": "IN_PROGRESS",
  "title": "PDF export spins forever on the Q3 board",
  "body": "**Steps**: open q3-board, click Export PDF.\n**Expected**: a PDF.\n**Actual**: spinner never resolves.",
  "appSlug": "q3-board",
  "source": "cli",
  "reporterName": "Dana Reyes",
  "reporterEmail": "dana.reyes@himarley.com",
  "githubUrl": "https://github.com/himarley/drop/issues/142",
  "commentCount": 2,
  "closedAt": null,
  "createdAt": "2026-06-18T15:02:00.000Z",
  "updatedAt": "2026-06-18T16:20:00.000Z"
}
```

## Methods

### List Reports

`GET /api/reports`

List reports you filed (most recent first). Admins can pass `all=true` to list every reporter's reports. Filter by `status` and/or `kind`.

**Parameters**

- **`all`** _(boolean · query)_ — Admin only: include all reporters' reports.
- **`status`** _(string · query)_ — Filter by status (OPEN|TRIAGED|IN_PROGRESS|RESOLVED|WONT_FIX).
- **`kind`** _(string · query)_ — Filter by kind (BUG|FEATURE|QUESTION).

**CLI**

```bash
drop reports list --status OPEN
```

**MCP**

```json
{
  "tool": "drop_reports_list",
  "arguments": {
    "status": "OPEN"
  }
}
```

**HTTP**

```bash
curl -X GET 'https://drop.himarley.ai/api/reports' \
  -H "Authorization: Bearer $DROP_TOKEN"
```

**Response** (200)

```json
[
  {
    "caseNumber": 142,
    "kind": "BUG",
    "status": "OPEN",
    "title": "PDF export spins forever on the Q3 board",
    "appSlug": "q3-board",
    "source": "cli",
    "reporterName": "Dana Reyes",
    "reporterEmail": "dana.reyes@himarley.com",
    "githubUrl": "https://github.com/himarley/drop/issues/142",
    "createdAt": "2026-06-18T15:02:00.000Z",
    "updatedAt": "2026-06-18T15:02:00.000Z"
  }
]
```

### File a Report

`POST /api/reports`

File a report — creates a GitHub issue in `himarley/drop` (labeled with the kind) and returns the **case number** (= the issue number). Takes an already-structured `{ kind, title, body }`; the conversational AI intake that produces that structure runs separately (`drop report` interactively, or `POST /api/reports/intake`). Optionally link a Droplet via `appSlug`.

**Parameters**

- **`kind`** _(string · body · required)_ — bug | feature | question.
- **`title`** _(string · body · required)_ — Short title for the issue.
- **`body`** _(string · body · required)_ — Full description (markdown).
- **`appSlug`** _(string · body)_ — Optional Droplet this concerns.
- **`source`** _(string · body)_ — Provenance: cli | drop-bar | web | slack | mcp.

**CLI**

```bash
drop reports create --kind BUG --title "PDF export spins forever on the Q3 board" --body "**Steps**: open q3-board, click Export PDF.
**Expected**: a PDF.
**Actual**: spinner never resolves (since this morning)." --app-slug q3-board --source cli
```

**MCP**

```json
{
  "tool": "drop_reports_create",
  "arguments": {
    "kind": "BUG",
    "title": "PDF export spins forever on the Q3 board",
    "body": "**Steps**: open q3-board, click Export PDF.\n**Expected**: a PDF.\n**Actual**: spinner never resolves (since this morning).",
    "appSlug": "q3-board",
    "source": "cli"
  }
}
```

**HTTP**

```bash
curl -X POST 'https://drop.himarley.ai/api/reports' \
  -H "Authorization: Bearer $DROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"kind":"BUG","title":"PDF export spins forever on the Q3 board","body":"**Steps**: open q3-board, click Export PDF.\n**Expected**: a PDF.\n**Actual**: spinner never resolves (since this morning).","appSlug":"q3-board","source":"cli"}'
```

**Response** (201)

```json
{
  "caseNumber": 142,
  "kind": "BUG",
  "status": "OPEN",
  "title": "PDF export spins forever on the Q3 board",
  "body": "**Steps**: open q3-board…",
  "appSlug": "q3-board",
  "source": "cli",
  "reporterName": "Dana Reyes",
  "reporterEmail": "dana.reyes@himarley.com",
  "githubUrl": "https://github.com/himarley/drop/issues/142",
  "createdAt": "2026-06-18T15:02:00.000Z",
  "updatedAt": "2026-06-18T15:02:00.000Z",
  "closedAt": null,
  "commentCount": 0
}
```

### Get a Report

`GET /api/reports/{caseNumber}`

Fetch one report by case number, including its current status (reconciled from GitHub on read), body, and comment count. Returns 404 if the report isn't yours (and you're not an admin) — no enumeration leak.

**Parameters**

- **`caseNumber`** _(number · path · required)_ — The case number (= GitHub issue number).

**CLI**

```bash
drop reports get 142
```

**MCP**

```json
{
  "tool": "drop_reports_get",
  "arguments": {
    "caseNumber": 142
  }
}
```

**HTTP**

```bash
curl -X GET 'https://drop.himarley.ai/api/reports/142' \
  -H "Authorization: Bearer $DROP_TOKEN"
```

**Response** (200)

```json
{
  "caseNumber": 142,
  "kind": "BUG",
  "status": "IN_PROGRESS",
  "title": "PDF export spins forever on the Q3 board",
  "body": "**Steps**: open q3-board…",
  "appSlug": "q3-board",
  "source": "cli",
  "reporterName": "Dana Reyes",
  "reporterEmail": "dana.reyes@himarley.com",
  "githubUrl": "https://github.com/himarley/drop/issues/142",
  "createdAt": "2026-06-18T15:02:00.000Z",
  "updatedAt": "2026-06-18T16:20:00.000Z",
  "closedAt": null,
  "commentCount": 2
}
```

### Update a Report

`PATCH /api/reports/{caseNumber}`

Change a report's triage status or open/closed state. Setting `status` (TRIAGED / IN_PROGRESS / RESOLVED / WONT_FIX) is **admin only** and writes the corresponding GitHub label/state, then notifies the reporter. `state` (open / closed) lets the reporter withdraw or reopen their own report.

**Parameters**

- **`caseNumber`** _(number · path · required)_ — The case number.
- **`status`** _(string · body)_ — New triage status (admin only).
- **`state`** _(string · body)_ — open | closed (reporter or admin).

**CLI**

```bash
drop reports set-status 142 --status IN_PROGRESS
```

**MCP**

```json
{
  "tool": "drop_reports_set_status",
  "arguments": {
    "caseNumber": 142,
    "status": "IN_PROGRESS"
  }
}
```

**HTTP**

```bash
curl -X PATCH 'https://drop.himarley.ai/api/reports/142' \
  -H "Authorization: Bearer $DROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status":"IN_PROGRESS"}'
```

**Response** (200)

```json
{
  "caseNumber": 142,
  "kind": "BUG",
  "status": "IN_PROGRESS",
  "title": "PDF export spins forever on the Q3 board",
  "body": null,
  "appSlug": "q3-board",
  "source": "cli",
  "reporterName": "Dana Reyes",
  "reporterEmail": "dana.reyes@himarley.com",
  "githubUrl": "https://github.com/himarley/drop/issues/142",
  "createdAt": "2026-06-18T15:02:00.000Z",
  "updatedAt": "2026-06-18T16:20:00.000Z",
  "closedAt": null,
  "commentCount": 2
}
```

### Comment on a Report

`POST /api/reports/{caseNumber}/comments`

Add a comment to a report. Posts to the GitHub issue attributed to the reporter (Drop's bot identity writes it; the reporter's name is in the body). Allowed for the reporter or an admin.

**Parameters**

- **`caseNumber`** _(number · path · required)_ — The case number.
- **`body`** _(string · body · required)_ — The comment text (markdown).

**CLI**

```bash
drop reports comment 142 --body "Still happening on prod this morning."
```

**MCP**

```json
{
  "tool": "drop_reports_comment",
  "arguments": {
    "caseNumber": 142,
    "body": "Still happening on prod this morning."
  }
}
```

**HTTP**

```bash
curl -X POST 'https://drop.himarley.ai/api/reports/142/comments' \
  -H "Authorization: Bearer $DROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"body":"Still happening on prod this morning."}'
```

**Response** (201)

```json
{
  "caseNumber": 142,
  "author": "Dana Reyes",
  "body": "Still happening on prod this morning.",
  "url": "https://github.com/himarley/drop/issues/142#issuecomment-1",
  "createdAt": "2026-06-18T17:00:00.000Z"
}
```

### List Report Comments

`GET /api/reports/{caseNumber}/comments`

List the comment thread on a report (from the GitHub issue), oldest first. Allowed for the reporter or an admin.

**Parameters**

- **`caseNumber`** _(number · path · required)_ — The case number.

**CLI**

```bash
drop reports comments 142
```

**MCP**

```json
{
  "tool": "drop_reports_comments",
  "arguments": {
    "caseNumber": 142
  }
}
```

**HTTP**

```bash
curl -X GET 'https://drop.himarley.ai/api/reports/142/comments' \
  -H "Authorization: Bearer $DROP_TOKEN"
```

**Response** (200)

```json
[
  {
    "author": "Dana Reyes",
    "body": "Still happening on prod this morning.",
    "url": "https://github.com/himarley/drop/issues/142#issuecomment-1",
    "createdAt": "2026-06-18T17:00:00.000Z",
    "fromReporter": true
  }
]
```
