What it creates
| Lookup key | Kind | Display | Price (USD) | Grants |
|---|---|---|---|---|
lavendly_starter_monthly | recurring | Lavendly Starter | $29 / mo | Starter plan |
lavendly_creator_monthly | recurring | Lavendly Creator | $89 / mo | Creator plan |
lavendly_studio_monthly | recurring | Lavendly Studio | $249 / mo | Studio plan |
lavendly_pack_100 | one-time | 100 credits | $12 | +100 credits |
lavendly_pack_500 | one-time | 500 credits | $55 | +500 credits |
lavendly_pack_1500 | one-time | 1500 credits | $149 | +1500 credits |
lavendly_pack_5000 | one-time | 5000 credits | $400 | +5000 credits |
lookup_key, so re-running the script never
creates duplicates, it finds existing prices and skips them.
One-shot flow
Get a sandbox key
Stripe dashboard → test mode → API keys.Use the Secret key (starts with
sk_test_…) or a Restricted key
(rk_test_…) with these permissions enabled:- Products → Write
- Prices → Write
- Webhook endpoints → Write (only if you pass
--webhook)
Drop it into .env.local
STRIPE_API_KEY=rk_test_… is also accepted if that’s the var name
your tooling uses.Apply and write back the price IDs
lookup_key), then
appends or updates the STRIPE_PRICE_* block in .env.local.Register the webhook (optional, recommended)
checkout.session.completedcustomer.subscription.deletedcustomer.subscription.pausedinvoice.payment_failed
STRIPE_WEBHOOK_SECRET. On re-runs it’s stored in the dashboard
(Webhooks → endpoint → Signing secret → click to reveal).Going to production
The exact same script with a live key:--live flag is REQUIRED for live keys. Without it the script
refuses to run, even in dry mode. There’s no auto-detection, you
explicitly opt in.
Re-running safely
The script is idempotent. Re-running it:- Finds each existing product by name → reuses it
- Finds each existing price by
lookup_key→ reuses it - Finds the existing webhook by URL → updates the subscribed events
- Archive the old price in the Stripe dashboard.
- Pick a new
lookup_key(e.g.lavendly_starter_monthly_v2) inscripts/stripe-setup.mjs. - Re-run with
--apply. - Update the corresponding
STRIPE_PRICE_*env var.
Troubleshooting
Stripe returned 401 Invalid API Key
Stripe returned 401 Invalid API Key
Your key isn’t a Stripe secret/restricted key. Check the prefix,
valid forms are
sk_test_, sk_live_, rk_test_, rk_live_.Stripe returned 403 on /products or /prices
Stripe returned 403 on /products or /prices
Restricted key with insufficient permissions. Edit the key in the
Stripe dashboard and grant Write on Products + Prices (and
Webhook endpoints if you use
--webhook).Refusing to run against a LIVE Stripe key
Refusing to run against a LIVE Stripe key
Pass
--live explicitly. The script never assumes you want to
touch your live account.