Loop
Sign inGet started
API reference

Feedback API

Reference for the Loop Feedback API: create items with POST /v2/feedback and list or filter with GET /v2/feedback, with request and response examples.

Overview

The Feedback API is the core of Loop. It exposes two endpoints: one to create a feedback item and one to list and filter items. All requests use the base URL https://api.loop.dev/v2 and a bearer API key. Responses are JSON.

POST https://api.loop.dev/v2/feedback   # create a feedback item
GET  https://api.loop.dev/v2/feedback   # list and filter items

Create feedback

POST /v2/feedback stores a single feedback item and returns it with a server-assigned id, status, and createdAt.

Parameters

Parameter Type Required Description
user.id string Yes Your stable identifier for the end user
message string Yes The feedback text
sentiment enum No positive, neutral, or negative
source string No Origin of the feedback, e.g. in-app-widget
tag string No Optional label used for triage and routing

Request

curl https://api.loop.dev/v2/feedback \
  -H "Authorization: Bearer $LOOP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "user": { "id": "u_8f2c" },
    "message": "The CSV export timed out on large datasets.",
    "sentiment": "negative",
    "source": "in-app-widget",
    "tag": "exports"
  }'

The same call through each SDK:

const item = await loop.feedback.create({
  user: { id: 'u_8f2c' },
  message: 'The CSV export timed out on large datasets.',
  sentiment: 'negative',
  source: 'in-app-widget',
  tag: 'exports',
});
item = loop.feedback.create(
    user={'id': 'u_8f2c'},
    message='The CSV export timed out on large datasets.',
    sentiment='negative',
    tag='exports',
)
item, err := client.Feedback.Create(ctx, &loop.Feedback{
    User:      loop.User{ID: "u_8f2c"},
    Message:   "The CSV export timed out on large datasets.",
    Sentiment: loop.Negative,
    Tag:       "exports",
})

Response

{
  "id": "fb_3a91",
  "user": { "id": "u_8f2c" },
  "message": "The CSV export timed out on large datasets.",
  "sentiment": "negative",
  "source": "in-app-widget",
  "tag": "exports",
  "status": "open",
  "createdAt": "2026-06-19T14:02:11Z"
}

New items always start with status: "open". A feedback.created webhook fires on success — see Webhooks.

List feedback

GET /v2/feedback returns a paginated list of items, most recent first. Use query parameters to filter.

Query parameters

Parameter Type Description
status enum Filter by open or resolved
sentiment enum Filter by positive, neutral, or negative
tag string Filter by a specific tag
limit integer Items per page (default 20, max 100)
cursor string Pagination cursor from a previous response

Request

Fetch open, negative feedback:

curl "https://api.loop.dev/v2/feedback?status=open&sentiment=negative&limit=2" \
  -H "Authorization: Bearer $LOOP_API_KEY"
const { data, nextCursor } = await loop.feedback.list({
  status: 'open',
  sentiment: 'negative',
  limit: 2,
});
result = loop.feedback.list(status='open', sentiment='negative', limit=2)
result, err := client.Feedback.List(ctx, &loop.ListParams{
    Status:    loop.Open,
    Sentiment: loop.Negative,
    Limit:     2,
})

Response

{
  "data": [
    {
      "id": "fb_3a91",
      "user": { "id": "u_8f2c" },
      "message": "The CSV export timed out on large datasets.",
      "sentiment": "negative",
      "source": "in-app-widget",
      "tag": "exports",
      "status": "open",
      "createdAt": "2026-06-19T14:02:11Z"
    }
  ],
  "nextCursor": "c_9d12",
  "hasMore": true
}

Pagination

When hasMore is true, pass nextCursor as the cursor parameter on the next request to fetch the following page. Continue until hasMore is false.

Errors

The API uses standard HTTP status codes:

Status Meaning
400 Validation error — a required field is missing/invalid
401 Invalid or missing API key
429 Rate limited or monthly item quota exceeded
500 Unexpected server error — safe to retry

Error bodies follow a consistent shape with error.type and error.message. Continue to Webhooks to act on new feedback in real time.

← PREVIOUS
Authentication
NEXT →
Webhooks