Skip to main content
POST
/
api
/
waitlist
Waitlist Signup
curl --request POST \
  --url https://api.example.com/api/waitlist
{
  "success": true
}

Waitlist Signup

Submit a waitlist request to join the Umbra beta program.

Endpoint

POST /api/waitlist

Authentication

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

Rate Limiting

5 requests per minute 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 (max 160 characters). Must be a valid email format.
company
string
Company name (max 160 characters)
use_case
string
Description of intended use case (max 320 characters)
metadata
object
Additional metadata as key-value pairs (max 12 entries)
form_token
string
required
HMAC-signed form token from /api/form-token

Request Body

{
  "email": "[email protected]",
  "company": "Acme Corp",
  "use_case": "Processing sensitive medical data in TEEs",
  "metadata": {
    "source": "homepage",
    "referrer": "search"
  },
  "form_token": "a1b2c3d4e5f6.1709654400.8f3a2b1c4d5e6f7890123456789abcdef0123456",
  "checkpoint": ""
}

Response

success
boolean
required
Whether the signup was successful

Error Responses

400 Bad Request

  • Missing or invalid email
  • 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

  • Database error
  • Unexpected server error

Example

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

# Then submit the waitlist request
curl -X POST https://umbra.concrete-security.com/api/waitlist \
  -H "Content-Type: application/json" \
  -H "Origin: https://umbra.concrete-security.com" \
  -d "{
    \"email\": \"[email protected]\",
    \"company\": \"Acme Corp\",
    \"use_case\": \"Processing sensitive medical data\",
    \"form_token\": \"$TOKEN\",
    \"checkpoint\": \"\"
  }"

Success Response

{
  "success": true
}

Error Response

{
  "error": "Email is required"
}

Data Handling

Waitlist requests are stored in Supabase with upsert behavior using email as the conflict key. Submitting the same email multiple times will update the existing record.

Validation Rules

  • Email: Required, max 160 characters, must match basic email regex (/^[^\s@]+@[^\s@]+\.[^\s@]+$/), converted to lowercase
  • Company: Optional, max 160 characters, trimmed
  • Use Case: Optional, max 320 characters, trimmed
  • Metadata: Optional object with max 12 string key-value pairs, empty values filtered out
  • 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 (5 req/min)
  • HMAC-signed form tokens with expiry
  • Honeypot field for bot detection
  • Input sanitization and validation
  • Supabase Row-Level Security (RLS) policies
Source: frontend/app/api/waitlist/route.ts

Build docs developers (and LLMs) love