API Keys

In A Nutshell
In a nutshell

Paystack has three types of API keys. Public keys initiate payments from your frontend, secret keys call the full API from your backend, and restricted keys call only the endpoints you grant them.

Key types

Every integration has a public key and a secret key for test mode and for live mode. Test keys start with pk_test_ or sk_test_, and live keys start with pk_live_ or sk_live_. Restricted keys are optional, and you create them on the dashboard when you need them.

TypePrefixWhere you use itWhat it can do
Public keypk_FrontendInitiate transactions with Paystack Inline and the Mobile SDKs
Secret keysk_BackendCall every endpoint in the Paystack API and verify webhook signatures
Restricted keyrk_BackendCall only the endpoints covered by its scopes

You use your public key in code that runs on your customer's device, so it's the only key that's safe to expose. Your secret key gives full access to the API. You also need it to verify webhook signatures, since Paystack signs webhook events with your secret key and not a restricted key. If your integration computes checkout hashes for Paystack Inline, or calls an endpoint that doesn't have a scope yet, you need your secret key for that too.

A restricted key is useful when a service only needs part of the API. For example, a reporting job that reads transactions only needs transactions:read. It's also the safer way to give a third party access to your account: you can scope the key to what their tool does, and revoke it when you stop working with them. If a restricted key leaks, it can only call the endpoints its scopes cover.

Keep secret and restricted keys on your server

Don't put a secret key or a restricted key in frontend code, a mobile app, or a code repository.

To learn how to send your key with a request, how test and live modes work, and how to set up IP allowlisting, check out the Authentication page.

Rotate your secret keys

You should rotate your secret keys on a regular schedule, and right away if you suspect one has leaked. You generate new keys on the dashboard, then choose how long your current keys keep working while you move your systems over to the new ones.

Before you begin!

Generating new keys replaces your live and test secret keys together. Before you start, find every place that uses either key: your production and staging servers, background workers and scheduled jobs, CI/CD secrets and your secrets manager, and your webhook verification code. Each of these needs the new key before your current key expires.

Generate new secret keys

  1. Open the Developers overview page on your dashboard.
  2. Click Generate new secret keys.
  3. Under How soon should your old keys expire?, choose an expiry time.
  4. Confirm, then copy your new live and test secret keys.

When your current keys expire, Paystack sends you an email to let you know. The email doesn't contain your key values.

Choose an expiry time

Your new keys work from the moment you confirm, and your current keys keep working until the expiry time you choose. The table below shows each option and when to use it:

OptionWhen to use it
ImmediatelyYou suspect a secret key has been exposed
30 minutesYou can update every system that uses the key within 30 minutes
2 hoursYou're doing a planned rotation with one deployment
6 hoursYou're doing a planned rotation across several services or teams
12 hoursSome systems need a manual change or an approval before you can deploy
NeverYour current keys keep working with no expiry. Don't choose this if a key has leaked.
If a key has been exposed

Choose Immediately. Every request made with the exposed key fails from that moment, including requests from your own servers, so have the new key ready to deploy.

Update your servers

Replace the secret key in each environment, then deploy or restart every service that reads it. We recommend reading the key from an environment variable or your secrets manager rather than from source code, so the next rotation is a configuration change and not a code change.

To confirm a server is using the new key, call the Check BalanceAPI endpoint from that server. A 200 response with "status": true means the key works:

1curl https://api.paystack.co/balance \
2 -H "Authorization: Bearer $PAYSTACK_SECRET_KEY"

Repeat the check with your test secret key in your test environments. Once your current key expires, any server still using it gets a 401 response with the message Invalid key. If you see this, make sure live systems have the new sk_live_ key and test systems have the new sk_test_ key, then redeploy.

Update your webhook signature validation

Paystack signs webhook events with your secret key, so your signature validation code needs the new key after you rotate. Until your current key expires, check each event's signature against both keys and accept it if either one matches. Once the current key expires, remove it from your configuration.

Restricted keys

Invite-only pilot

