Back to pairl.dev

Start saving in under 5 minutes

PAIRL compresses your LLM context automatically. No SDK, no refactoring — change your base URL, keep your API keys, and watch the savings on every request.

Anthropic, OpenAI & Google supported Python, Node.js, any HTTP client Free tier, no credit card required
1

Create your account

Sign up at the PAIRL Console. Your first API key is generated automatically — copy it right away, it won't be shown again.

Create free account

Your key looks like this: pk_live_9a3f... — save it somewhere safe. You can always create additional keys under Settings.

2

Point your app at PAIRL

Change your base URL to route requests through PAIRL. Your existing provider key stays the same — PAIRL forwards it on every request and never stores it.

Python · Anthropic
# pip install anthropic
from anthropic import Anthropic

client = Anthropic(
    base_url="https://api.pairl.dev/v1/proxy/anthropic",
    api_key="sk-ant-...",             # your Anthropic key — unchanged
    default_headers={
        "Authorization": "Bearer pk_live_...",  # your PAIRL key
    }
)

# Use the client exactly as before
message = client.messages.create(
    model="claude-opus-4-20250514",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}]
)
Python · OpenAI
# pip install openai
from openai import OpenAI

client = OpenAI(
    base_url="https://api.pairl.dev/v1/proxy/openai",
    api_key="pk_live_...",              # your PAIRL key
    default_headers={
        "X-Provider-Key": "sk-...",  # your OpenAI key
    }
)

# Use the client exactly as before
response = client.chat.completions.create(
    model="gpt-5",
    messages=[{"role": "user", "content": "Hello!"}]
)
Python · Google
# pip install requests
import requests

response = requests.post(
    "https://api.pairl.dev/v1/proxy/google/v1beta/models/gemini-2.5-flash:generateContent",
    headers={
        "Authorization": "Bearer pk_live_...",  # your PAIRL key
        "X-Provider-Key": "AIza...",           # your Google API key
        "Content-Type": "application/json",
    },
    json={
        "contents": [{"role": "user", "parts": [{"text": "Hello!"}]}],
        "generationConfig": {"maxOutputTokens": 1024},
    }
)
data = response.json()
print(data["candidates"][0]["content"]["parts"][0]["text"])
Node.js · Anthropic
// npm install @anthropic-ai/sdk
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  baseURL: "https://api.pairl.dev/v1/proxy/anthropic",
  apiKey: "sk-ant-...",              // your Anthropic key — unchanged
  defaultHeaders: {
    "Authorization": "Bearer pk_live_...",  // your PAIRL key
  },
});

// Use the client exactly as before
const message = await client.messages.create({
  model: "claude-opus-4-20250514",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Hello!" }],
});
Node.js · OpenAI
// npm install openai
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.pairl.dev/v1/proxy/openai",
  apiKey: "pk_live_...",              // your PAIRL key
  defaultHeaders: {
    "X-Provider-Key": "sk-...",  // your OpenAI key
  },
});

// Use the client exactly as before
const response = await client.chat.completions.create({
  model: "gpt-5",
  messages: [{ role: "user", content: "Hello!" }],
});
Node.js · Google
// No extra package needed — uses built-in fetch
const response = await fetch(
  "https://api.pairl.dev/v1/proxy/google/v1beta/models/gemini-2.5-flash:generateContent",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer pk_live_...",  // your PAIRL key
      "X-Provider-Key": "AIza...",           // your Google API key
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      contents: [{ role: "user", parts: [{ text: "Hello!" }] }],
      generationConfig: { maxOutputTokens: 1024 },
    }),
  }
);
const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);
curl
# Anthropic
curl https://api.pairl.dev/v1/proxy/anthropic/v1/messages \
  -H "Authorization: Bearer pk_live_..." \
  -H "X-Provider-Key: sk-ant-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-opus-4-20250514",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

