Send your key in the Authorization header on every request:
Authorization: Bearer uc_live_…| Key type | Prefix | Where it works | Safe to expose? |
|---|---|---|---|
| Secret (live) | uc_live_ | Everything in your live workspace, limited by scopes | No |
| Secret (test) | uc_test_ | Everything in your test workspace (section 12), limited by scopes | No |
| Publishable | uc_pub_ | Only POST /v1/collect from the browser snippet, from allow-listed origins | Yes |
Scopes. A secret key only does what its scopes allow: links:read, links:write, qr:read, qr:write, pages:read, pages:write, insights:read, domains:read, domains:write, webhooks:read, webhooks:write, workspace:read, members:write, billing:read, and on Business+ conversions:read, conversions:write, pixels:read, pixels:write. A missing scope returns 403 insufficient_scope and names the scope you need in error.param.
One key, one workspace. A key is bound to the workspace it was created in. You never pass a workspace id.
Rotating. In the dashboard (or POST /v1/api-keys/{id}/rotate) you get a new secret while the old one keeps working for 24 hours, so you can deploy without downtime. Revoking is immediate.
Security tips
- Keep secret keys in environment variables or a secrets manager; never in client-side code, repos or support tickets.
- Create one key per integration with the smallest scope set, and set
expires_aton CI keys. - Only publishable keys (
uc_pub_) belong in HTML, and only with your real origins on the allow list. - Watch
last_used_atin Settings → API keys and delete keys you no longer recognise.
Email verification. Until the email on an account is verified it cannot create anything — links, QR codes, pages, domains or API keys. The API answers 403 email_verification_required; verify the email in the dashboard and retry.