# Rotating API keys

> Your application's API keys reach every merchant instance in their environment, so treat them like any other production credential and replace them regularly. E

Your application's API keys reach every merchant instance in their environment, so treat them like any other production credential and replace them regularly. Each environment can hold two keys at once, which lets you move your integration to a new key before you switch the old one off, with no downtime.

## How often to rotate

**We recommend rotating every API key at least every 90 days.** Rotate immediately, without waiting for the next scheduled rotation, when:

- a secret key may have been exposed: committed to a code repository, written to a log, pasted into a ticket, chat or email, or put in a browser or mobile app
- someone who could see the key leaves your team, or no longer needs access
- a server, laptop or service that held the key may have been compromised

If you are assessed against PCI DSS, requirement 8.6.3 asks you to change application credentials periodically and whenever they may be compromised. A 90-day rotation, recorded each time, gives you that evidence.

Sandbox and live keys are separate. Rotate both: a sandbox key can't move money, but it can read and change your sandbox merchants' data.

## Before you start

- **Find your keys.** In the Shuttle portal, open your organisation, then your [application](/platforms/embedded-payments/applications/), then **Developer**. Sandbox and Live each have their own card with their own keys.
- **Check your access.** If you can't see an environment's card, or its keys show **Access Restricted**, your role doesn't cover that environment. Ask an administrator of your organisation.
- **List where the key is used.** Note every place that holds the secret key or its shared key before you begin (see [Where keys are used](#where-keys-are-used)). A copy you miss stops working when you disable the old key.

## Rotate a key

The steps are the same for Sandbox and Live. Do them in the card for the environment you are rotating.

1. **Create the new key.** Under your current key, **API Key 1**, select **create** next to **API Key 2**. The new key appears as **ACTIVE**. Both keys now work.
2. **Copy the new secret key.** Select **show secret key** on API Key 2, then **copy**. Put it straight into your secret store (a secrets manager or your deployment's encrypted environment variables), not a file or a message.
3. **Test the new key.** Make a read-only request with it before you deploy:

   ```bash
   curl -u "$NEW_SHUTTLE_SECRET_KEY:" \
     "https://app.shuttleglobal.com/c/api/instances?limit=1"
   ```

   A `200` response means the key works. A `401` means you copied the wrong value or the key for the other environment.
4. **Move your integration to the new key.** Update every place in your list and deploy. If you load shuttle.js, change the shared key in its URL to API Key 2's shared key at the same time.
5. **Confirm nothing still uses the old key.** Check on your side that every server and region is running the new configuration, scheduled jobs and scripts have picked it up, and your logs show no requests sent with the old key.
6. **Disable the old key.** Select **disable** on API Key 1. Its status changes to **INACTIVE** and requests made with it are refused with `401`. Repeat the test request with the old key to confirm it now fails.
7. **Watch for errors.** Keep an eye on your logs for `401` responses from Shuttle for a day or two. If something you missed breaks, select **enable** on the old key to restore it while you fix that service, then disable it again.
8. **Delete the old key.** When you are sure nothing needs it, select **delete** on the inactive key. A deleted key can't be restored.

An environment holds at most two keys, so delete the old key before your next rotation: until you do, there is no **create** option. Keys are numbered by age, so once the old key is deleted, your new key shows as **API Key 1**.

## If a key has been exposed

Don't wait for a quiet moment to change over. Create the new key, deploy it, and disable the exposed key as soon as the deploy is out, even if a few requests from a service you missed fail. Then:

- delete the exposed key once your integration is stable on the new one
- remove the key from wherever it leaked, such as repository history, logs or tickets. Removing it doesn't make it safe again, but stops it spreading further
- [contact Shuttle support](mailto:support@shuttleglobal.com) if you think the key was used by someone else, so we can help you check what it was used for

## Where keys are used

Check each of these when you build your list:

- **Your servers.** Every environment, region and deployment that calls the Shuttle API, including staging copies that point at live.
- **Background jobs and scripts.** Scheduled tasks, queue workers, reporting and reconciliation scripts, and one-off tools.
- **shuttle.js.** The script URL for [Express Checkout](/platforms/embedded-payments/express-checkout-integration-guide/) and [BNPL Messaging](/platforms/embedded-payments/bnpl-messaging-integration-guide/) contains the key's **shared key**. Each API key has its own shared key, so update the URL with the new one.
- **Phone payment connectors.** A Twilio or Telnyx Pay connector stores a Shuttle secret key in its own configuration, outside your systems. Update it in the Twilio Console or Telnyx Portal (see [Twilio Pay architecture](/platforms/twilio/pay-architecture/)).
- **CI and test configuration.** Pipelines, test suites and monitoring checks that call the API.

This page covers your application's API keys. Merchants' instance API keys and OAuth client secrets are separate credentials with their own controls. See [Authentication for platforms](/platforms/reference/authentication/) for how API keys are sent with each request.