QuotaGuard and Bloomberg Data License API Integration Guide
QuotaGuard Static IPs let your cloud app reach the Bloomberg Data License Hypermedia API (HAPI) from two fixed addresses you register once in the Bloomberg Enterprise Console. Route both the OAuth token call and your data calls through the proxy, and every request to Bloomberg arrives from one of your two static IPs regardless of how your platform rotates underneath.
Scope: This guide is for the Data License Hypermedia API, the REST interface at api.bloomberg.com/eap. It does not apply to the Bloomberg Terminal, the Desktop API, the Server API (SAPI), or the B-PIPE market data feed. Those run over Bloomberg’s own network, appliances, or dedicated connectivity, and an outbound proxy does not apply to them.
Inbound and EU residency: This page covers the outbound integration. For inbound static IPs and EU data residency options, see the Bloomberg Data License integration page.
The Bloomberg Data License API Rejects Non-Allowlisted IPs
The Hypermedia API enforces a customer-controlled IP allowlist. Every request must originate from an IP registered in your Bloomberg Enterprise Console, under the Web API Connectivity Policy for your Web API application. There are two failure signatures:
- A
401whose detail states the IP is not whitelisted. - On the OAuth host, a connection that completes the TLS handshake and is then closed before any HTTP response. Your client reports a dropped socket with no status code, which looks like a network bug rather than an access decision.
Cloud platforms like Replit, Vercel, and AWS Lambda assign a rotating outbound IP, so even after you register an address, your next request leaves from a different one and gets rejected. The fix is two IPs that stay on the list.
Getting Started
After creating a QuotaGuard account, you are redirected to your dashboard, where you can find your proxy credentials and two static IP addresses.
Choose the right proxy region: Select the QuotaGuard region closest to where your application runs. The region is set at sign-up. Changes after sign-up require contacting support.
Keep your proxy URL and Bloomberg credentials in environment variables:
QUOTAGUARDSTATIC_URL="http://username:password@<your-quotaguard-proxy-host>:9293"
BLOOMBERG_CLIENT_ID="from-your-bloomberg-credential-file"
BLOOMBERG_CLIENT_SECRET="from-your-bloomberg-credential-file"
Register Your Two IPs in Bloomberg Enterprise Console
In the Enterprise Console, open the Web API Connectivity Policy for your Web API application and add both QuotaGuard IP addresses to the authorized set. Two details cause the TLS-accept-then-close failure if you get them wrong:
- Register both addresses. QuotaGuard load-balances across the pair, and either can serve a given request.
- Attach them to the correct application and catalog. An IP registered against the wrong application still fails.
Route the OAuth Token Request Through the Proxy
The API uses OAuth 2.0 client credentials. You exchange your Bloomberg-issued credentials for a short-lived JWT bearer token at bsso.blpprofessional.com, then send that token with every data request. Both calls must leave from your static IPs.
Python (requests)
import os, requests
proxies = {
"http": os.environ["QUOTAGUARDSTATIC_URL"],
"https": os.environ["QUOTAGUARDSTATIC_URL"],
}
token = requests.post(
"https://bsso.blpprofessional.com/ext/api/as/token.oauth2",
data={
"grant_type": "client_credentials",
"client_id": os.environ["BLOOMBERG_CLIENT_ID"],
"client_secret": os.environ["BLOOMBERG_CLIENT_SECRET"],
},
proxies=proxies,
).json()["access_token"]
Node.js (undici)
import { ProxyAgent, fetch } from 'undici';
const dispatcher = new ProxyAgent(process.env.QUOTAGUARDSTATIC_URL);
const res = await fetch('https://bsso.blpprofessional.com/ext/api/as/token.oauth2', {
method: 'POST',
dispatcher,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'client_credentials',
client_id: process.env.BLOOMBERG_CLIENT_ID,
client_secret: process.env.BLOOMBERG_CLIENT_SECRET,
}),
});
const { access_token } = await res.json();
On Bun (common on Replit), fetch accepts a per-request proxy option directly: fetch(url, { proxy: process.env.QUOTAGUARDSTATIC_URL, ... }).
Go
proxyURL, _ := url.Parse(os.Getenv("QUOTAGUARDSTATIC_URL"))
client := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)}}
form := url.Values{}
form.Set("grant_type", "client_credentials")
form.Set("client_id", os.Getenv("BLOOMBERG_CLIENT_ID"))
form.Set("client_secret", os.Getenv("BLOOMBERG_CLIENT_SECRET"))
resp, _ := client.PostForm("https://bsso.blpprofessional.com/ext/api/as/token.oauth2", form)
defer resp.Body.Close()
Route the Data Requests Through the Proxy
With a token, call the Hypermedia API at api.bloomberg.com/eap. The catalog endpoint is the usual first authenticated call and confirms both your token and your IP registration before you build a full data request.
catalogs = requests.get(
"https://api.bloomberg.com/eap/catalogs/",
headers={"Authorization": f"Bearer {token}", "Accept": "application/json"},
proxies=proxies,
)
print(catalogs.status_code)
From there the Hypermedia API follows Bloomberg’s request-response model: create a data request describing the universe, fields, and trigger, then retrieve the output when ready. Those calls all run against api.bloomberg.com/eap and all go through the proxy. Bloomberg’s developer documentation covers the request workflow. QuotaGuard only changes the IP your requests come from.
Testing Your Integration Is Using the Static IP
curl -x "$QUOTAGUARDSTATIC_URL" https://ip.quotaguard.com
Expected response:
{"ip":"<one of your two QuotaGuard static IPs>"}
The returned IP must be one of the two static IPs in your QuotaGuard dashboard, and both must be registered in the Enterprise Console. Run it more than once to confirm both (load-balanced).
Troubleshooting
401 with an IP not whitelisted
Copy the IP from the error and confirm it is one of your two QuotaGuard addresses, registered against the correct application and catalog.
OAuth call drops the socket with no status code
The classic signature of an IP that is not on the list or is registered to the wrong application. Bloomberg accepts the TLS handshake and then closes the connection. Re-check that both addresses are active in the Web API Connectivity Policy for the correct application.
407 Proxy Authentication Required
This is the QuotaGuard proxy, not Bloomberg. Your QUOTAGUARDSTATIC_URL credentials are wrong. Confirm them against your dashboard.
Half your requests fail
You registered only one of the two IPs. The load balancer routes through both, so register both.
QuotaGuard Static vs QuotaGuard Shield
| Feature | QuotaGuard Static | QuotaGuard Shield |
|---|---|---|
| Protocol | HTTP / HTTPS / SOCKS5 | HTTPS / SOCKS5 over TLS |
| Customer-to-proxy hop | Plaintext (proxy credential sent in the clear) | TLS-encrypted |
| HTTPS payload | Tunneled end-to-end, never decrypted at the proxy | Tunneled end-to-end, never decrypted at the proxy |
| Best for | Most apps | Regulated data or environments that require TLS on every hop |
| Starting price | $19/month | $29/month |
For Bloomberg Data License, Static is the right product. The proxy sees only host and port, and your Bloomberg payload stays in the end-to-end TLS session. The one thing Static does not encrypt is the proxy-auth credential on the first hop. Choose QuotaGuard Shield when your security review requires that first hop encrypted as well. Shield gives you the same two static IPs and solves the allowlist identically.
Ready to Get Started?
Get in touch or create a free trial account.
View Bloomberg Data License Integration Features
Read: How to Get a Static IP for the Bloomberg Data License API