Stripe API Keys: Test vs Live, Explained
Stripe gives you 4 key types across test and live mode. Learn which is which, and how Ringtail mints the right scoped Stripe API key from its official API.

Rocco kept the test key and the live key in different pockets. Mixing them up is how you charge a real card during a demo.

🦝 Rocco: sk_test_ plays pretend. sk_live_ moves real money. never let them share a pocket.
Stripe gives you a publishable key and a secret key in each of two modes — test and live — so four keys total, plus optional restricted keys for least privilege. Test keys (pk_test_…, sk_test_…) hit the sandbox and move no real money; live keys (pk_live_…, sk_live_…) charge real cards. You find them under Developers → API keys with a mode toggle. Below is what each key does, when to use a restricted key, and how Ringtail mints the right scoped Stripe key from Stripe's official API without exposing it to your coding agent.
Where do you find Stripe API keys?
You find them in the Stripe dashboard under Developers → API keys at dashboard.stripe.com. A test mode toggle at the top of the dashboard switches the whole view — and the keys shown — between test and live. Flip it to see the test keys; flip it back for live.
Publishable keys are visible in full anytime (they're safe for client-side use). The secret key is revealed once when you create or roll it; after that Stripe masks it. Restricted keys live on the same page under Create restricted key.
What's the difference between test and live keys?
Test keys operate on Stripe's sandbox and move no real money; live keys operate on your real account and charge real cards. They're not interchangeable — a sk_test_ key against live data returns an error, and vice versa.
| Key | Ringtail-scoped equivalent | What it does | Where it's safe |
|---|---|---|---|
Publishable test pk_test_ | client-side, sandbox | Identifies your account in test mode | Public — client code |
Secret test sk_test_ | full sandbox access | Full API access to test data | Server only |
Publishable live pk_live_ | client-side, real | Identifies your account in live mode | Public — client code |
Secret live sk_live_ | full live access | Full API access, moves real money | Server only — guard it |
Publishable keys (pk_…) are meant to be exposed in front-end code; they can't move money on their own. Secret keys (sk_…) must stay server-side — a leaked sk_live_ key can issue refunds and read customer data. Keep test and live secrets in separate environment variables so a config mix-up can't charge a real card in a demo.
When should you use a Stripe restricted key?
Use a restricted key (rk_…) whenever a service needs only part of the API — a webhook processor, a reporting job, a background worker. Instead of handing that service a full-power sk_live_ key, create a restricted key under Developers → API keys → Create restricted key and grant read or write only on the specific resources it touches (for example, read-only on Charges, none on Customers).
A restricted key is Stripe's built-in least-privilege API key provisioning: the key can do exactly its job, so a leak from your reporting service can't issue refunds. Reserve the full secret key for the core payment path that genuinely needs it, and give everything else a restricted key.

🦝 Rocco: the reporting job doesn't need to move money. give it a restricted key that can only read.
How do you use the keys safely in code?
Publishable key on the client, secret key on the server, read from the environment:
# .env.local — test mode during development
STRIPE_SECRET_KEY="sk_test_..."
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_test_..."
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
Never commit a secret key, and never ship sk_live_ to the browser. If a live secret key ever appears in a git commit or client bundle, roll it immediately in the dashboard — the make-before-break approach in rotating API keys without breaking production applies. Keeping secrets out of the repo in the first place is stop committing secrets to git.
How does Ringtail create the right key for you?
Once you've connected your Stripe account to Ringtail one time, Ringtail mints the right scoped key for the right environment by driving Stripe's official API — a restricted key for a worker, the correct test or live secret for the matching environment — so you never fumble the test/live toggle again. Ringtail reads STRIPE_SECRET_KEY from your .env.example, calls Stripe's official API to create a key scoped to what your service needs, validates it, and writes the value into .env.local (test) and your Infisical (per environment).
It's value-free: the key string is returned by Stripe's API straight into your files. Your coding agent decides test vs live and which resources the key may touch, but never sees the secret. Install it once:
curl -fsSL ringtail.sh | sh
ringtail up
Ringtail uses official provider APIs only — never a browser bot with your Stripe login. For provisioning every key in a project this way, see how to stop juggling 15 API keys on every new project.
FAQ
What's the difference between a Stripe test key and a live key?
A Stripe test key (pk_test_… / sk_test_…) operates on Stripe's sandbox and moves no real money, so you can build and test freely. A live key (pk_live_… / sk_live_…) operates on your real account and charges real cards. They're not interchangeable — using a test key against live data returns an error. Keep them in separate environment variables so a config mix-up can't charge a real card.
What's the difference between publishable and secret Stripe keys?
Publishable keys (pk_…) are safe to expose in client-side code — they identify your account but can't move money on their own. Secret keys (sk_…) grant full API access and must stay server-side; a leaked sk_live_ key can issue refunds and read customer data. Put publishable keys in the browser and secret keys only on your server, read from environment variables.
When should I use a Stripe restricted key?
Use a restricted key (rk_…) when a service needs only part of the Stripe API — a webhook handler, a reporting job, a background worker. Create it under Developers → API keys → Create restricted key and grant read or write only on the resources that service touches. A restricted key limits the blast radius: if it leaks, it can't perform actions you didn't grant, unlike a full secret key.
Can Ringtail mint the correct Stripe key for each environment?
Yes. After you connect your Stripe account to Ringtail once, Ringtail calls Stripe's official API to create the right scoped key — restricted where a service needs less, test or live matching the environment — validates it, and writes it to .env.local and Infisical. It's value-free, so the key never reaches your coding agent, and it uses the official API only, never browser automation.
