Bybit expires every API key created without bound IP addresses after 90 days. Push orders, balances, and agent calls through two fixed static EU IPs, whitelist them once, and hold keys that never age out.
# one variable pins egress on every surface
HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443
# bound keys never expire, so bind addresses
# that never rotate
curl -s "https://api.bybit.com/v5/account/wallet-balance?accountType=UNIFIED&coin=BTC" \
-H "X-BAPI-API-KEY: $BYBIT_API_KEY" \
-H "X-BAPI-SIGN: $SIGN"
Bybit wants API keys bound to specific IP addresses, and it enforces the point with a deadline. The rule is easy to follow only if your infrastructure can name an egress address that never changes. Most cannot.
The FAQ states it plainly: "An API key created without binding IP address(es) will expire after 90 days." Every unbound key is a quarterly project of re-creation, re-permissioning, re-deployment, and re-testing, on a schedule Bybit chose and you did not.
Binding IP address(es) is exactly what removes the expiration, and it works beautifully until your platform reschedules a workload and the egress address changes. Then a key built to live forever is refused at the door. Expire every 90 days, or lock out at random: those are the options rotating egress gives you.
Bybit answers at api.bybit.com for production, api-testnet.bybit.com for testnet, and api-demo.bybit.com for demo trading, and a key only works against the surface it was cut for; the mismatch surfaces as error 10003. Three surfaces, three keys, three whitelists, unless the addresses behind them are shared.
Before a line of integration code, the institutional paths want addresses. OAuth onboarding and the Broker Management Backend both make submitting an OpenAPI Whitelist IP a mandatory prerequisite, not an afterthought. The pair you nominate there should be the pair your traffic actually leaves from, or the paperwork describes a fiction.
Your Platform
bots · strategies · agents
HTTPS Proxy
(Static EU IP)
Bybit
api.bybit.com
Bind both fixed addresses to the key at creation and the 90-day clock is switched off at the source: the key stops aging, and every signed request arrives from an address it has always known.
HTTPS_PROXY once in your platform's environment; order placement, wallet reads and agent traffic then leave from your fixed pair.X-BAPI-SIGN and X-BAPI-API-KEY headers stay encrypted past the proxy hop; we never see them.Binding addresses is the documented way to make a key permanent, and a fixed pair is the documented way made painless. Cut the key, paste two IPs, and the quarterly re-creation ritual simply ends.
Containers reschedule, nodes recycle, functions cold-start on fresh addresses. When the egress pair never moves, every one of those events is invisible to a key that checks source addresses, which is the entire point of binding one.
Production, testnet, demo, OAuth paperwork: the same two addresses answer every whitelist question Bybit asks. Running multi-venue books? Our Bitpanda static IP guide and Bitstamp guide extend the pattern to those desks.
Anyone holding Bybit API keys who wants the 90-day expiration gone without building a machine that locks them out.
Bots that place and chase orders all day cannot survive a dead key or a refused origin. Bound keys on a fixed pair keep placing orders on day 400 exactly as they did on day one.
Accounting jobs poll wallet balance endpoints on a cron and file the numbers somewhere serious. A key that quietly expires turns a nightly report into an incident, and it always expires on the worst week.
A strategy that earns its keep on demo trading or testnet graduates to production, and each surface checks a key cut for its own domain. One egress pair across the promotion path means the move changes nothing about origins.
Institutional integrations clear OAuth onboarding and the Broker Management Backend before anything else, and both want an OpenAPI Whitelist IP up front. Nominate the pair once and the paperwork matches the packets.
One environment variable routes every signed request out of your fixed EU address.
Set the variable wherever your platform runs. Bybit authenticates with headers rather than query keys, and the signature is computed on your side before the request ever reaches the proxy.
# .env, task definition, Kubernetes secret, wherever env config lives
HTTPS_PROXY=https://user:pass@eu-01.outboundgateway.com:8443
# signed read of your unified wallet, egressing from your static EU IP
curl -s "https://api.bybit.com/v5/account/wallet-balance?accountType=UNIFIED&coin=BTC" \
-H "X-BAPI-API-KEY: $BYBIT_API_KEY" \
-H "X-BAPI-TIMESTAMP: $TS" \
-H "X-BAPI-RECV-WINDOW: 5000" \
-H "X-BAPI-SIGN: $SIGN"
# $SIGN = HMAC_SHA256(secret, $TS + api_key + recv_window + query)
Bybit's own Python SDK builds the signature and headers for you, and because it rides on requests, HTTPS_PROXY from the environment is honored with no extra wiring.
import os
from pybit.unified_trading import HTTP
session = HTTP(
testnet=False, # production keys, api.bybit.com
api_key=os.environ["BYBIT_API_KEY"],
api_secret=os.environ["BYBIT_API_SECRET"],
)
wallet = session.get_wallet_balance(
accountType="UNIFIED", coin="BTC"
)
Node's built-in fetch ignores proxy env vars, so hand it undici's ProxyAgent, and sign the verified way: timestamp, then key, then recv_window, then the query string.
import { ProxyAgent } from 'undici';
import { createHmac } from 'node:crypto';
const key = process.env.BYBIT_API_KEY;
const ts = Date.now().toString(), recv = '5000';
const query = 'accountType=UNIFIED&coin=BTC';
const sign = createHmac('sha256', process.env.BYBIT_API_SECRET)
.update(ts + key + recv + query).digest('hex');
const res = await fetch('https://api.bybit.com/v5/account/wallet-balance?' + query, {
dispatcher: new ProxyAgent(process.env.HTTPS_PROXY),
headers: {
'X-BAPI-API-KEY': key,
'X-BAPI-TIMESTAMP': ts,
'X-BAPI-RECV-WINDOW': recv,
'X-BAPI-SIGN': sign,
},
});
The whitelist is configured while the key is being created, and a bound key never expires, so this checklist is the last Bybit key ceremony you repeat on a schedule.
# creating the key (website only, not the app):
# Profile -> Account & Security -> API Management
# Create New Key -> System-generated API Keys
# permissions: grant the narrowest set the bot tolerates
# select: "Only IPs with granted permissions are
# permitted to access the OpenAPI"
# enter BOTH fixed IPv4 addresses, comma-separated, no spaces
# confirm with Google Authenticator; key shown once
# brand-new account? key creation unlocks 48 hours
# after registration, plan the onboarding around it
# existing key: API Management -> edit under the
# "IP Address Added" column to add the pair later
Bind the key, cancel the countdown
Every account comes with its own pair of static EU IPv4 addresses. Enter both while the key is being created and the expiration rule never applies to it, and enter the same pair into every key that follows. Because both addresses are whitelisted, a proxy failover costs the key nothing, and the next key you cut is a paste of two addresses that have not moved.
Which traffic is covered? The proxy carries your outbound authenticated REST calls: production on api.bybit.com, testnet on api-testnet.bybit.com, demo trading on api-demo.bybit.com. Keys are domain-matched, and error 10003 is the signature of a key pointed at the wrong surface, so keep the pair whitelisted on every key you cut. Bybit.eu serves EEA traders under MiCA, though no separate EU API host appears in the official docs, so the same pair rides whichever surface you call. Nothing flows inbound: no webhook source IP list is published, so there is no third-party range to mirror on your firewall.
📖 Complete Documentation: For detailed examples, error handling, and advanced configurations, see the Python guide, the Node.js guide, or all guides.
Bybit's European arm is licensed in Austria: Bybit EU GmbH holds a CASP licence from the FMA, and Bybit Payments GmbH was granted an Electronic Money Institution licence by the same regulator for Bybit.eu, where the Bybit Card reaches the EEA. Your requests still deserve an EU origin, and that part is your call.
Bybit's docs note that IPs located in the US or Mainland China are restricted and answer with 403 Forbidden. Egress from EU data centres keeps you clear of those blocks by default and keeps one clean residency story for the order and balance data riding in your calls.
Bybit already built the locks: 2FA at creation, a secret displayed exactly once, keys matched to their domain. A key bound to your IPs is the one that keeps standing when the worst happens, because a leaked key and secret still cannot transact from servers outside the whitelist, and TLS passthrough keeps X-BAPI-SIGN sealed the whole way there.
Binding IPs is how a Bybit key earns permanence. Two fixed addresses turn that from a risk into a two-minute checkbox performed once per key.
Keys get rotated, replaced, and re-scoped forever. The addresses they are bound to never change, so each new key is the same paste and nothing else.
You compute X-BAPI-SIGN before the request leaves, and TLS passthrough carries it to Bybit untouched. The proxy relays ciphertext and nothing else.
Both addresses sit in the whitelist from day one, so a proxy node failing over is a detail your key was configured to ignore before it ever happened.
Bybit refuses US and Mainland China IPs outright. An origin in EU data centres sidesteps the block and keeps you off the wrong side of the map.
Starting from €19/month. Flexible plans for every scale. Cancel anytime.
A single environment variable points every signed Bybit call at two fixed EU addresses your keys are bound to, from the first order to the key you cut two years from now.
Starting from €19/month. Flexible plans for every scale. Cancel anytime.
Because it was created without bound IP addresses. The API FAQ is explicit: "An API key created without binding IP address(es) will expire after 90 days." The expiration is the enforcement mechanism, and binding addresses to the key is the documented way out. Give the key a pair of fixed addresses and it stops aging the moment it is created.
On the website, go to Profile, then Account & Security, then API Management, and click Create New Key. Choose System-generated API Keys, set the permissions the workload needs, and select the option reading "Only IPs with granted permissions are permitted to access the OpenAPI". Paste both fixed IPv4 addresses, separated by commas with no spaces, confirm with Google Authenticator, and store the secret; it is shown exactly once. For a key that already exists, the edit control under the "IP Address Added" column opens the same binding flow.
Yes. Submitting an OpenAPI Whitelist IP is a mandatory prerequisite during onboarding for OAuth and the Broker Management Backend, so the address question comes before the integration work, not after it. Nominate your two fixed EU IPs there, and the same pair covers everyday traffic once the integration goes live.
Tell us what your Bybit integration runs on, and we will show you exactly where the pair plugs in.
Contact Our Founders →