Operations
Every API key is locked to a specific set of source IPs. Requests from any other IP are rejected before a token is minted.
Every API key is locked to a specific set of source IPs. Requests from any other IP are rejected with 403 forbidden_ip before a token is minted and before any WebSocket is upgraded. We enforce this on every key we issue. It’s how we make sure a key that ends up where it shouldn’t can’t be quietly used or resold from somewhere else.
Why it’s enforced
Bearer API keys are powerful, and they’re impossible to keep perfectly secret. They end up in logs, backups, build configs, third-party integrations, and developer machines. Without an IP lock, a leaked key works from anywhere on the internet. With one, it works only from servers you control. We don’t make this opt-in because the failure mode (silently reselling or reusing a leaked key) is too costly to leave to chance.
What’s allowed
- IPv4 addresses, like
203.0.113.42 - IPv4 CIDR ranges, like
203.0.113.0/24 - IPv6 addresses, like
2001:db8::1 - IPv6 CIDR ranges, like
2001:db8::/32
What you receive on a mismatch
HTTP/1.1 403 Forbidden
Content-Type: application/json
{"error":"forbidden_ip"}
Both the token mint endpoint and the WebSocket upgrade enforce the lock. You won’t get past either without an allowed IP.
The check uses your server’s public-facing IP as seen by us. If you’re behind a corporate proxy or NAT, what counts is the external IP your traffic exits with, not the internal address your application thinks it has.
Providing your IPs
You hand us the list when your key is provisioned. To change it later, email us with the updated IPs or CIDRs. Updates take effect immediately for new mint and upgrade requests.
Cross-family behavior
An IPv4 client never matches an IPv6 CIDR and vice versa. If your servers may connect from either family (some Kubernetes clusters do), give us both ranges explicitly.
Finding your servers’ IPs
If you’re not sure what your external IP looks like:
- For a single server: run
curl https://api.ipify.orgfrom that server to see its public IP - For a load-balanced fleet: send us the egress IP range that fronts the fleet, not the individual hosts
- For serverless edge platforms calling us: the source IP is typically a shared egress pool that isn’t stable enough to lock to. Route the connection through a fixed-IP proxy or a VM with a static IP instead
When your IPs change
If your egress IPs change and we haven’t been updated, you’ll see 403 forbidden_ip on every mint attempt and your connection will not open. Email us the new list before the cutover, or right after, and retry.