Last updated: 2026-06-14
All API requests use the HTTPS protocol with JSON request bodies.
Prefer https://api.crazyrouter.com/v1 by default. If you are unsure whether a client should use the root domain or /v1, check API Endpoints first.
| Header | Value | Description |
|---|
Authorization | Bearer YOUR_API_KEY | API authentication key |
Content-Type | application/json | Request body format |
| Header | Value | Description |
|---|
Accept | application/json | Response format |
Content-Encoding | gzip | Optional. Set this when the request body is gzip-compressed |
Request Example
curl https://api.crazyrouter.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-xxxxxxxx" \
-d '{
"model": "gpt-5.5",
"messages": [{"role": "user", "content": "Hello"}],
"stream": false
}'
Sending a gzip request body
If your request body is large, for example long context, long documents, or a large message history, you can gzip-compress the original JSON body before sending it.
gzip only changes the transport format. It does not change the request semantics. Crazyrouter decompresses the body before parsing the JSON.
Add these headers:
Content-Type: application/json
Content-Encoding: gzip
Content-Encoding: gzip means the request body itself is gzip-compressed. It is different from Accept-Encoding: gzip, which is usually used for response compression.
Python
import gzip
import json
import requests
payload = {
"model": "gpt-5.5",
"messages": [
{"role": "user", "content": "Put your long context or document here..."}
],
"stream": False
}
raw = json.dumps(payload, ensure_ascii=False).encode("utf-8")
compressed = gzip.compress(raw)
resp = requests.post(
"https://api.crazyrouter.com/v1/chat/completions",
headers={
"Authorization": "Bearer sk-xxxxxxxx",
"Content-Type": "application/json",
"Content-Encoding": "gzip",
},
data=compressed,
timeout=120,
)
print(resp.status_code, resp.text)
Node.js
import zlib from "node:zlib";
const payload = {
model: "gpt-5.5",
messages: [
{ role: "user", content: "Put your long context or document here..." },
],
stream: false,
};
const raw = Buffer.from(JSON.stringify(payload));
const compressed = zlib.gzipSync(raw);
const resp = await fetch("https://api.crazyrouter.com/v1/chat/completions", {
method: "POST",
headers: {
Authorization: "Bearer sk-xxxxxxxx",
"Content-Type": "application/json",
"Content-Encoding": "gzip",
},
body: compressed,
});
console.log(resp.status, await resp.text());
cURL
cat > body.json <<'JSON'
{
"model": "gpt-5.5",
"messages": [
{
"role": "user",
"content": "Put your long context or document here..."
}
],
"stream": false
}
JSON
gzip -c body.json > body.json.gz
curl https://api.crazyrouter.com/v1/chat/completions \
-H "Authorization: Bearer sk-xxxxxxxx" \
-H "Content-Type: application/json" \
-H "Content-Encoding: gzip" \
--data-binary @body.json.gz
Automatically enable gzip by body size
If your system is a workflow, you usually do not need to manually decide which business steps should use gzip. Put the decision in your shared HTTP client wrapper: serialize the JSON body first, check its byte size, and gzip only when it is above a threshold.
Recommended threshold:
body >= 128KB: enable gzip
body < 128KB: send as normal JSON
If your requests are often MB-sized, 256KB is also a reasonable threshold. Do not force gzip for very small requests, because compression overhead and gzip headers can make them larger.
Python wrapper example:
import gzip
import json
import requests
def post_json(url, payload, api_key, gzip_threshold=128 * 1024):
raw = json.dumps(payload, ensure_ascii=False).encode("utf-8")
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
}
if len(raw) >= gzip_threshold:
body = gzip.compress(raw)
headers["Content-Encoding"] = "gzip"
else:
body = raw
return requests.post(url, headers=headers, data=body, timeout=120)
Node.js wrapper example:
import zlib from "node:zlib";
async function postJson(url, payload, apiKey, gzipThreshold = 128 * 1024) {
const raw = Buffer.from(JSON.stringify(payload));
const headers = {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
};
const body =
raw.length >= gzipThreshold
? (() => {
headers["Content-Encoding"] = "gzip";
return zlib.gzipSync(raw);
})()
: raw;
return fetch(url, {
method: "POST",
headers,
body,
});
}
Use this when:
- a single request body is often larger than 1 MB
- you repeatedly upload long context or long documents
- your client can directly control the HTTP body and headers
Streaming Requests
Set stream: true to enable SSE streaming output:
curl https://api.crazyrouter.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-xxxxxxxx" \
-d '{
"model": "gpt-5.5",
"messages": [{"role": "user", "content": "Hello"}],
"stream": true
}'
Streaming responses use the Server-Sent Events (SSE) format. Each event starts with data: and the stream ends with data: [DONE].
Online Debugging
You can debug the API online using the following methods:
- Crazyrouter Playground - After signing in, visit crazyrouter.com/console/playground to test directly in your browser
- cURL - Send requests using the command-line tool
- Postman / Apifox - Use API debugging tools