# Feedback widget & API

> Issue and manage keys for the feedback widget and the Feedback API: pk_live_* publishable keys for browsers, sk_live_* secret keys for servers.

Source: https://productos.ca/documentation/pages/settings/widget-keys (last reviewed 2026-09-22)

The **Widget & API** section (Settings → Integrations & Data → Widget & API) is where admins and owners issue the keys that let your product send feedback into ProductOS: through the [embeddable feedback widget](https://productos.ca/documentation/api/v1/widget), or with your own code through the [Feedback API](https://productos.ca/documentation/api/v1/feedback-api).

## What you'll see

- **Install snippet**: the widget's script tag, pre-filled with your first active publishable key's prefix.
- **Publishable keys**: name, displayable prefix (`pk_live_xxxx…`), allowed origins, last used, revoked flag, and **New key**.
- **Attribution**: whether the widget footer's "Powered by ProductOS" link is shown.
- **Feedback API**: a starter request and the **Secret keys** list (name, prefix `sk_live_xxxx…`, last used), with **New secret key**.

Active keys are listed first; revoked keys stay below them for history.

## Two kinds of key

| | Publishable (`pk_live_`) | Secret (`sk_live_`) |
| :--- | :--- | :--- |
| Used by | The widget, and browser code calling the Feedback API | Your servers calling the Feedback API |
| Safe in customer-facing code | Yes | No |
| Origin allowlist | Required | None; requests with an `Origin` header are refused |
| Can submit | Yes | Yes |
| Submissions linked to accounts automatically | No | Yes |
| Can read submissions back and list a person's submissions | No | Yes, for Feedback API submissions only |

Neither kind can read anything else in the workspace. For general API access, use an [API token](https://productos.ca/documentation/api/v1/authentication).

## Issuing

- **Name**: what the key is for (e.g. "Marketing site", "Production backend"). One key per app or environment makes rotation painless.
- **Allowed origins** (publishable keys only): a comma-separated host list. Supported shapes:
  - Host with port (`localhost:3000`): that port only
  - Host only (`example.com`): any port
  - Wildcard subdomain (`*.vercel.app`): any subdomain
  - `*`: any origin (mostly for local development)

The full key shows **exactly once** on creation. Copy it immediately; only a hash and a short display prefix are stored. Put secret keys in your server's secret manager, never in browser or mobile app code.

## Origin enforcement

For publishable keys, the widget endpoint and the Feedback API check the request's `Origin` (or `Referer` if `Origin` is missing) against the key's allowed origins. A mismatch returns `403 forbidden` with the rejected host echoed back for debugging. Edit a publishable key's origins with the pencil icon; secret keys have none to edit.

## Rotating

Issue a new key, deploy it (update the embed snippet or your server's secret), then revoke the old one. There is no grace period: once revoked, a key returns `401` on its next request.

## Related

- [Feedback API](https://productos.ca/documentation/api/v1/feedback-api): submitting feedback and NPS scores from your own code
- [Public feedback widget](https://productos.ca/documentation/api/v1/widget): embedding the script
- [Authentication](https://productos.ca/documentation/api/v1/authentication): API tokens (`pos_live_*`) for everything else
