Documentation

Quickstart

Connect once, keep your existing SDK. Nothing here needs a code rewrite.

Want to see the effect before wiring anything up? The playground runs the same question through one model twice — raw and compressed — with no account.

Do I call CompresLM or my LLM first?

Call CompresLM only. You do not send a separate request to OpenAI/Anthropic first. CompresLM is a drop-in proxy: your app talks to https://compreslm.com/v1, we compress what we can, then we forward the request to your provider with your key. The model reply comes back through us in the same OpenAI-compatible shape.

1

Your app

Same SDK as today. Base URL → CompresLM. CompresLM token + provider key in headers.

2

CompresLM

Auth. Compress input context. If you set compress_output: true, also reduce completion tokens. Never store your provider key.

3

Your LLM provider

One upstream call on your account. You pay the provider for tokens; we bill only a share of measured savings.

4

Back to your app

Standard chat-completion JSON — choices[0].message.content, usage, tools, streaming.

We never store your prompts, completions, or provider key. We only record token counts (before/after) for your dashboard and bill — see Privacy Policy.

Create an account and a token

Sign up at /app, verify your email, then click Generate token. Copy it once — it is shown only at creation time. This token goes in the Authorization header on every request; it identifies your account, not your LLM provider.

Point your client at CompresLM

Change two things in your existing OpenAI-compatible client: the base URL (point it at CompresLM) and add one extra header carrying your own provider key. Everything else — model names you're used to, message format, streaming, tool calls — stays the same.

HeaderRequiredValue
Authorization Required Bearer YOUR_COMPRESLM_TOKEN — identifies your CompresLM account.
X-LLM-API-Key Required Your OpenAI / Anthropic / provider key. Used for this one request only, then discarded — never written to disk or logs.
X-LLM-API-Base Optional Only for a self-hosted / local model (vLLM, Ollama, etc.) — the URL of your own inference server.

Python

from openai import OpenAI

client = OpenAI(
    base_url="https://compreslm.com/v1",
    api_key="YOUR_COMPRESLM_TOKEN",
    default_headers={"X-LLM-API-Key": "YOUR_PROVIDER_KEY"},
)

resp = client.chat.completions.create(
    model="gpt-4o-mini",  # any model name your provider accepts
    messages=[{"role": "user", "content": "Summarize nothing — just say hi."}],
)
print(resp.choices[0].message.content)

cURL

curl https://compreslm.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_COMPRESLM_TOKEN" \
  -H "X-LLM-API-Key: YOUR_PROVIDER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [{"role":"user","content":"Hello"}]
  }'

JavaScript

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://compreslm.com/v1",
  apiKey: "YOUR_COMPRESLM_TOKEN",
  defaultHeaders: { "X-LLM-API-Key": "YOUR_PROVIDER_KEY" },
});

const r = await client.chat.completions.create({
  model: "gpt-4o-mini", // any model name your provider accepts
  messages: [{ role: "user", content: "Hello" }],
});

What you get back

A standard chat-completion response from your provider — same fields you already parse (choices, usage, etc.). CompresLM shortens the prompt by default. With compress_output: true it also reduces completion tokens — still a normal model answer in the usual response shape.

Choose your model

Send any model name your provider accepts — the exact string you already pass today (gpt-4o-mini, gpt-4.1, o3, claude-sonnet-4-6, claude-opus-4-1, …). There is no supported-model list to pick from: we forward the name to your provider unchanged, on your key. Compression is on by default and does not change which model answers you.

Any model name — long inputs are compressed before they reach the model, and text carrying numbers, dates, names and identifiers survives far more often than ordinary prose. That is a strong bias, not a guarantee: see Terms, section 12, and pick exact when nothing may be dropped.

Self-hosted models — add X-LLM-API-Base and prefix the name with the API flavour your server speaks, e.g. openai/my-llama-3.1-70b, so we know how to talk to it.

Turn compression off for a single request by appending -raw to one of the built-in aliases (gpt-4o-mini-raw, gpt-4o-raw, claude-sonnet-raw) — sent through byte-for-byte, useful for A/B-checking output quality. The *-smart aliases are historical synonyms of the plain names and keep working.

What to send where

This is the one idea worth five minutes. A request carries two different things, and telling them apart is what makes compression safe:

You sendWhat we do with it
The material — a contract, a report, retrieved chunks, chat history, a log a tool just returned.
Send it as context.
Scored against your question, span by span. What the answer needs stays; the rest goes.
The question — what you actually want to know.
Keep it as the last user message.
Never compressed. It is the ruler everything else is measured against.

Put both in one big user message and it still works — we fall back to reading the tail of the message as the question. But that is a guess, and a wrong guess is how compression drops something you needed. Separating them removes the guess.

The same request, both ways

# Guessing — document and question in one message
messages=[{"role": "user", "content": contract + "\n\nWhat is the notice period?"}]

# Told — the document is context, the question is the message
messages=[{"role": "user", "content": "What is the notice period?"}],
extra_body={"context": contract}

Python SDKs pass it through extra_body; in JavaScript and cURL it is just another top-level field:

curl https://compreslm.com/v1/chat/completions \
  -H "Authorization: Bearer YOUR_COMPRESLM_TOKEN" \
  -H "X-LLM-API-Key: YOUR_PROVIDER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "context": "...the contract, the report, the retrieved chunks...",
    "messages": [{"role":"user","content":"What is the termination notice period?"}]
  }'

Ask specifically. Compression reads your question to decide what matters, so "what does this say about termination, notice periods and renewal?" protects more of a contract than "summarise this". A vague question is a vague ruler.

Everything the model needs must be in the request. We fetch nothing on your behalf and remember nothing between calls — if a fact is not in context or in the messages, the model will not see it.

Shortening the answer is a separate, opt-in flag — compress_output, on the profiles page.