Feedback Service
Collect product feedback from signed-in users and let admins reply inside Downcity.
FeedbackService adds a simple feedback inbox to a federation. Signed-in users can submit feedback for the current city, admins can review and reply, and users can later read the official reply through the API.
Register
import { Federation } from "@downcity/city";
import { FeedbackService } from "@downcity/services";
const fed = new Federation({ db });
fed.use(new FeedbackService());The service stores feedback in Downcity's database. It does not send email, Slack messages, webhooks, or push notifications.
User APIs
Submit feedback with a user token:
curl http://127.0.0.1:43127/v1/feedback/send \
-H "Authorization: Bearer ub_xxx" \
-H "Content-Type: application/json" \
-d '{
"message": "Image generation often stays queued",
"contact": "[email protected]",
"meta": {
"page": "/billing",
"client_version": "1.2.3"
}
}'Response:
{
"feedback_id": "fb_xxx",
"status": "open",
"created_at": "2026-06-30T10:00:00.000Z"
}Read the current user's feedback for the current city:
curl "http://127.0.0.1:43127/v1/feedback/me?status=replied&limit=50" \
-H "Authorization: Bearer ub_xxx"The response includes the original message, current status, admin reply, reply author, and reply timestamp.
Admin APIs
List feedback:
curl "http://127.0.0.1:43127/v1/feedback/messages?status=open&limit=100" \
-H "Authorization: Bearer sk_admin_xxx"Optional filters are city_id, user_id, status, and limit.
Reply to feedback:
curl http://127.0.0.1:43127/v1/feedback/reply \
-H "Authorization: Bearer sk_admin_xxx" \
-H "Content-Type: application/json" \
-d '{
"feedback_id": "fb_xxx",
"reply": "We fixed the async result parser.",
"reply_by": "support"
}'Update status:
curl http://127.0.0.1:43127/v1/feedback/status \
-H "Authorization: Bearer sk_admin_xxx" \
-H "Content-Type: application/json" \
-d '{
"feedback_id": "fb_xxx",
"status": "closed"
}'Supported statuses are open, reviewing, replied, and closed.