Restricted keys are available to integrations enrolled in the pilot. Integrations that connect to Paystack through a plugin aren't included in the pilot.

A restricted key authenticates requests the same way a secret key does, with Authorization: Bearer rk_..., but it can only call the endpoints its scopes allow. Every restricted key has a label that describes what it's for and at least one scope, such as transactions:read. You can also give it an expiry date, after which the key stops working.

You can change a key's label and scopes after you create it, and an integration can have up to 50 active restricted keys. Because restricted keys grant access to the API, Paystack asks for your dashboard password whenever you create, update, rotate, or revoke one.

Create a restricted key

Before you create a key, decide which scopes the service needs and grant only those. Switch your dashboard to test or live mode first: a key created in test mode starts with rk_test_ and only works with test data.

  1. Open the restricted keys section of the Developers overview page on your dashboard.
  2. Enter a label that describes what the key is for, such as Reporting service.
  3. Select the scopes the key needs.
  4. Optionally, set an expiry date.
  5. Enter your dashboard password to confirm.
  6. Copy the key and store it in your secrets manager. After you leave the page, the dashboard only shows the key's last 4 characters.

Make a request with a restricted key

You send a restricted key in the Authorization header, just as you would a secret key. This request calls the List TransactionsAPI endpoint with a key that has the transactions:read scope:

1curl "https://api.paystack.co/transaction?perPage=1" \
2 -H "Authorization: Bearer $PAYSTACK_RESTRICTED_KEY"

If you've set up the key and scope correctly, you get a 200 response:

1{
2 "status": true,
3 "message": "Transactions retrieved",
4 "data": [
5 {
6 "id": 4099260516,
7 "domain": "test",
8 "status": "success",
9 "reference": "re4lyvq3s3",
10 "amount": 40333,
11 "currency": "NGN",
12 "paid_at": "2024-08-22T09:15:02.000Z"
13 }
14 ],
15 "meta": {
16 "next": "dW5kZWZpbmVkOjQwMTM3MDk2MzU=",
17 "previous": null,
18 "perPage": 1
19 }
20}

If you get an error instead, see Restricted key errors.

Rotate or revoke a restricted key

Rotating a restricted key replaces that one key, and the new key keeps the same label and scopes. The current key stops working immediately, or after a grace window of up to 24 hours, and you can't rotate it again while it's in its grace window. Only the service that uses the key needs updating.

Revoke a restricted key when nothing should use it again, such as when you stop working with the third party that held it. The key stops working on the next request.

Scopes

A scope grants a restricted key access to one resource at one level, and it's written as resource:level, for example transactions:read. The read level grants the endpoints that retrieve a resource, and write grants the endpoints that create, update, or delete it.

The table below lists the levels each resource supports:

ResourceLevels
apple_paywrite
balanceread
bank_accountsread, write
banksread, write
bulk_chargesread, write
connectwrite
customer_insightsread
customersread, write
direct_debitread, write
disputes_refundsread, write
metricsread, write
payment_pagesread, write
payment_requestsread, write
payoutswrite
plansread, write
preauthorizationsread, write
productsread, write
settlementsread, write
subaccountsread, write
terminalsread, write
transactionsread, write
transfersread, write
verificationwrite
virtual_accountsread, write
webhooksread, write
What restricted keys can't do

Restricted keys can't manage API keys or change your integration settings, and some endpoints don't have a scope yet. Use the dashboard or your secret key for those.

Restricted key errors

Paystack checks the key first, then the key's scopes, then the request itself. This means a request with a missing scope gets a 403 response even if its body is also invalid. The table below shows each error a restricted key can get:

StatusMeaning
401The key is unknown, malformed, revoked, expired, or you replaced it when you rotated it. The message is Invalid key, the same as for an invalid secret key.
403The key is valid but doesn't have the scope the endpoint requires. Add the scope to the key on the dashboard, or use a key that has it.
400The key has the required scope, but the request is invalid. This is the same validation error a secret key gets.