SDK client
Use the core client from browser or server code. Configure access first; each method returns a promise.
Read feedback and releases
Follow installation and identity before calling the client. Public keys see only the feedback exposed by the public API; a customer token does not unlock internal items.
import { Reflet } from "reflet-sdk";
const reflet = new Reflet({ publicKey: "fb_pub_YOUR_PUBLIC_KEY" });
const page = await reflet.list({
search: "filters",
sortBy: "votes",
limit: 20,
offset: 0,
});
if (page.hasMore) {
const nextPage = await reflet.list({
search: "filters",
sortBy: "votes",
limit: 20,
offset: 20,
});
}List options are search (title and description), status (open, under_review, planned, in_progress, completed, or closed), statusId (custom status), sortBy (votes, newest, oldest, or comments), limit (at most 100), and offset.
Submit and respond
All writes except creation need a server-signed user token. Passing user is not enough. See trusted identity.
import { Reflet } from "reflet-sdk";
export async function respondToFeedback(token: string, feedbackId: string) {
const reflet = new Reflet({
publicKey: "fb_pub_YOUR_PUBLIC_KEY",
userToken: token, // Signed by your authenticated server.
});
const vote = await reflet.vote(feedbackId);
const { commentId } = await reflet.comment({
feedbackId,
body: "This also happens when I return from a bookmarked item.",
});
await reflet.subscribe(feedbackId);
return { vote, commentId };
}Optional creation context can include page information, metadata, selected elements, and console warnings/errors. The core client does not collect these automatically. For a capture UI, use the floating feedback widget. Survey client methods are documented in surveys.
Attach a screenshot
Upload bytes to the one-shot storage URL, then attach the returned storage ID to an existing feedback item. saveScreenshot returns { screenshotId }. Upload and attachment are separate operations; a failed attachment does not mean feedback creation failed.
import { Reflet } from "reflet-sdk";
export async function attachScreenshot(
reflet: Reflet,
feedbackId: string,
image: Blob,
) {
const { uploadUrl } = await reflet.getScreenshotUploadUrl();
const upload = await fetch(uploadUrl, {
method: "POST",
headers: { "Content-Type": image.type },
body: image,
});
if (!upload.ok) {
throw new Error(`Screenshot upload failed (${upload.status})`);
}
const result: unknown = await upload.json();
if (
typeof result !== "object" || result === null ||
!("storageId" in result) || typeof result.storageId !== "string"
) {
throw new Error("Screenshot upload returned no storageId");
}
return await reflet.saveScreenshot({
feedbackId,
storageId: result.storageId,
mimeType: image.type,
size: image.size,
captureSource: "widget",
});
}Other attachment fields are filename, width, height, pageUrl, annotatedStorageId, and annotations. Use captureSource: "element" for a selected-element close-up. The published declarations include the annotation shape. Review and redact images before upload; direct client calls do not apply widget capture protections.
Handle errors
import { Reflet, RefletError } from "reflet-sdk";
const reflet = new Reflet({ publicKey: "fb_pub_YOUR_PUBLIC_KEY" });
try {
await reflet.create({
title: "Keep my filters",
description: "Filters reset after opening an item.",
});
} catch (error) {
if (error instanceof RefletError) {
// status 0 means the network request failed.
// Use status to choose UI copy; message contains the API's explanation.
throw new Error(`Feedback was not sent (${error.status}): ${error.message}`);
}
throw error;
}RefletErrorexposesstatus,message, and optionalcode.- HTTP 401 becomes
RefletAuthError; HTTP 404 becomesRefletNotFoundError. Other HTTP failures, including 400, areRefletError. Do not rely on the exportedRefletValidationErrorfor API validation failures. - Network failures have status 0. Invalid JSON also throws
RefletErrorwith the response status. - 403 can indicate an origin or access restriction. 429 can indicate a rate limit or write quota. Keep the returned message visible and consult the API guide.
- The client has no automatic retry or request cache. Do not blindly repeat creation or comments after an uncertain network failure.