Happy House - Ecommerce Docs
Developer ResourcesFeedback

Feedback Mobile API Reference

Integration reference for mobile feedback endpoints.

Feedback Mobile API Reference

Audience: Mobile/frontend developers Scope: Mobile feedback contracts currently implemented.


Mobile APIs

Submit Feedback

Endpoint

POST /api/mobile/feedback

Auth

  • Authorization: Bearer <user-jwt>

Request body

{
	"category": "feature_request",
	"subject": "Please add dark mode",
	"message": "Dark mode would make the app easier to use at night."
}

Feedback categories:

  • bug_report
  • feature_request
  • general_feedback

Important behavior:

  • feedback is one-way in v1
  • mobile users do not have list/detail endpoints for previous feedback submissions

Submit Feedback — Public (Guest)

Endpoint

POST /api/mobile/feedback/public

Auth

  • @Public() — none. This is a separate route from POST /api/mobile/feedback, not the same route with auth relaxed, because the two take different bodies. Letting a signed-in customer post the guest body would let them attribute a message to somebody else's name/email.

Rate limit

  • PUBLIC_CONTACT_GUEST — 5 requests / hour, keyed on ip+device (apps/api/src/common/guards/ip-throttler.config.ts). Rejected requests still consume quota — the throttle guard runs before DTO validation.

Request body

{
  "name": "Sita Sharma",
  "email": "sita@example.com",
  "phone": "+977 98XXXXXXXX",
  "category": "general_feedback",
  "subject": "Question about warranty",
  "message": "Is the Marshall Acton III covered by a local warranty?",
  "companyWebsite": ""
}
FieldRequiredNotes
nameYes1-120 chars, trimmed
emailYesmax 255, @IsEmail()
phoneNomax 40
categoryYesbug_report | feature_request | general_feedback
subjectYes1-255 chars — the authenticated endpoint's DTO does not require this field, the guest one does
messageYes1-5000 chars
companyWebsiteNohoneypot. Render hidden, leave empty, never autofill. forbidNonWhitelisted: true means any other undeclared field 400s.

Response — always identical, regardless of outcome

{ "message": "Message received. We will get back to you shortly.", "data": { "status": "received" } }

The response carries no id and no echo of the sender. It is the same whether the message was stored, or discarded because the honeypot was filled — so a bot learns nothing from the response, and the endpoint cannot be used to test whether an email address belongs to an existing account.

Honeypot behavior: a non-empty companyWebsite causes the submission to be logged at warn and not persisted — no row is written to feedback_submissions — but the caller still receives the normal 200 acknowledgement above.

Both routes notify the shop. An accepted submission writes a feedback.submitted outbox row in the same transaction as the insert, targeting NOTIFICATIONS / notification.send_email. It does two jobs from one row: an internal notice reaches the shop's own inbox, and the dispatcher's relay raises a live admin notification (Feedback_READ) — the feed is a side-effect of dispatch, so an event with no job to dispatch cannot reach the stream.

The destination is fixed configuration — SUPPORT_EMAIL — never the address in the request. That is what makes it safe on an unauthenticated route. An acknowledgement posted back to whatever address a form carried would turn this endpoint into an outbound-email amplifier: anyone could make the API mail a third party by typing their address into the contact form.

The honeypot path is upstream of all of it. A discarded submission opens no transaction, writes no row and queues nothing, so a bot filling every field cannot make the endpoint send anything at all.

Errors

HTTPCondition
400validation failure — missing/invalid email, blank message, or an undeclared field
429over 5 requests/hour for this IP+device pair

Not to be confused with POST /api/mobile/feedback above — that route still requires a bearer token and takes a different body (no name/email/phone; the account is the identity).

Common Error Scenarios

  • 400: invalid numeric path param
  • 401: missing or invalid JWT
  • 422: invalid category/body validation