API keys & encryption
Two different kinds of secret meet in Promptly, and it's worth separating them before anything else:
- Your Promptly API key — identifies your workspace to Promptly. It travels in your website's page source, because the widget needs it.
- The secrets Promptly holds for you — your AI provider key, catalog integration credentials, database connection strings. These never leave the server, and they are encrypted at rest.
The first half of this page covers the key you hand out. The second covers the secrets you hand over.
Your API key
Every key looks like pk_ followed by a long random string — for example pk_8sJd…. It is 256 bits of cryptographic randomness, which means the token is the secret: there's no matching password, no way to derive it, and no way to recover it if lost. Guessing one is not a realistic attack.
Promptly compares the key you send against the stored value in constant time, so an attacker cannot learn a key character by character by measuring how long a rejection takes.
You have one key per workspace, and it carries no scopes — it authenticates as "this workspace" for widget endpoints and nothing more. It cannot read your dashboard, your team, or your billing; those need a signed-in user.
Manage it at Dashboard → Settings → API keys.
Shown once — copy it immediately
The full key is displayed only at the moment it is created or regenerated. After you leave the page the dashboard shows a masked placeholder. There is no "reveal" button, because Promptly is not able to show it to you again in a way that would be safe — if you lose it, you regenerate.
🖼️ [Image] — The API keys page showing the masked key and the "Regenerate Key" button.
Regenerating
Regenerating invalidates the previous key immediately. Every widget and integration still using the old key stops working the second you click the button — so treat it as a small deployment, not a settings tweak:
- Click Regenerate Key and copy the new value.
- Update the
data-api-keyattribute in every embed snippet, on every site. - Update any direct API caller you've built.
- Reload one of your pages and send a test message to confirm the widget still answers.
Regenerate when a key may have leaked — committed to a public repository, pasted into a support ticket, shared in a screenshot — or as routine rotation. If a key has definitely leaked, regenerate first and update your sites afterwards; a few minutes of a broken widget is cheaper than an unknown third party using your workspace and your AI credits.
🎬 [Video] — Regenerating an API key, copying the new value, and updating the embed snippet.
Your key is visible in your page source — and that's fine
The widget reads the key from a data-api-key attribute on the embed script and sends it in the X-Api-Key header. Anyone who views source on your site can read it. This is normal for a browser-side widget key, and it is why the second layer exists: pair the key with an allowed-domains list so a copied key is useless anywhere but your own sites. See Origin guard & rate limiting.
What you should never do is put the key somewhere it will outlive your control of it: a public repository, a mobile app binary, a shared document, a screenshot in a public thread.
Encryption at rest
Secrets Promptly stores on your behalf are encrypted with AES-256 (AES-256-CBC), and every value gets its own random initialization vector — so two identical secrets do not produce identical ciphertext, and one compromised value tells an attacker nothing about the next.
Encrypted at rest:
| Secret | Notes |
|---|---|
| Your AI provider API key | The key you add under bring your own key. Decrypted server-side only to call your provider. |
| Catalog integration credentials | The token, key, or username and password Promptly uses to read your product catalog. |
| Dedicated database connection strings | Only relevant on a dedicated storage mode — see Data isolation & storage modes. Never stored in plain text. |
Your provider key is never shown back to you
Once saved, an AI provider key is only ever displayed masked — first four and last four characters, like sk-a…ab4c. The dashboard shows that mask, the API returns that mask, and nothing in Promptly will print the whole value again. If you need the full key, get it from your provider's console; if you no longer have it there either, issue a new one and update it in Promptly. See API key statuses.
Custom base URLs are validated
If you point a provider at a custom base URL (for a proxy or a self-hosted, OpenAI-compatible endpoint), Promptly checks the address before it will call it. Internal and private destinations are refused — loopback, private network ranges, link-local and cloud metadata addresses — with a plain "Base URL is not allowed". The check is repeated at connection time against the address the hostname actually resolves to, so a hostname that resolves publicly once and privately later still won't be reached. This protects the platform, and it protects you from a mistyped or malicious URL turning your workspace into a probe of Promptly's internal network. Detail in Custom base URLs.
What gets recorded
Security-relevant account events are written to an audit trail you can review — password changes and resets, forced sign-out of all sessions, account deactivation and reactivation, plus platform-side security signals such as blocked abusive traffic and detected prompt injection. See Agent presence & audit log.