The short version: A price migration needs write on Subscriptions, Prices and Products, and read on Customers, Account and Invoices. Everything else stays None. If you already administer the client's Stripe account, that list is all you need. If you do not, ask for a restricted key with exactly those scopes rather than dashboard access or a secret key, and there is a copy-paste email below.
When you need to ask, and why a restricted key is the right ask
Plenty of agencies already administer their clients' Stripe accounts and can create the key themselves, in which case skip to the permission list below, which is the part that actually matters. This is for the other case: you build and run the site, but billing lives with the client, and you need access you do not currently have.
Asking for access to the system that takes their money is a different conversation from asking for WordPress admin, and most of the obvious ways to grant it are far broader than the job needs. Adding you as a Stripe team member hands over the whole dashboard: payouts, disputes, customer payment methods, the lot. Sharing a secret key is worse, because it is unscoped and it is the kind of thing that lives in a Slack message forever. Neither is proportionate to changing a price.
A restricted key is the answer. The client creates it themselves, in their own account, with a specific list of permissions. It is revocable in one click, it can be scoped so tightly that it cannot do anything they would object to, and it never gives you a way into the dashboard itself.
The email
Copy this, fill in two blanks, send it. It is deliberately short and it explains the shape of what you are asking for rather than assuming they know what a restricted key is.
Subject: Quick Stripe access for the price update Hi [client], To run the price change we discussed, I need a restricted Stripe key from your account. Restricted means it can only touch the parts this job needs, and nothing else. The permissions to set: Write: Subscriptions, Prices, Products Read: Customers, Account, Invoices Everything else stays None. That means no access to your payment methods, your coupons or your tax settings. The invoice access is read only, used to work out what a change would cost a member before anything is applied; it cannot create, edit or send an invoice, and none of it can move money. To create one: Stripe Dashboard, then Developers, then API keys, then "Create restricted key". Set those six permissions, name it something like "Price migration", and send it over. Before anything is applied I'll send you the full list of affected members with their current and new pricing, so you can approve it. You can delete the key in that same screen the moment we're finished. Thanks, [you]
Why each permission is on the list
If your client asks, and the good ones do, here is the justification for each line. Being able to answer this on the spot is most of why the request goes smoothly.
- Subscriptions (write). The actual job. Reading which subscriptions are on the old price, and updating them to the new one. This also covers subscription schedules, which is how a change is queued for someone's next renewal instead of applied immediately.
- Prices (write). Stripe prices are immutable, so a price change means creating a new price rather than editing the old one. Write also allows archiving the old price so nobody signs up on it by accident.
- Products (write). Only to set the new price as the product's default, so new signups get the new price too. Without this you change existing members and new ones keep arriving on the old price.
- Customers (read). So the affected-member list has names and email addresses in it. Without this you get a list of subscription ids, which is useless as an approval document.
- Account (read). Reads the account id, so tooling can tell one client's account from another.
- Invoices (read). Read only, to estimate what a change would cost a member before it is applied. It cannot create, edit or send invoices.
Notice what is not on the list: payment methods, coupons, tax rates, payouts, disputes, balance. A client can check that in the key editor themselves, and it is worth inviting them to.
What to do after the migration
Tell them to delete the key, and say so in the same message where you report the work is done. It closes the loop, it is good practice, and it is the difference between a client who feels they gave you access to a task and one who feels they gave you access to their Stripe account.
If you work with the same client repeatedly, it is still better to have them create a fresh key each time than to hold one indefinitely. A key that exists for two days is a much smaller thing to worry about than one that exists for two years.
If the client pushes back
Two objections come up, and both have straightforward answers.
"Can you just tell me what to click instead?" Sometimes the right answer is yes. If they only have a handful of subscribers, walking them through it themselves is fine. It stops being reasonable somewhere in the low tens, because every subscription is a separate manual edit and manual edits are where mistakes with someone's billing come from.
"What happens if something goes wrong?" Answer it before you run anything, not after. Show them the list of affected members first, agree it in writing, and tell them what the undo path is. If the change is queued for each member's renewal rather than applied immediately, there is a window where undoing it costs nothing at all, which is usually the detail that settles it.
Running migrations for clients?
The agency guide covers the whole workflow: the key, the preview your client signs off on, notice windows, and pricing across multiple accounts. Test mode is free end to end.
Read the agency guide →Frequently asked questions
Is a restricted key safe to send over email?
Safer than the alternatives, but treat it like a password. Ask the client to send it through whatever channel you already use for credentials, and have them delete the key when the work is finished. Because it is scoped, the worst case is much smaller than a shared secret key or a dashboard invite.
Can I create the restricted key myself if I already have dashboard access?
Yes, and that is fine when you are already a team member on the account. The reason to have the client create it is that it keeps the boundary explicit: they can see exactly what they granted, and they can revoke it without involving you.
Does the client need to be on a particular Stripe plan?
No. Restricted keys are available on every Stripe account, under Developers then API keys.
What if their subscriptions were created by a membership plugin?
That is the usual case and it does not change the access you need. What it changes is whether the subscriptions can be re-priced at all, and the test is whether the subscription ids start with sub_, meaning native Stripe Billing. Paid Memberships Pro, MemberPress, Ghost and Substack all create those.