Public endpoints
No session required. Used by the embed widget and the public portal. Enforce project key + domain allowlist on mutating routes.
GET/v1/widget/:pk/config
publicReturns public widget config (greeting, mascot, capture flags). Cacheable — Cache-Control: public, max-age=60, stale-while-revalidate=300. Optional KV HIT/MISS via X-OpenRoadmap-Cache.
POST/v1/feedback
publicPersist a submission. Returns 201 fast; ack email is async.
{
"projectKey": "pk_demo_acme_website",
"message": "Add dark mode",
"type": "feature",
"email": "optional@example.com",
"visitorId": "anon_abc123",
"honeypot": "",
"context": { "url": "https://app.example.com/reports" },
"identified": { "id": "usr_1", "plan": "pro" }
}Tip
Non-empty honeypot returns a fake success and drops the payload (bot trap).
POST/v1/votes
public{
"projectKey": "pk_demo_acme_website",
"featureId": "<uuid>",
"visitorId": "anon_abc123",
"email": "optional@example.com"
}POST/v1/subscriptions
publicFollow a feature for status-change emails.
{
"projectKey": "pk_demo_acme_website",
"featureId": "<uuid>",
"email": "you@example.com"
}GET/v1/public/:orgSlug/roadmap
publicBuckets: now, next, later, shipped plus project meta.
GET/v1/public/:orgSlug/features
publicOptional ?q= search across title/summary.
GET/v1/public/:orgSlug/features/:slug
publicFeature detail + linked submission excerpts for the portal page.
GET/v1/demo/meta
publicDemo helpers: public key, org slug, demo login email.