Skip to content
Median
Esc
↑↓navigate↵open⌘Jpreview

Submit feedback

One note in, a verdict out. A fast model reads what was written, calls it a bug or a suggestion, writes the title and the write-up, picks a priority, and drops it if it is spam. A note about something already on the list joins that signal instead of adding a row, so the same complaint from ten people is one signal with ten reporters.

This is the endpoint behind the feedback panel, and the one for notes collected anywhere else: an app store review, a survey, a message in a community. Use POST /v1/signals when you already know what the thing is and how it should read.

It waits for the reading, so expect a second or two. outcome is unread when the reader was unavailable or the organization has filing switched off; nothing is filed either way.

POST/feedback
Authorization
AuthorizationBearer token · headerrequired
`MEDIAN_KEY` from Settings under API, or an MCP OAuth access token. A key acts as the organization; a token acts as the person who approved it.
Request body
requiredapplication/json
sessionstringrequired
Who the note is from: any stable id for that person, the same one every time. It is what makes two notes from one person one reporter, and it is the browser's session token when the note comes from the widget. 8 to 128 characters.
bodystringrequired
What they actually wrote, in their words.
max length 2000
userobject
Their name and email, if you know them.
Show properties
namestring
emailstring
avatarUrlstring
pageobject
Where they were. The query string is dropped before the URL is stored.
Show properties
urlstring
titlestring
referrerstring
imagesstring | object[]
Pictures of the thing, as http or https addresses. They show on the report and on any issue it is pushed to. A bare string works where you have nothing to call it.
max items 6
Show properties
Array of string | object
One of:
string
string
object
urlstringrequired
namestring
What it shows, in a few words. Read off the address when left out.
Responses
200Where the note ended up.
outcomestring
Allowed:bugsuggestionspamunread
signalIdstring | null
The signal it landed on, or null when nothing was filed.
400The request is malformed, and the message names the field.
errorobject
Show properties
codestring
messagestring
401The bearer token is missing, revoked, or expired.
errorobject
Show properties
codestring
messagestring
429Too many requests. Wait the seconds in `Retry-After`. Limits depend on the plan. See [rate limits](/api/errors-and-limits#rate-limits).
errorobject
Show properties
codestring
messagestring
Request
curl -X POST "https://api.median.sh/v1/feedback" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "session": "user_8812",
  "body": "The export button on the billing page does nothing on my phone.",
  "page": {
    "url": "https://acme.com/settings/billing"
  },
  "images": [
    {
      "url": "https://files.acme.com/reports/8812-billing.png",
      "name": "Billing page on iOS"
    }
  ]
}'
Response
{
  "outcome": "bug",
  "signalId": "string"
}