Skip to main content
POST
/
api
/
feedback
Submit Feedback
curl --request POST \
  --url https://api.example.com/api/feedback
{
  "success": true
}

Submit Feedback

Submit feedback about the Umbra platform via email.

Endpoint

POST /api/feedback

Authentication

Requires a valid form token obtained from the /api/form-token endpoint.

Rate Limiting

3 requests per 2 minutes per IP address. Returns 429 Too Many Requests with a Retry-After header when exceeded.

Security Requirements

  • Must be same-origin request (checked via Origin header)
  • Must have Content-Type: application/json
  • Must include valid form token (10-minute expiry)
  • Honeypot field (checkpoint) must be empty

Request Parameters

email
string
required
Email address for follow-up (max 200 characters). Must be a valid email format.
name
string
Name of the person submitting feedback (max 200 characters)
message
string
required
Feedback message (max 2000 characters)
source
string
Source of the feedback (e.g., “chat”, “homepage”, “docs”). Defaults to “unspecified”. Max 140 characters.
form_token
string
required
HMAC-signed form token from /api/form-token

Request Body

{
  "email": "[email protected]",
  "name": "Alice Johnson",
  "message": "The attestation verification process is very smooth. Would love to see support for SEV-SNP in addition to TDX.",
  "source": "chat",
  "form_token": "a1b2c3d4e5f6.1709654400.8f3a2b1c4d5e6f7890123456789abcdef0123456",
  "checkpoint": ""
}

Response

success
boolean
required
Whether the feedback was submitted successfully

Error Responses

400 Bad Request

  • Missing or invalid email
  • Missing or empty message
  • Missing or expired form token
  • Honeypot field not empty

403 Forbidden

  • Cross-origin request blocked

415 Unsupported Media Type

  • Missing or invalid Content-Type header

422 Unprocessable Entity

  • Email format validation failed

429 Too Many Requests

  • Rate limit exceeded (includes Retry-After header with seconds to wait)

500 Internal Server Error

  • Feedback inbox not configured (RESEND_TO_EMAIL_FEEDBACK env var missing)
  • Email delivery failed

Example

# First, get a form token
TOKEN=$(curl https://umbra.concrete-security.com/api/form-token | jq -r '.token')

# Then submit feedback
curl -X POST https://umbra.concrete-security.com/api/feedback \
  -H "Content-Type: application/json" \
  -H "Origin: https://umbra.concrete-security.com" \
  -d "{
    \"email\": \"[email protected]\",
    \"name\": \"Alice Johnson\",
    \"message\": \"Great platform! Love the TEE integration.\",
    \"source\": \"chat\",
    \"form_token\": \"$TOKEN\",
    \"checkpoint\": \"\"
  }"

Success Response

{
  "success": true
}

Error Response

{
  "error": "Feedback cannot be empty."
}

Email Delivery

Feedback is delivered via Resend to the address configured in the RESEND_TO_EMAIL_FEEDBACK environment variable. The email includes:
  • Source of feedback
  • Submitter’s name and email
  • Message content (HTML formatted with proper escaping)
  • Subject line: Umbra beta feedback ({source})
HTML content is escaped to prevent injection attacks using a custom escapeHtml function.

Validation Rules

  • Email: Required, max 200 characters, must match basic email regex (/^[^\s@]+@[^\s@]+\.[^\s@]+$/), converted to lowercase
  • Name: Optional, max 200 characters, trimmed
  • Message: Required, max 2000 characters, trimmed
  • Source: Optional, max 140 characters, defaults to “unspecified”
  • Form Token: Required, must be valid HMAC signature and not expired (10-minute TTL)
  • Checkpoint: Must be empty (honeypot field)

Implementation Details

The endpoint implements multiple security layers:
  • Same-origin enforcement via header validation
  • Rate limiting per IP address (3 req/2min)
  • HMAC-signed form tokens with expiry
  • Honeypot field for bot detection
  • Input sanitization and HTML escaping
  • Email delivery via Resend API
Source: frontend/app/api/feedback/route.ts

Build docs developers (and LLMs) love