Skip to content

Response Compression

The CSMarketCap API now returns compressed responses (Brotli or gzip) when your client advertises support for it. This significantly reduces payload size and latency — especially for large analytics and price-history responses.

This is the same mechanism browsers have always used. Most HTTP clients handle it automatically and require no changes. If you're seeing unreadable / binary response bodies after this change, this page explains why and how to fix it.

TL;DR

If your responses suddenly look like binary garbage, your client asked for compression (via the Accept-Encoding header) but isn't decompressing it. Either let your HTTP client decompress automatically (see Fix 1), or opt out by sending Accept-Encoding: identity (see Fix 2).

How it works

Compression is negotiated per request and is fully backwards-compatible:

  1. Your client sends an Accept-Encoding header listing the encodings it supports, e.g. Accept-Encoding: br, gzip.
  2. If a supported encoding is offered, the API compresses the body and responds with a Content-Encoding header (br or gzip) plus Vary: Accept-Encoding.
  3. Your client reads Content-Encoding and decompresses the body before parsing it as JSON.

A few details worth knowing:

  • If you send no Accept-Encoding header (or Accept-Encoding: identity), the API returns the response uncompressed, exactly as before. Nothing breaks.
  • Small responses (under ~1 KB) are sent uncompressed even if you support compression.
  • Both Brotli (br) and gzip are offered; Brotli is preferred when available.

The catch: many HTTP libraries add Accept-Encoding for you automatically. If the library adds the header but you then read the raw response bytes (instead of letting the library decode them), you'll see compressed (binary) data. That's the source of the complaints — not a change in the data itself.

Most clients already handle this

No action is needed if you use any of these — they request and decompress transparently:

  • Browsers (fetch, XMLHttpRequest)
  • Node.jsaxios, got, node-fetch, and the built-in fetch (Node 18+)
  • Pythonrequests, httpx (gzip out of the box; Brotli once the brotli package is installed)
  • Gonet/http (transparent gzip, as long as you don't set Accept-Encoding yourself)
  • PHP — Guzzle (decode_content is on by default)
  • Our official SDK

Symptom: unreadable / binary responses

WARNING

You'll know compression is the issue if all of these are true:

  • The response body is binary / "mojibake" (e.g. starts with bytes like \x1f\x8b for gzip).
  • The response has a Content-Encoding: br or Content-Encoding: gzip header.
  • JSON.parse / .json() throws an "unexpected token" error.

It means your request advertised compression but your code didn't decode the body.

The cleanest fix is to let your HTTP client do what browsers do — decode the body according to Content-Encoding. In most cases this is the default; the examples below show the explicit, known-good setup.

bash
# --compressed makes curl advertise Accept-Encoding AND decode the response for you
curl --compressed \
  -H "api-token: YOUR_JWT_TOKEN_HERE" \
  "https://api.csmarketcap.com/api/v2/rest/min-prices?game_id=730"
js
const axios = require('axios');

// axios decompresses gzip/brotli automatically (decompress: true is the default).
const res = await axios.get(
  'https://api.csmarketcap.com/api/v2/rest/min-prices',
  {
    headers: { 'api-token': 'YOUR_JWT_TOKEN_HERE' },
    params: { game_id: 730 },
    // decompress: true, // <- default; only set it if you previously turned it off
  },
);

console.log(res.data); // already-parsed JSON
js
// Built-in fetch (Node 18+) and browser fetch decode br/gzip automatically.
const res = await fetch(
  'https://api.csmarketcap.com/api/v2/rest/min-prices?game_id=730',
  { headers: { 'api-token': 'YOUR_JWT_TOKEN_HERE' } },
);

const data = await res.json(); // decoded + parsed for you
python
import requests

# requests decodes gzip/deflate out of the box.
# For Brotli responses, install the decoder once:  pip install brotli
res = requests.get(
    'https://api.csmarketcap.com/api/v2/rest/min-prices',
    headers={'api-token': 'YOUR_JWT_TOKEN_HERE'},
    params={'game_id': 730},
)

data = res.json()  # res.text/res.json() are already decompressed
go
req, _ := http.NewRequest("GET",
    "https://api.csmarketcap.com/api/v2/rest/min-prices?game_id=730", nil)
req.Header.Set("api-token", "YOUR_JWT_TOKEN_HERE")

// Do NOT set Accept-Encoding yourself: net/http then requests gzip and
// decompresses the body transparently. (If you set it manually, you must
// decompress the body yourself.)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body) // already decompressed

Fix 2: Opt out of compression

If you can't decompress on your side (e.g. a constrained environment, or a client that only handles gzip while receiving Brotli), simply tell the API not to compress by sending Accept-Encoding: identity. You'll get the exact same uncompressed responses as before.

bash
curl -H "Accept-Encoding: identity" \
  -H "api-token: YOUR_JWT_TOKEN_HERE" \
  "https://api.csmarketcap.com/api/v2/rest/min-prices?game_id=730"
js
const res = await axios.get(url, {
  headers: {
    'api-token': 'YOUR_JWT_TOKEN_HERE',
    'Accept-Encoding': 'identity',
  },
});
python
res = requests.get(url, headers={
    'api-token': 'YOUR_JWT_TOKEN_HERE',
    'Accept-Encoding': 'identity',
})
go
req.Header.Set("Accept-Encoding", "identity")

Prefer Fix 1

Opting out trades a little bandwidth/latency for simplicity. If you can decompress (almost every modern client can), Fix 1 gives you faster, smaller responses.

Using the official SDK

If you use the CSMC SDK, there's nothing to do — it uses an HTTP client that negotiates and decompresses responses automatically.

Need help?

If you're still seeing decoding issues after trying the above, reach out with your client library and version (and a sample of the response headers) via our support team on Telegram.

Need help? Contact our support team