Skip to main content

Overview

This endpoint submits quality feedback (good or bad) for a chat response. Use feedback to help Uppzy improve answer quality over time and to track which questions are being answered well. Feedback can only be submitted for completed requests. The feedback rating is stored and can be viewed in the dashboard analytics.

Authentication

Requires API key in the X-API-Key header:
X-API-Key: <YOUR_API_KEY>

Request body

session_id
string
required
The session ID from the original chat request.
request_id
string
required
The request ID from the chat response. Used to identify which specific Q&A pair the feedback applies to.
feedback
string
required
The feedback rating. One of: good, bad.
  • good: The answer was helpful and accurate.
  • bad: The answer was incomplete, inaccurate, or irrelevant.

Request example

curl --request POST \
  --url "https://api.uppzy.com/api/v1/m2m/sites/<SITE_ID>/chat/feedback" \
  --header "X-API-Key: <YOUR_API_KEY>" \
  --header "Content-Type: application/json" \
  --data '{
    "session_id": "user-123-web",
    "request_id": "req_550e8400e29b41d4a716446655440000",
    "feedback": "good"
  }'

Response schema

status
string
Always ok on success.
request_id
string
The request ID for which feedback was submitted.
feedback
string
The feedback value submitted (good or bad).
feedback_submitted_at
string (ISO 8601 timestamp)
The timestamp when the feedback was recorded. Omitted if feedback was already submitted for this request.

Response example

{
  "status": "ok",
  "request_id": "req_550e8400e29b41d4a716446655440000",
  "feedback": "good",
  "feedback_submitted_at": "2024-06-13T14:32:45Z"
}

Error responses

400 Bad Request

Missing or invalid fields.
{
  "error": "feedback must be 'good' or 'bad'"
}
Common causes:
  • Missing session_id, request_id, or feedback
  • Invalid UUID format for IDs
  • Feedback value not good or bad

401 Unauthorized

API key is missing, invalid, expired, or revoked.
{
  "error": "invalid_api_key"
}

403 Forbidden

The API key’s plan does not include M2M API access.
{
  "error": "api_access_not_available_on_plan"
}

404 Not Found

The request does not exist or does not belong to the site.
{
  "error": "request not found"
}

409 Conflict

The request has not been completed yet (still pending or failed).
{
  "error": "feedback can only be submitted for completed responses"
}

500 Internal Server Error

An unexpected error occurred.

Implementation tips

When to collect feedback

Collect feedback after the user has had time to read and evaluate the answer:
  1. Chat UI pattern: Show thumbs up/down buttons below each answer
  2. Batch pattern: Collect feedback periodically (e.g., after 5 responses)
  3. Queue pattern: Submit feedback asynchronously after the user rates

Feedback collection in a chat interface

async function submitFeedback(siteId, sessionId, requestId, isSatisfied) {
  const feedback = isSatisfied ? "good" : "bad";

  try {
    const response = await fetch(
      `https://api.uppzy.com/api/v1/m2m/sites/${siteId}/chat/feedback`,
      {
        method: "POST",
        headers: {
          "X-API-Key": process.env.UPPZY_API_KEY,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          session_id: sessionId,
          request_id: requestId,
          feedback,
        }),
      }
    );

    if (!response.ok) {
      console.error(`Feedback submission failed: ${response.status}`);
      return;
    }

    const data = await response.json();
    console.log(
      `Feedback recorded at ${data.feedback_submitted_at}`
    );
  } catch (err) {
    console.error(`Error submitting feedback: ${err}`);
  }
}

// Usage: when user clicks thumbs up
submitFeedback(siteId, sessionId, requestId, true);

// Usage: when user clicks thumbs down
submitFeedback(siteId, sessionId, requestId, false);

Idempotency

Submitting the same feedback twice returns the original submission time:
// First submission
await submitFeedback(siteId, sessionId, requestId, "good");
// Returns: { status: "ok", feedback_submitted_at: "2024-06-13T14:32:45Z" }

// Second submission of the same feedback
await submitFeedback(siteId, sessionId, requestId, "good");
// Returns: { status: "ok", feedback_submitted_at: "2024-06-13T14:32:45Z" }
// (same timestamp as first)
However, changing feedback from good to bad (or vice versa) updates it:
// First: submit "good"
await submitFeedback(siteId, sessionId, requestId, "good");
// feedback_submitted_at: "2024-06-13T14:32:45Z"

// Later: change to "bad"
await submitFeedback(siteId, sessionId, requestId, "bad");
// feedback_submitted_at: "2024-06-13T14:35:12Z" (updated)

Tracking feedback for analytics

Store feedback in your application to track quality trends:
-- Track feedback by day
SELECT
  DATE(submitted_at) as date,
  COUNT(*) as total_responses,
  SUM(CASE WHEN feedback = 'good' THEN 1 ELSE 0 END) as good_count,
  ROUND(
    100.0 * SUM(CASE WHEN feedback = 'good' THEN 1 ELSE 0 END) / COUNT(*),
    2
  ) as satisfaction_rate
FROM feedback_logs
GROUP BY DATE(submitted_at)
ORDER BY date DESC;

Error handling and retries

Feedback submission is non-critical; if it fails, log it but don’t block the user:
async function submitFeedbackSafely(siteId, sessionId, requestId, feedback) {
  try {
    const response = await fetch(
      `https://api.uppzy.com/api/v1/m2m/sites/${siteId}/chat/feedback`,
      {
        method: "POST",
        headers: {
          "X-API-Key": process.env.UPPZY_API_KEY,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          session_id: sessionId,
          request_id: requestId,
          feedback,
        }),
        timeout: 5000, // Short timeout
      }
    );

    if (!response.ok) {
      // Log but don't throw
      console.warn(
        `Feedback submission failed (${response.status}), continuing...`
      );
    }
  } catch (err) {
    // Network or timeout error, log and continue
    console.warn(`Feedback submission error (${err.message}), continuing...`);
  }
}

Dashboard integration

Feedback is visible in the Uppzy dashboard:
  • Go to AnalyticsFeedback to see satisfaction rates over time
  • Filter by date range, question topic, or confidence level
  • Use low-satisfaction answers to prioritize document improvements