Publishable vs secret keys
Which key goes in your HTML, which key stays on your server. Test vs live prefixes.
Two flavours of key, four prefixes. Pick the right one for the right context and you'll never accidentally leak a secret in your HTML.
Publishable vs secret
| Type | Prefix | Where it lives | What it can do |
|---|---|---|---|
| Publishable (live) | pk_live_… | Your HTML, in the embed snippet | Fetch widget config, submit a lead |
| Publishable (test) | pk_test_… | Local dev, staging | Same — but use it only outside production |
| Secret (live) | sk_live_… | Your server, in env vars | Read leads, quotes; manage destinations |
| Secret (test) | sk_test_… | Local dev, staging | Same — but on the test environment |
The four prefixes — when each one ships
Innkept generates the prefix based on the environment where you create the key:
- Production environment →
pk_live_/sk_live_ - Anywhere else →
pk_test_/sk_test_
On the hosted Innkept (quote.innkept.com), every key you generate is a live key.
Test keys exist for self-hosted setups and local development.
Creating a key
- Open API keys in the dashboard.
- Click New key.
- Give it a label (e.g. "Squarespace site", "Staging WP", "Server-to-server").
- Optionally add an origin allowlist.
- Save. The publishable key is shown immediately.
Secret keys are shown once. Right after you generate a secret key we display the full string and never again — only a hashed copy is stored. If you lose it, you can't recover it; you have to revoke and create a new one.
Where to put each key
Publishable in your HTML
<script src="https://quote.innkept.com/embed/v1/loader.js"
data-key="pk_live_xxxxxxxxxxxxxxxx"
async></script>
Anyone can view-source on your page and copy this. That's expected — the origin allowlist is what keeps it safe.
Secret on your server
# In your .env or secrets manager
INNKEPT_SECRET_KEY=sk_live_xxxxxxxxxxxxxxxx
# In code (Node example)
fetch('https://api.innkept.com/v1/leads', {
headers: { Authorization: `Bearer ${process.env.INNKEPT_SECRET_KEY}` }
})
Never commit a secret key to git. Never put one in client-side JS. Use environment variables.
Scopes
Publishable keys carry the scopes read_config and submit_quote —
enough to run the widget and create a lead, nothing else. Secret keys carry full scopes for
server-to-server use. Per-key scope tuning is on the roadmap.
Last used at
Each key shows when it was last used. If you see a key that hasn't been hit in months, consider revoking it — it's probably an old test key from a launch.
Something missing or wrong? Tell us.
Updated regularly. UK English. No AI slop.