SaaS API Keys & Tokens UX Patterns: Real Screenshots (2026)
The API keys page is where a SaaS product hands a user a secret that can move money, read data, or run their whole integration — and it is also the surface teams most often ship as a bare table with a "Create key" button and no thought for the reveal, the scoping, or the day the key leaks. This guide covers the decisions that make credential management safe and usable at the same time: showing the secret exactly once and making it effortless to copy, naming and scoping each key so a compromised one is contained, separating test and live environments so nobody ships a sandbox key to production, surfacing last-used and created metadata so dead keys are obvious, and making rotation and revocation a calm, reversible-feeling action instead of a scary one — each shown with real SaaS screenshots from shipped developer platforms instead of mockups.
The API keys page is one of the highest-stakes screens a SaaS product ships, and it is routinely one of the least designed. It is where the interface hands a user a string of characters that can charge their customers, read their entire dataset, delete records, or run the integration their business depends on — and yet the common version is a bare table with a "Create key" button, a column of masked dots, and a delete icon, built as if it were a settings list rather than the front door to everything the product can do programmatically. Stripe issues publishable and secret keys split cleanly across test and live modes; OpenAI shows a platform key exactly once and never again; Vercel, Netlify, and GitHub mint personal access tokens with scopes and expirations; Twilio, Resend, and Linear all put a key-management surface behind their developer settings. For any product with an API, this page is where security and usability collide most directly: make it too loose and a leaked key becomes a breach with no blast-radius control, make it too rigid and developers work around it by sharing one god-key in a shared doc, which is worse.
The job of this surface is to let a developer create, use, and retire credentials safely without ever having to think about the cryptography underneath — and the design is what determines whether the safe path is also the easy path. A good API-keys page treats a key as a secret with a lifecycle: it is generated, revealed once, named and scoped so its power is bounded, used and observed, and eventually rotated or revoked. Each of those moments is a design decision, and getting them right is what separates a page developers trust from one they route around. It is worth scoping this precisely: this is not third-party integrations (connecting Slack or Google via OAuth so the product acts on your behalf — that is its own surface), and it is not user roles and permissions (who on your team can do what inside the app). This is the developer-credential surface: the keys and tokens a user creates to let their own code talk to the API. The decisions below are what make that surface both safe and genuinely usable, each shown with real SaaS screenshots so you can see how mature developer platforms handle it.
Reveal the secret exactly once — and make copying it effortless
The single most important interaction on this page is the moment a key is created, because a well-built product stores only a hash of the secret and therefore can show the full value exactly once, at creation, and never again. This is a real security property, not a UX inconvenience to design around, and the whole creation flow should be built around communicating it clearly: when the key appears, the interface must say, unmistakably, that this is the only time it will be shown, and it must make capturing the value trivial in that single window. That means a prominent copy button that actually confirms it copied (a check state, a "Copied" toast — not a silent no-op the user has to second-guess), the full secret visible and selectable rather than truncated behind an ellipsis, and, on developer platforms, often a one-click reveal into an environment-file snippet or a language-specific example so the key lands where it is actually used. The failure modes here are quietly severe: a modal the user can dismiss with an accidental click before they have copied the value, a copy button that fails silently so they paste an empty string, or a design that truncates the secret so they copy only part of it and spend an hour debugging a 401. Because the value is unrecoverable, the interface should also make the consequence of losing it clear and the recovery obvious — if you did not copy it, you do not retype it, you delete this key and create a new one — so a user who fumbles the reveal has a calm, understood path rather than a support ticket. Treating the one-time reveal as the centerpiece of the flow, with copying made effortless and confirmed, is the difference between a credential system users trust and one that burns them on their first key.
Name and scope every key so a leak is contained, not catastrophic
A key with a name and a bounded scope is a manageable asset; a pile of anonymous all-powerful keys is a liability, and the design choices that produce the first over the second are naming and scoping at creation time. Requiring — or at least strongly inviting — a human name for each key ("production-backend", "zapier-integration", "ci-deploy") is what makes the list legible six months later when someone has to answer "what is this key for and can I delete it"; an unnamed key is one nobody dares revoke because nobody knows what it will break, so the whole list ossifies into fear. Scoping is the more consequential half: letting a user restrict a key to specific permissions (read-only vs read-write, specific resources, specific endpoints) or to an expiration date means a leaked key is a contained incident rather than a total compromise. GitHub's fine-grained personal access tokens, with per-repository access and granular permissions and a mandatory expiration, are the mature end of this; the immature end is a single key that can do everything the account can do, forever. The design work is to make the powerful, safe choice the easy one: sensible scope defaults (least privilege, not full access), scopes presented in plain language rather than raw permission strings, and expiration offered as a friendly default rather than buried. A product that lets — and gently nudges — users to create narrow, named, expiring keys has turned key management from a standing risk into a routine hygiene task, and that nudge lives entirely in how the creation form is designed.
Separate test and live environments so a sandbox key never ships to production
For any product that has both a sandbox and a real environment — anything touching money, messages, or irreversible actions — keeping test and live keys visibly and structurally separate is not a nicety but a safeguard against a specific, expensive mistake: shipping a test key to production and silently dropping real traffic, or worse, shipping a live key into a test harness and charging real customers. Stripe is the canonical model here: a prominent test-mode toggle, keys that are clearly labeled test vs live and even color-coded, and a mental model where the two worlds never bleed into each other. The design principles that make this work are visibility and friction in the right places: the current environment should be unmistakable at a glance (a persistent badge, a color, a mode switch that changes the whole surface, not a checkbox easy to miss), live keys should carry a stronger visual weight or an extra confirmation because their blast radius is real, and the interface should make it hard to confuse which environment a given key belongs to when copying it. The failure mode is a single undifferentiated list where test and live keys sit side by side looking identical, so the user copies the wrong one and does not find out until money moves or does not. Making the environment a first-class, always-visible dimension of the keys page — not a filter the user has to remember to set — is what prevents the entire category of test-vs-live mistakes, and it is a defining trait of developer platforms people trust with production traffic.
Surface last-used and created metadata so dead keys are obvious
Keys accumulate — a developer creates one for a script they run twice, an integration they later remove, a contractor who has since left — and without metadata the list becomes an unauditable pile nobody will ever prune, which is precisely how old, forgotten, over-privileged keys become the thing that gets exploited. The fix is to show, for every key, the information that makes a keep-or-kill decision possible: when it was created, who created it (in a team context), when it was last used, and often the last few characters of the key so a user can match it against a key they hold without revealing the secret. Last-used is the most valuable of these by far, because a key that has not been used in ninety days is almost certainly safe to revoke, and surfacing that turns an intimidating audit into an obvious cleanup — the product is effectively telling the user which keys are dead. Mature platforms go further and show a bit of usage context (last-used timestamp, sometimes last-used IP or a request count) so an anomaly — a key that suddenly starts being used from somewhere unexpected — is visible on the page where the user can act on it. The design discipline is to make the metadata scannable rather than buried in a detail drawer: a keys table where created and last-used are columns, sortable so the stale keys float to the top, turns key hygiene from a task nobody does into one the interface almost does for them. A keys page without last-used is a page that guarantees dead keys live forever.
Make rotation and revocation calm, clear, and hard to do by accident
The end of a key's life — rotating it because it may have leaked, or revoking it because it is no longer needed — is where the design has to hold two things in tension: revoking a key is destructive and immediate (anything using that key breaks the instant it is revoked), so it must be protected against accidental clicks, but it also must not be so frightening that a user leaves a compromised key live rather than face the flow. The pattern that resolves this is a clear, honest confirmation that states the consequence in plain terms — "revoking this key will immediately break any application still using it" — paired with an identifier (the key's name, its last four characters) so the user is certain they are killing the right one, and no undo, because there genuinely is none. Rotation deserves special design attention because the safe way to rotate is to create the new key, deploy it, and only then revoke the old one, and a thoughtful product supports that overlap rather than forcing a hard cutover: some platforms offer an explicit "roll" action that provisions a replacement and lets the old key keep working for a grace window, which is the difference between a zero-downtime rotation and an outage. The visual language matters too: destructive actions should look destructive (a red, deliberately-placed revoke, not a delete icon adjacent to a copy icon where a misclick is easy), and a leaked-key panic — the case where speed matters most — should have an obvious, fast path to kill the key without hunting. Getting this right means a user rotates keys as routine hygiene instead of avoiding it, and that a real leak gets shut down in seconds rather than after a debate about which button is safe to press.
Mask secrets everywhere else — the page should never leak what it protects
Outside the one-time reveal at creation, the keys surface should treat the secret as something it deliberately does not show, because a page whose whole purpose is guarding credentials undermines itself the moment it renders a full secret over someone's shoulder, into a screen recording, or in a support screenshot. The default state of every existing key is masked — dots or a prefix plus the last four characters (sk_live_...a4f2) — enough for the user to identify which key it is without exposing the value, and there is intentionally no "show" button that reveals a stored secret, because a correctly-built product cannot show it (it only kept a hash) and a product that can show it is storing secrets in a way it should not. This masking has to extend past the table into the details that leak: a key's value should never appear in a URL, never be logged where it surfaces in an activity feed, never be emailed in plain text. The copy affordance on an existing key, where it exists, copies the identifier or triggers a fresh reveal flow rather than exposing the original secret. The design tell of a mature keys page is that it is boring to look at precisely because it is not showing you anything sensitive — masked values, last-four identifiers, metadata — and the only place a full secret ever appears is the single creation moment, gated behind an explicit reveal. A keys page that shows full secrets in its resting state is not a security feature with a UX problem; it is a leak the design is committing on the product's behalf.
The details that separate a keys page developers trust from a bare table
Each decision above is modest on its own; a credential surface feels genuinely designed — safe and usable at once — when they are handled together. These are the behaviours mature SaaS developer platforms share across their API-key and token screens.
- The secret is shown exactly once at creation, framed unmistakably as the only reveal, with a prominent copy button that confirms it copied and the full value visible — never truncated, never silently dismissible before capture.
- Every key can be named and scoped at creation (least-privilege defaults, plain-language permissions, an optional or default expiration) so the list stays legible and a leaked key is contained rather than total.
- Test and live environments are a first-class, always-visible dimension — labeled, color-coded, or mode-switched — so a sandbox key never ships to production and a live key never lands in a test harness.
- The keys table shows created, created-by, and last-used metadata (plus a last-four identifier), sortable so stale keys surface, turning key hygiene into an obvious cleanup instead of an audit nobody performs.
- Revocation is destructive-by-design: a plain-language confirmation stating the consequence, the key identified by name or last-four, no false undo — and rotation supports an overlap (new key live before the old is killed) for zero-downtime.
- Secrets are masked everywhere outside the one-time reveal — last-four identifiers in the table, no full value in URLs, logs, emails, or activity feeds — and there is no "show stored secret" button, because a correctly-built product only kept a hash.
- The page is kept distinct from third-party integrations (OAuth connections the product makes on your behalf) and from user roles/permissions (who on your team can do what) — it is the developer-credential issuance and lifecycle surface.
Common SaaS API-key & token mistakes
- Showing a newly created secret in a modal the user can dismiss with a stray click before copying, or a copy button that fails silently so they paste an empty string.
- Truncating the full secret behind an ellipsis at the one reveal, so the user copies only part of it and debugs a 401 for an hour.
- Unnamed, unscoped, non-expiring keys that can do everything forever, producing a list nobody dares revoke because nobody knows what each key does.
- A single undifferentiated list where test and live keys look identical, so the wrong one gets copied and the mistake only surfaces when money moves — or does not.
- No last-used or created metadata, guaranteeing that dead, forgotten, over-privileged keys live forever as the most likely thing to be exploited.
- A revoke icon sitting next to a copy icon with no confirmation, so a misclick breaks production — or, at the opposite extreme, a flow so scary users leave a compromised key live.
- A "show" button that reveals a stored full secret in the resting state, exposing it to shoulder-surfers, screen recordings, and support screenshots.
- Leaking the secret into a URL, an activity-feed log line, or a plaintext confirmation email — undermining the entire purpose of the page.
Frequently asked questions
Why can I only see an API key once?
Because a security-conscious product stores only a hashed version of the secret, not the secret itself — which means that after the one-time reveal at creation, it genuinely cannot show you the full value again, only a masked identifier. This is a feature, not a bug: if the product could re-display your full key on demand, it would mean the plaintext secret is sitting in its database, where a breach or a rogue employee could read it. The correct design consequence is that the creation moment is the single window to capture the value, so the interface should make copying it effortless and clearly warn that it will not be shown again. If you miss it, the right move is not to retype it — you delete that key and create a new one, which takes seconds. A product that offers to re-reveal an existing key's full secret is quietly telling you it stores your credentials in a way it should not.
How is an API key different from an OAuth integration?
They solve different problems and live on different surfaces. An API key (or personal access token) is a credential you create for your own code to call the product's API directly — you generate it, store it in your environment, and your backend or script authenticates with it. An OAuth integration is the product connecting to a third-party service on your behalf — you click "Connect Slack" or "Connect Google", approve a consent screen, and the two apps exchange tokens behind the scenes so the product can act in that other service without you ever handling a raw key. The keys page is where you manage credentials for your code; the integrations page is where you manage connections to other apps. Blurring them is a common information-architecture mistake — burying API-key management inside an "Integrations" tab, or mixing OAuth connections into the keys table — and keeping them separate matches the different mental models: "credentials my code uses" versus "apps this product is connected to".
Should API keys expire by default?
For most products, offering expiration and defaulting to a sensible window is the safer design, because a key that expires is a key that cannot leak forever — the biggest risk with credentials is the forgotten, long-lived, over-privileged key that no one is watching. GitHub's fine-grained tokens make expiration effectively mandatory for exactly this reason. That said, expiration has a real cost: a key that silently expires can take down a production integration at an unpredictable moment, so if you offer or enforce it, the design must support it — advance-warning notifications before a key expires, clear last-used data so the user knows which keys are live, and an easy rotation path. The balance most mature platforms strike is to make short-lived, scoped keys the easy default for interactive and one-off use, while allowing longer-lived (but still named, scoped, and monitored) keys for stable production integrations, paired with proactive expiry reminders so no one is surprised by an outage. The wrong answer is a single non-expiring, all-powerful key with no usage visibility, which is the exact shape of the credentials that end up in breaches.
Study real SaaS API-key & token pages in the SaaSUI library
Every decision above is easier to apply when you can see how real products solved it. Browse real API-key and access-token management screens, developer settings, one-time secret reveals, key-creation and scoping flows, test-vs-live environment toggles, and revocation and rotation patterns from shipped SaaS applications like Stripe, Vercel, Linear, GitHub and other polished developer platforms in the SaaSUI.Design library, with real screenshots instead of mockups, to study how mature products handle the one-time reveal, name and scope keys for least privilege, separate test and live credentials, surface last-used metadata, make revocation safe, and mask secrets everywhere the key is not being created.

Interested in sponsoring SaaSUI.Design? Learn about sponsorship options →











