Project Settings: Origins, Environments & Bug reports

This document answers four critical administrative questions: “How do I stop comments arriving from somewhere I don’t control?”, “Where do I tell PinSay my app lives?”, “What may a bug report carry from my app?” and “How do I claim feedback visitors left on my site before it was in PinSay?”

Part 1: Restrict where comments can come from

By default, a PinSay project accepts comments from any web page where its widget snippet is embedded. If you deploy a staging or production build, anyone with access to that web page can leave comments.

In your project settings, the toggle “Only accept comments from the configured app URLs” enables strict origin enforcement.

How origin enforcement works

Origin enforcement is opt-in per project (disabled by default). When you enable it, PinSay verifies the HTTP Origin header (or Referer header) of every incoming comment or reply against your configured environment URLs.

The footgun: Enabling enforcement with no URLs

Enabling origin enforcement when no app URLs are configured will block all browser traffic. Because web browsers always send an Origin header on cross-origin POST requests, if your project has no matching URLs, every submission will be rejected. Always add at least one application URL before toggling enforcement on.

Allowed exceptions & special cases

When origin enforcement is enabled, the following exceptions are evaluated:

  • Localhost exemption for Local comments: When a comment is tagged with the Local environment, origins running on localhost (e.g. http://localhost:5173, http://127.0.0.1:3000, http://[::1]:4200) are always allowed. Developers running local servers do not need to register transient development ports in project settings.
  • PinSay dashboard exemption: The PinSay web dashboard's own origin is always allowed, ensuring your team can reply to comments directly from the web dashboard regardless of where the app is hosted.
  • Requests without an Origin header (CLI & AI tools): Automation tools, local CLI scripts, and AI coding agents make direct API calls with an API key and do not send browser Origin headers. These requests are permitted for staff accounts (owners, developers, and administrators) but strictly rejected for client / quick-access accounts, which are only authorized to interact through approved web browsers.

Wildcard URL patterns for preview deployments

Teams using ephemeral preview environments (such as pull request deployments on Vercel, Netlify, or Cloudflare Pages) can configure wildcard URL patterns instead of manually adding every branch URL.

PinSay enforces strict safety constraints on wildcard patterns:

  • At most one asterisk: A pattern may contain at most one * character.
  • Leftmost host label only: The wildcard must reside in the leftmost label of the hostname (e.g. https://myapp-*.vercel.app or https://*.staging.example.com). Wildcards in paths, ports, or higher-level domain labels are rejected.
  • Mandatory literal prefixes on shared hosts: On public multi-tenant platforms where any third party can register a subdomain (e.g. vercel.app, netlify.app, pages.dev, github.io, web.app, firebaseapp.com, herokuapp.com, railway.app, fly.dev, onrender.com, azurewebsites.net, etc.), bare wildcards like https://*.vercel.app are strictly forbidden. You must include a literal prefix scoped to your organization, such as https://myapp-*.vercel.app. This prevents unrelated projects on that platform from injecting feedback into your queue.
  • Minimum label requirements: On private domains, a bare wildcard requires at least three labels (e.g. https://*.staging.example.com is allowed, but https://*.example.com requires a literal prefix).

What commenters see when blocked

If a browser request arrives from an unauthorized origin while enforcement is enabled, the API immediately responds with HTTP 403 Forbidden and the message:

"Comments are not allowed from this address."

The embedded widget displays an error toast informing the user that the comment could not be saved.

Comment rate limiting

To safeguard against abuse and automated spam, PinSay enforces a sliding-window rate limit on comment creation and replies:

  • Limit: 30 comments/replies per 60-second sliding window per authenticated user.
  • Response when exceeded: HTTP 429 Too Many Requests with a standard Retry-After header specifying the back-off duration in seconds.

Part 2: Workspace environments & project URLs

PinSay organizes application endpoints through workspace environments.

Important distinction: Workspace environments vs comment tags

A workspace environment (such as local, staging, or production) defines where your application runs and maps allowed URLs. This is not the same as the "Local / Staging / Production" tag selected on an individual comment pin. The comment tag is a categorization label indicating where an observer found an issue; workspace environments define the operational targets in your workspace.

Enabling and managing environments

Workspace administrators manage environments from Settings → Environments in the dashboard:

  • Enabled toggle: Administrators can enable or disable specific environments. When an environment is disabled, it cannot be selected when adding new application URLs.
  • Disabling an environment does not break live widgets: Disabling an environment in the dashboard removes the URL mapping from active lists, but does not take a live widget offline. The widget treats an origin with a disabled environment as unmapped (allowed) rather than explicitly deactivated. Only setting an individual URL mapping's toggle to Inactive (IsActive = false) takes a widget offline.

Assigning a URL per environment

In your Project Settings, you can assign exactly one URL per enabled environment:

Environment Example URL Usage
local http://localhost:5173 Local developer workstation and test servers.
staging https://staging.example.com Shared internal test environment or QA review deployment.
production https://example.com Live customer-facing application.

Retirement of the legacy "default" environment

Earlier releases of PinSay used a generic environment named default. This has been officially retired across all services in favor of local.

The default environment is disabled and hidden from the environment picker, but any URLs already assigned to it keep working exactly as before — they are not moved. To bring one under local, re-save that URL against the local environment in Project Settings.

Not yet available

Multiple URLs for the same environment within a single project, or path-based URL routing (e.g. https://example.com/app1 and https://example.com/app2 as separate environments), are not currently supported. Each project defines at most one URL per environment.

Part 3: Bug reports

Three settings in the project's settings decide what a comment marked as a bug carries. Only workspace admins can change them.

  • Bug capture — attaches the network calls, console errors and the person's steps from the seconds before the comment. Off by default.
  • Request and response content — also keeps JSON and text bodies (up to 4,000 characters each) and query strings, with secrets replaced by [REDACTED] in the browser and again on the server. Off by default; only available while bug capture is on.
  • Excluded addresses — one pattern per line. Calls whose address matches are recorded without headers, query values or content. * matches anything; a pattern that starts with / matches the path, any other pattern the host (with its port) and path. Examples: /api/auth/*, payments.example.com/*.

The report appears on the comment in the dashboard (Network / Console) and in the prompt @pinsay/cli apply gives your AI agent, where failing calls come with their content.

Part 4: Verify your domain and claim earlier visitor feedback

People with the PinSay browser extension can leave feedback on any site, even one that is not in PinSay yet. That feedback is kept apart from every workspace. Once you prove you own the domain, you can claim it into your project's Visitor feedback inbox.

Verify the domain

Open the project's settings and choose the Domains tab (workspace admins only). It lists the domain of every App URL from the Environments tab; app.example.com and www.example.com both count as example.com, so one verification covers every subdomain. Choose Verify domain and publish the value it shows with one of these methods:

  • DNS TXT record (recommended) — host _pinsay-verification, type TXT, value pinsay-verify=<token>. DNS changes can take a while to appear.
  • HTML <meta> tag — <meta name="pinsay-verification" content="<token>"> inside the <head> of your home page at https://<domain>/.
  • /.well-known file — a plain text file at https://<domain>/.well-known/pinsay-verification.txt that contains only the token.

Then choose Check verification now. PinSay tries the tag, then the file, then DNS, and stops at the first match. The token is valid for 72 hours (asking again renews it); a verified domain stays verified for a year after its last successful check. A domain can be verified by one workspace at a time.

Claim the feedback

When feedback is waiting on one of the project's domains, a banner at the top of Visitor feedback says how many comments there are. Admins verify the domain from there or, once it is verified, choose Claim. Claimed comments arrive as Pending review with their original date, page, element and screenshot, and keep the Visitor label; comments left without an email carry the Anonymous badge.

How many earlier comments a workspace can claim per domain is part of its plan, and claimed comments count toward the monthly visitor comment and storage allowances. When a limit is reached, the newest comments are claimed and the rest stay reserved until the allowance grows. Unclaimed feedback is deleted after a retention period (90 days by default).