# Feedback API

> Report a problem or a missing feature to the Checkbox team.

| Operation | Endpoint |
|---|---|
| [Send feedback](#createFeedback) | `POST /v1/feedback` |
| [Claim the one-time review prompt for a site](#claimReviewPrompt) | `POST /v1/sites/{site}/review_prompt` |

## The Feedback object

Feedback sent to the Checkbox team.

| Field | Type | Description |
|---|---|---|
| `id` | string | Unique identifier of the feedback (fb_…). |
| `object` | enum | String representing the object's type. Always "feedback". |
| `type` | enum | Kind of feedback. One of `bug`, `idea`, `question`, `review`. |
| `status` | enum | open until Checkbox staff reply or close it. One of `open`, `replied`, `closed`. |
| `redacted` | boolean | true when text that looked like a secret, card number or email address was replaced with [redacted] before it was stored. |
| `created` | integer | When it was received. Unix timestamp in seconds. |

## Send feedback {#createFeedback}

`POST /v1/feedback`

Report a problem or a missing feature in Checkbox. Include what you tried, what happened and what you expected, and the site / request id when there is one. With type review, send a structured review of Checkbox the product (score 0-10, liked, disliked, wrong_verdicts, would_keep_using, stack) — only after the human said yes and saw the text. A review describes what worked or did not in Checkbox: it never states that the site broke a law or had unfixed problems, and carries no site names, URLs, customer data or quotes of the site's pages or emails (URLs are removed and no site is attached). Never include secrets or customer data: anything that looks like a secret, card number or email address is replaced with [redacted]. The Checkbox team reads every message. Rate limited to 20 per key per hour.

**Scope** `account:read` · **Idempotent** (send `Idempotency-Key`) · **Operation** `createFeedback`

SDK: `checkbox.feedbacks.create()` (Node) · `checkbox.feedbacks.create()` (Python). MCP / agents: operation `createFeedback`.

#### Body

| Field | Type | Description |
|---|---|---|
| `type` | enum | bug: something is broken; idea: a missing feature or improvement; question: something unclear; review: a structured review of Checkbox the product (send only after the human said yes and saw the text; no site names, URLs, customer data, quotes of the site's pages or emails, or claims that the site broke a law). Default idea. One of `bug`, `idea`, `question`, `review`. |
| `message` | string | What you tried, what happened and what you expected (at most 5000 characters). Required except for type review. Secrets, card numbers and email addresses are replaced with [redacted]. |
| `score` | integer | type review (required): how likely the human is to recommend Checkbox, 0-10. |
| `liked` | array of strings | type review: what worked, at most 5 short phrases. |
| `disliked` | array of strings | type review: what did not work, at most 5 short phrases. |
| `wrong_verdicts` | array of strings | type review: Checkbox verdicts the human believes were wrong, each "<check id>: <short reason about Checkbox's verdict>" (at most 5; the reason is kept to 200 characters). |
| `would_keep_using` | boolean | type review: whether the human would keep using Checkbox. |
| `stack` | string | type review: framework and billing, short. |
| `context` | object | Optional context that helps us reproduce it. For type review only agent and tool are kept (reviews never carry the site or request id). |
| `context.site` | string | Site id the feedback is about. |
| `context.request_id` | string | Request-Id of the API call it is about. |
| `context.tool` | string | MCP tool or CLI command involved. |
| `context.agent` | string | The agent or client sending it. |

#### Returns

Returns a [Feedback](https://checkbox.site/docs/api/feedback#the-feedback-object) object.

Errors use the [standard envelope](https://checkbox.site/docs/api/errors) with a stable `code` and, where useful, `next_action`.

```curl
curl https://app.checkbox.site/v1/feedback \
  -u "$CHECKBOX_SECRET_KEY:" \
  -H "Content-Type: application/json" \
  -d '{
  "type": "bug",
  "message": "verify_task returned needs_review for signup.consent.affirmative although the checkbox is unchecked by default.",
  "context": {
    "tool": "verify_task",
    "agent": "claude-code"
  }
}'
```
```node
import Checkbox from '@checkbox-site/node';

const checkbox = new Checkbox(process.env.CHECKBOX_SECRET_KEY);

const feedback = await checkbox.feedbacks.create({
  type: 'bug',
  message: 'verify_task returned needs_review for signup.consent.affirmative although the checkbox is unchecked by default.',
  context: { tool: 'verify_task', agent: 'claude-code' },
});
console.log(feedback);
```
```python
import os
from checkbox import Checkbox

checkbox = Checkbox(os.environ["CHECKBOX_SECRET_KEY"])

feedback = checkbox.feedbacks.create(
    type="bug",
    message="verify_task returned needs_review for signup.consent.affirmative although the checkbox is unchecked by default.",
    context={"tool": "verify_task", "agent": "claude-code"},
)
print(feedback)
```

```json title="Response"
{
  "id": "fb_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "object": "feedback",
  "type": "bug",
  "status": "open",
  "redacted": false,
  "created": 1793318400
}
```

## Claim the one-time review prompt for a site {#claimReviewPrompt}

`POST /v1/sites/{site}/review_prompt`

The MCP tools call this when a site's compliance plan reaches compliant (including "Compliant · N live checks pending"). show is true exactly once per site: the agent then asks the human once whether they want to send a quick review of Checkbox (createFeedback with type review), and sends it only on a yes, after showing the text. Never send a review without the human's yes.

**Scope** `compliance_plans:read` · **Operation** `claimReviewPrompt`

SDK: `checkbox.reviewPrompts.claim()` (Node) · `checkbox.review_prompts.claim()` (Python). MCP / agents: operation `claimReviewPrompt`.

#### Parameters

| Parameter | In | Type | Description |
|---|---|---|---|
| `site` **required** | path | string | Unique identifier of the site (site_…). |

#### Body

| Field | Type | Description |
|---|---|---|
| `trigger` | enum | What reached compliant: the plan (retrieveCompliancePlan) or the verification of the last required task (verifyTask). Default plan_compliant. One of `plan_compliant`, `last_task_verified`. |

#### Returns

Returns a `ReviewPrompt` object.

Errors use the [standard envelope](https://checkbox.site/docs/api/errors) with a stable `code` and, where useful, `next_action`.

```curl
curl https://app.checkbox.site/v1/sites/site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b/review_prompt \
  -u "$CHECKBOX_SECRET_KEY:" \
  -H "Content-Type: application/json" \
  -d '{}'
```
```node
import Checkbox from '@checkbox-site/node';

const checkbox = new Checkbox(process.env.CHECKBOX_SECRET_KEY);

const reviewPrompt = await checkbox.reviewPrompts.claim('site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b');
console.log(reviewPrompt);
```
```python
import os
from checkbox import Checkbox

checkbox = Checkbox(os.environ["CHECKBOX_SECRET_KEY"])

review_prompt = checkbox.review_prompts.claim("site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b")
print(review_prompt)
```

```json title="Response"
{
  "object": "review_prompt",
  "site": "site_3f9a1c2e7b4d4e0f9a8b7c6d5e4f3a2b",
  "show": true,
  "reason": "first_time",
  "message": "Ask the user once whether they want to send Checkbox a quick review of this session…",
  "shown_at": 1793318400
}
```
