Planned API key rotation and a leaked API key need different responses. For a routine change, two valid keys let you move applications gradually before retiring the old credential. If a key has been exposed, revoke it promptly: keeping an attacker’s access alive to avoid an interruption is not a safe rotation strategy.
This guide covers both paths for applications using the SiftingIO market data API. If you are setting up a test environment, create an account and generate an API key. Store the full key when it is first shown; an existing key cannot be revealed again later.
Choose the right rotation path#
| Situation | First action | Availability trade-off |
|---|---|---|
| Scheduled credential change, no suspected exposure | Create a replacement while the old key remains valid | A staged cutover can reduce interruption |
| Key found in a public repository, client bundle or exposed log | Revoke the exposed key and investigate its use | Accept an interruption rather than leave access open |
| Only one active key is allowed | Prepare the deployment, then revoke and replace | There is no two-key overlap |
| All key slots are occupied | Identify an unused key or arrange capacity before the planned change | Do not revoke an unidentified production credential |
A two-key deployment does not guarantee uninterrupted data. Your processes still need to reload their configuration, a stream may need to reconnect, and a reconnect can leave a gap in observations. The objective is a controlled transition with evidence that every consumer moved.
1. Inventory the consumers before a planned rotation#
List more than the main application. A daily export, CI job, notebook or standby instance can hold a credential long after the web server has switched.
| Consumer | Secret location | How it picks up a change | Check after cutover |
|---|---|---|---|
| REST application | Server-side secret reference | Reload or redeploy | Successful authenticated request |
| Scheduled job | Scheduler or job secret | Next run, or an explicit test run | Completed job using the new secret version |
| WebSocket worker | Worker secret reference | Reconnect with the new key | Authentication and subscription acknowledgements |
| Backup instance | Its own deployment configuration | Restart or redeploy | Test the failover path |
Record a non-secret version label, such as market-data-2026-09, in deployment logs. Do not print the key, process environment, request headers or authenticated WebSocket URL to prove which credential is in use. An explicit label is easier to audit than a few trailing characters, which can collide.
For browser applications, keep the provider credential on your server. The web-app API key guide covers that architecture; rotation does not fix a key that is still being shipped to clients.
2. Create and store the replacement#
Open the API keys section of your dashboard. For a planned overlap, your account must have an unused active-key slot. The standard allowances listed on the pricing page, checked on September 30, 2026, are:
| Plan | Active API keys |
|---|---|
| Free | 1 |
| Builder | 3 |
| Pro | 10 |
| Ultra | 20 |
Check the allowance shown in your own account, particularly for a custom arrangement. A new key is not a new subscription and should not be treated as a way around usage limits.
Copy the replacement once into your server-side secret store. A runtime environment variable can deliver it to a process, but do not commit a .env file, paste the key into a ticket, or use a client-exposed environment variable. Restrict who can read the secret and turn off debug output that dumps configuration.
If you cannot create a second key, prepare the deployment changes first, schedule the interruption, revoke the old key, generate the replacement and restart the consumers. Do not promise an exact recovery time before testing that procedure.
3. Move REST jobs and verify an actual request#
Update one low-risk consumer first. For a Python service using requests, this small server-side check reads the credential from the environment without putting it in a command-line argument or URL:
import os
import requests
response = requests.get(
"https://api.sifting.io/v1/last/quote/forex/EURUSD",
headers={"X-API-Key": os.environ["SIFTING_KEY"]},
timeout=10,
allow_redirects=False,
)
print("Quote check HTTP status:", response.status_code)
response.raise_for_status()
if response.status_code != 200:
raise RuntimeError("Expected a direct 200 response")
quote = response.json()
if not all(field in quote for field in ("b", "a", "t")):
raise RuntimeError("Expected a quote response")
Use a market and symbol your account can access. A non-200 response needs interpretation: an entitlement or data-availability problem is not necessarily a bad key. Record the status and a safe error category, not the authenticated request object.
Once that check passes, update the remaining consumers. Run infrequent jobs deliberately rather than assuming that changing a shared secret has restarted every process. Be careful with scheduled jobs that have side effects: use their supported dry-run or read-only health check where appropriate.
4. Reconnect the WebSocket worker deliberately#
A running worker may have read its environment only at startup. Updating a secret does not prove the existing socket is using it.
The WebSocket documentation describes authentication with an initial frame:
{ "op": "auth", "key": "REPLACEMENT_KEY_FROM_YOUR_SECRET_STORE" }
This is a message shape, not a real credential or a complete client. Send it promptly after connecting to wss://stream.sifting.io/ws/v1, wait for a successful authentication acknowledgement, then subscribe to the intended channels. Confirm the subscription acknowledgement and data or market state appropriate for that instrument. An authenticated socket alone is not proof that the subscription succeeded.
If the account has spare connection capacity, start the replacement worker while the old one is running, then transfer responsibility for publishing downstream updates. Avoid delivering duplicate events from both workers. Without spare capacity, stop the old connection before opening the replacement and allow for the resulting observation gap.
Keep the existing heartbeat and reconnect controls. This is a credential change, not a reason to replace a working streaming client. The REST and WebSocket guide explains the two delivery paths.
5. Retire the old key and observe the next job cycle#
For a planned rotation, revoke the old key after all known consumers have passed their checks. Then watch authentication failures, subscription failures and scheduled-job results through at least one run of each consumer.
Do not assume revocation immediately closes every already-open socket. Restart your own old-key workers and verify the replacement connection explicitly. If a compromise is involved, contact support when you need help confirming that access has been invalidated; a quiet log is not proof that nobody used the key.
A failed job after revocation should move to the new credential. Do not restore an exposed key to make the alert disappear.
If the key was leaked, contain first#
Revoke the exposed credential promptly, then deploy a replacement. Review the exposure window, usage changes and systems that could have copied it. Removing a secret from the latest commit does not invalidate copies in older commits, forks, downloaded bundles or logs.
Remove the source of the exposure, scan for related credentials, and restrict the departed user or integration’s access where relevant. Use a secret scanner with redacted findings; commands that print matching lines can copy the full key into terminal logs and incident notes. Coordinate any repository-history cleanup with collaborators after containment.
The OWASP secrets-management guidance is a useful reference for rotation, revocation and secret access controls.
The checklist for the next rotation#
- Every consumer has an owner and a documented secret reference.
- REST checks confirm a valid response, not merely a completed deployment.
- Streaming workers authenticate and subscribe using the replacement.
- No log, browser bundle or URL contains the credential.
- The old key is revoked and infrequent jobs have been checked.
- A leaked key takes the containment path, never the leisurely overlap path.
That makes the next rotation a repeatable operation rather than a search through servers after the first 401.



