API reference

API reference: POST /api/feedback

Create one feedback item. This is the same endpoint the widget uses, and it is open to direct calls from any language.

Request

Endpoint
POST https://usero.io/api/feedback
Content-Type: application/json
  • CORS: Access-Control-Allow-Origin: *. Call it straight from browsers, mobile apps, desktop apps, or servers.
  • Auth: the clientId in the body identifies your project. No API key, no auth header.
  • Abuse control: if your client has a domain allowlist configured in Settings, requests from other origins get a 403. New clients have no allowlist, so everything is accepted.

Required fields

clientId is always required. On top of that, every submission needs a rating (1 to 4), a non-empty comment, or both. Everything else is optional.

Fields

Field Type Required Description
clientId string yes Your project id, starts with client_. See Find your clientId.
rating integer one of rating / comment 1 to 4: 1 Terrible, 2 Bad, 3 Good, 4 Amazing.
comment string one of rating / comment Free-text feedback. Must be non-empty if no rating is sent.
userEmail string no The submitter's email, must be a valid address. Lets you reply and groups feedback by person in the dashboard. An empty string is treated as absent.
pageUrl string no URL the feedback was given on. If omitted, the server falls back to the Referer header.
pageTitle string no Title of the page the feedback was given on.
referrer string no The page the user arrived from.
environment string no Tags the feedback with an environment (for example staging). See the warning below before sending this.
screenshots array no Screenshot objects returned by POST /api/screenshots. Each item: fileName (string), url (string), fileSize (number), mimeType (string), width (number, optional), height (number, optional).
metadata object no Arbitrary JSON attached to the feedback, 10KB max when serialized. Good place for app version, OS, build number, or feature flags.
sessionReplayId string no 1 to 128 characters. Links the feedback to a session replay recorded by the session replay plugin.
replayOffsetMs integer no Non-negative millisecond offset into the linked replay at which the feedback was given.

Warning

Omit environment for your default environment. Do not send a placeholder like "no-env" or "default". The dashboard treats an absent environment as the default; a literal placeholder string creates a separate environment and your feedback will not appear in the default inbox.

Examples

Minimal submission:

curl -X POST https://usero.io/api/feedback \
  -H "Content-Type: application/json" \
  -d '{"clientId": "YOUR_CLIENT_ID", "rating": 3}'

Full-field submission:

curl -X POST https://usero.io/api/feedback \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "YOUR_CLIENT_ID",
    "rating": 2,
    "comment": "Export to CSV times out on large projects",
    "userEmail": "jamie@example.com",
    "pageUrl": "https://yourapp.com/projects/42/export",
    "pageTitle": "Export project",
    "referrer": "https://yourapp.com/projects/42",
    "environment": "staging",
    "metadata": {
      "appVersion": "2.4.1",
      "os": "macOS 15.2",
      "build": 1842
    }
  }'

For native apps, metadata is the place for app version, OS version, and build number, so every report arrives with the context you need to reproduce it.

Response

Success:

json
{ "success": true, "feedbackId": "abc123" }

Errors

Status Body Meaning and fix
400 {"error": "Invalid data provided", "issues": {"rating": ["..."]}} Validation failed. issues names each failing field. The most common cause: neither rating nor a non-empty comment was sent.
400 {"error": "Metadata too large (max 10KB)"} Serialized metadata exceeds 10KB. Trim it.
403 {"error": "Domain not allowed"} Your client has a domain allowlist and this request's origin is not on it. Add the origin in Settings, or clear the allowlist.
500 {"error": "Internal server error"} Something broke on our side. Safe to retry.