Feedback

Let users send free-form feedback (bug reports, suggestions, confusion about a result) along with a screenshot of what they were looking at when they hit "Send feedback". The feedback is delivered by email to the VPT team for triage.

Overview

submitFeedback is intentionally simple in its first iteration:

  • The user types a description of their feedback.
  • Your app captures a PNG screenshot of the current screen and base64-encodes it.
  • You POST both to submitFeedback along with optional context (app version, device, route, etc.).
  • The server emails everything (with the screenshot attached) to the VPT team and returns an opaque FeedbackId the user can quote.
Phase 1 — email-only delivery

The current implementation does not persist feedback to the database. It is delivered by email only. A future phase will add a user_feedback table and an admin dashboard alongside the existing Query Reports dashboard. The request/response shape will not change.

Authentication

submitFeedback uses the same authentication scheme as reportQuery: the user must be logged in, and the request must include their session credential as api_key in the body. The dev_key is also required at the gateway.

Screenshot attached
The PNG ships as an email attachment so triage happens directly from the inbox.
Optional log linkage
Pass an X-VPT-Log-Id as logId to connect the feedback to a specific previous API call.
Strict size limits
Description capped at 4 000 chars, screenshot at 2 MB decoded. Oversized payloads are rejected with a clear error.

submitFeedback

Submit user feedback with an attached screenshot. Delivered by email; no DB row is created in Phase 1.

POST /api

Headers

Header Required Description
Content-Type Required application/json

Request Body

JSON
{
  "query":   "submitFeedback",
  "dev_key": "your_developer_key",
  "api_key": "user_session_api_key",
  "data": {
    "description":      "After computing takeoff for LFPG 27R the V1 displayed seems too low.",
    "screenshotPng":    "iVBORw0KGgoAAAANSUhEUgAA...",   // base64-encoded PNG
    "appVersion":       "1.4.2 (build 312)",
    "serverApiVersion": "1.3.6",
    "deviceOs":         "iOS 17.5",
    "deviceModel":      "iPhone 14 Pro",
    "route":            "TakeoffResults",
    "logId":            12345,
    "extras": {
      "lastCalcId": "calc_98aa12"
    }
  }
}

Parameters

Parameter Type Required Description
query string Required Must be "submitFeedback"
dev_key string Required Your developer key
api_key string Required The authenticated user's session api_key
data object
description string Required The user's feedback text (max 4 000 characters)
screenshotPng string Required Base64-encoded PNG of the current screen. A data:image/png;base64, prefix is accepted and stripped automatically. Decoded payload max 2 MB.
appVersion string Optional Your client app version string
serverApiVersion string Optional The VPT API version your app is targeting
deviceOs string Optional e.g. iOS 17.5, Android 14
deviceModel string Optional Device or browser model identifier
route string Optional The screen / route the user was on when submitting
logId integer Optional An X-VPT-Log-Id from a previous response this feedback relates to
extras object Optional Free-form key/value pairs reserved for future custom feedback forms. Included verbatim in the email body.

Success Response

200 OK
{
  "Success":    true,
  "FeedbackId": "fb-9f3a17b2c4d8"
}

FeedbackId is an opaque short reference (no database row is created in Phase 1). Show it to the user as a quotable reference.

Error Responses

Condition Error message
Missing or invalid api_key Authentication required to submit feedback.
description empty Description is required.
screenshotPng empty Screenshot (screenshotPng) is required.
screenshotPng not valid base64 Screenshot is not valid base64.
Decoded screenshot > 2 MB Screenshot too large (max 2 MB decoded).
Decoded payload not a PNG Screenshot must be a valid PNG image.
More than 5 submissions in the past hour Rate limit exceeded. Please wait before submitting more feedback.

Full Example

JavaScript
// 1. Capture a PNG screenshot of the current screen.
//    (Use html2canvas in browsers, or your platform's screenshot API.)
const canvas = await html2canvas(document.body);
const screenshotPng = canvas.toDataURL('image/png').split(',')[1]; // strip prefix

// 2. Submit feedback.
const response = await fetch('https://api.virtualperformancetool.com/', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    query:   'submitFeedback',
    dev_key: 'your_developer_key',
    api_key: currentUserApiKey,
    data: {
      description:      userFeedbackText,
      screenshotPng,
      appVersion:       app.version,
      serverApiVersion: '1.3.6',
      deviceOs:         platform.os,
      deviceModel:      platform.device,
      route:            currentRoute,
      logId:            lastResponseLogId   // optional
    }
  })
});

const result = await response.json();
if (result.Success) {
  showToUser(`Thanks! Feedback submitted (ref ${result.FeedbackId}).`);
} else {
  showError(result.Error?.[0]?.Message ?? 'Unable to send feedback.');
}

Limits & Rate Limiting

Limit Value
Description length 4 000 characters (truncated if longer)
Screenshot decoded size 2 MB
Total request payload ~3 MB recommended
Submissions per user 5 per hour

Keep the screenshot lean: scale to the device's logical resolution and prefer PNG-8 or compressed PNG. A typical phone screenshot is well under 500 KB.

Privacy

  • The user's api_key is consumed for authentication only and is never included in the email body.
  • The screenshot is sent as an email attachment to the VPT team and retained as long as the email is retained.
  • Make it explicit in your client UI that submitting feedback attaches a screenshot of the current screen, so users can avoid sending sensitive content.
  • Feedback submissions are also logged in api_query_logs like any other API call (subject to the standard 3-day retention plus auto-redaction of api_key, dev_key, password and token-named fields).

Integration Tips

Suggested UX pattern
  1. Surface a "Send feedback" entry point in a stable place (settings, help menu, or a long-press on the app's logo).
  2. When tapped, immediately capture a PNG screenshot of the current screen before presenting the feedback sheet (otherwise you'll just capture the sheet itself).
  3. Show a sheet with:
    • A thumbnail preview of the captured screenshot.
    • A multi-line text field for the description (placeholder: "What's wrong, or what would you improve?").
    • A clear note: "Your screenshot will be attached."
  4. On submit, POST submitFeedback and store the returned FeedbackId.
  5. Always pass appVersion, deviceOs, deviceModel and the current route — these context fields drastically reduce triage time.
User must be logged in

The feedback button should only be visible when a user is authenticated, as the endpoint requires a valid api_key. For anonymous contexts, link to the support page instead.