# Google
curl https://api.pairl.dev/v1/proxy/google/v1beta/models/gemini-2.5-flash:generateContent \
  -H "Authorization: Bearer pk_live_..." \
  -H "X-Provider-Key: AIza..." \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{"role": "user", "parts": [{"text": "Hello!"}]}],
    "generationConfig": {"maxOutputTokens": 1024}
  }'

That's it for code changes. Your existing prompts, parameters, and response handling all stay the same. PAIRL compresses the context before forwarding and returns the provider's response untouched.

Using GPT-5.6 with tools & reasoning? That combination needs OpenAI's Responses API (/v1/responses) — chat/completions rejects it. PAIRL supports it natively: keep the same base URL and call client.responses.create(...). See the Responses API notes in the docs.

3

See what you saved

Every response includes headers showing the exact savings. No guesswork — you see the numbers on each request.

Response headers
HTTP/1.1 200 OK
Content-Type: application/json

X-PAIRL-Savings-Tokens: 3840      # tokens removed from input
X-PAIRL-Savings-USD:    0.01152   # dollar value of those tokens
X-PAIRL-Fee-USD:        0.00346   # PAIRL's share (30% on Basic)
X-PAIRL-Degraded:       false     # compression worked normally

# → You saved $0.00806 net on this single request

For a full view of your savings over time, open the PAIRL Console — it shows per-request details, daily trends, and cumulative savings.

What happens behind the scenes

Your request arrives at PAIRL. The gateway analyzes your message history and compresses redundant context into a compact semantic format (PAIRL v1.6): each earlier turn is carried as word-for-word quotes of what was actually said, so nothing in the compressed history is made up. For agentic and tool-use sessions, tool-call/result chains are compressed to compact #call/#ret records — achieving up to 95% reduction for high-volume agentic workloads.

The compressed request is forwarded to your provider using your own API key. You pay your provider for the smaller token count.

The response comes back unchanged. PAIRL measures how many tokens were saved and deducts a small fee from your credit balance — only when savings actually occurred.

Use PAIRL in your own stack

PAIRL is an open specification. Encode, validate, and decode messages natively with the reference libraries — no lock-in.

TypeScript npm
$ npm install pairl
Python PyPI
$ pip install pairl
Rust crates.io
$ cargo add pairl

The gateway compresses deeper. The open libraries handle the PAIRL format itself. The hosted gateway adds advanced compression techniques of our own that go well beyond what a self-hosted implementation can reach — substantially more token savings, with the same one-line setup.

Good to know

Agentic sessions get the biggest savings

PAIRL v1.2 adds tool-use compression for Claude Code, Cursor, and similar workflows. Tool-call/result chains (which dominate agentic context) compress by ~95%, while a recency window keeps the last few interactions verbatim so the model stays in full context.

Compressed history is quoted, never invented

PAIRL v1.6 carries your earlier turns as word-for-word excerpts of the original conversation ([...] marks omitted text). Every excerpt is verified against the original and copied from it character-for-character — a summary, where one appears, is always labeled as such. See the docs.

Repeated, structured data compresses further

PAIRL v1.5 adds columnar record blocks: when many records share the same shape (evidence with claim/source/confidence, quota figures, cost lines), the keys are declared once and the values listed in rows — cutting ~40% of tokens on schema-heavy messages, losslessly. See the docs.

Short messages pass through for free

Inputs under ~50 tokens are forwarded directly — no compression, no fee. PAIRL only activates when there's meaningful context to compress.

If compression fails, you pay nothing

When the encoder can't compress a request, it's forwarded unchanged (fail-open). The response header X-PAIRL-Degraded: true tells you, and the fee is always zero.

Your keys never touch our database

PAIRL reads your provider key from the request header, forwards it to the provider, and discards it. Nothing is logged or stored.

Control compression per request

Add X-PAIRL-Mode: off to bypass compression for specific calls, or force to always compress. Default is auto — compress when profitable.

Next steps

Questions or feedback? Reach us at [email protected]