Docsary
Markdown Ask Claude Ask ChatGPT
On this page

Reports

Reports are how you tell us something is broken or missing. Filing one stores it against your organization and notifies us; listing them shows you everything your organization has filed and where each one stands.

For the workflow, including what makes a report actionable, see Support.

All endpoints require an organization API key. A read-only key is enough to file — reporting a problem is not a change to your content.

File a report

POST /v1/reports
curl -s -X POST "$DOCSARY_API/v1/reports" \
  -H "authorization: Bearer $DOCSARY_KEY" \
  -H "content-type: application/json" \
  -d '{
    "kind": "bug",
    "title": "Search returns nothing for hyphenated terms",
    "body": "Searching for drop-in on our site returns zero results, but drop in finds the page. Reproduced on two versions.",
    "page_url": "https://docs.acme.com/guide/search",
    "contact": "docs@acme.com",
    "meta": { "client": "ci", "version": "2.4.1" }
  }'
Field Type Required Notes
kind string yes bug or feature. Nothing else is accepted.
title string yes 3–200 characters after trimming. One line; the detail goes in body.
body string yes 10–10000 characters after trimming. Plain text.
page_url string no The page the report is about. An http/https URL, a site-relative path, or a #fragment.
contact string no An email address, at most 200 characters. We reply to it.
meta object no Anything that helps — client name, version, browser. At most 2000 characters once serialized.
{
  "id": "rep_9f2c4a1b7e6d8035c1a4b9e2f7d60a83",
  "kind": "bug",
  "title": "Search returns nothing for hyphenated terms",
  "status": "open",
  "created_at": 1756300000000,
  "email": { "status": "sent" }
}

201 on success. The report is stored before we try to notify ourselves, so the id in this response is a record that exists whatever the email block says.

The email block

Every report is stored first and notified second. This block reports what the second step did, so you never have to guess whether it happened.

status Meaning
sent We were notified.
skipped Notifications are not configured right now, with a reason.
failed The notification could not be delivered, with an error.

A skipped or failed notification does not lose your report. It is stored, it has an id, it appears in your list, and we work from the stored record. This block exists so the response tells you exactly what happened rather than implying more than did.

Errors

Response Cause
400 {"error":"kind must be one of: bug, feature"} kind missing or not one of the two
400 {"error":"title required (string)"} title missing or not a string
400 containing title must be 3..200 characters Title too short or too long
400 {"error":"body required (string)"} body missing or not a string
400 containing body must be 10..10000 characters Body too short or too long
400 containing unsafe page_url page_url is not an allowed URL shape
400 {"error":"contact must look like an email address"} contact is not an email address
400 {"error":"meta must be an object"} meta is an array or a scalar
400 containing meta is too large meta serializes to more than 2000 characters
401 {"error":"missing bearer token"} No key. There is no anonymous filing path
403 {"error":"org API key required (not admin token)"} A report belongs to an organization
429 containing reports per hour Your organization's hourly filing limit

The page_url allow-list is the one used for site settings and markdown links: http:, https:, mailto:, a path beginning with a single /, or a #fragment. javascript:, data:, protocol-relative //host, and schemeless relative paths are refused:

{"error":"unsafe page_url (allowed: http:, https:, mailto:, or a /site-relative path)"}

Filing limit

An organization may file 20 reports per hour. The 21st is refused with 429:

{
  "error": "too many reports: this organization may file 20 reports per hour. Add the detail to an existing report, or wait and file again.",
  "limit": 20,
  "window": "hour"
}

Nothing is stored, and the reports you already filed are untouched. The limit is per organization and counted over the preceding hour rather than reset on the clock hour. If you have a real reason to exceed it — a batch of findings from an audit, say — ask us rather than looping.

List your reports

GET /v1/reports
curl -s -H "authorization: Bearer $DOCSARY_KEY" \
  "$DOCSARY_API/v1/reports?status=open&limit=20"
{
  "reports": [
    {
      "id": "rep_9f2c4a1b7e6d8035c1a4b9e2f7d60a83",
      "kind": "bug",
      "title": "Search returns nothing for hyphenated terms",
      "body": "Searching for drop-in on our site returns zero results...",
      "page_url": "https://docs.acme.com/guide/search",
      "contact": "docs@acme.com",
      "meta": { "client": "ci", "version": "2.4.1" },
      "status": "open",
      "created_at": 1756300000000
    }
  ],
  "next_offset": null
}

Newest first. You see your own organization's reports and nothing else — the organization is taken from your key, never from the request.

Parameter Default Notes
status all open, triaged, or closed. Any other value is a 400.
limit 50 Capped at 200.
offset 0 Rows to skip.

next_offset is the offset to pass for the next page, or null once you have reached the end — the same paging shape as rerender.

status Meaning
open Received, not yet looked at
triaged Read and understood, and on a list
closed Done, or decided against

Status is set by us. There is no endpoint for an organization to change it; to reopen something, file a new report and quote the old id in the body.

Errors

Response Cause
400 containing unknown status status is not one of the three
400 {"error":"limit must be a positive number"} limit is zero, negative, or not a number
400 {"error":"offset must be zero or a positive number"} offset is negative or not a number
401 {"error":"missing bearer token"} No key
403 {"error":"org API key required (not admin token)"} The list is scoped to an organization