SUMMA

Developer Platform

Python SDK

Drive single models and multi-model debate from the official openai or anthropic Python SDKs — just point base_url at Summa.

1

Connect & install

Summa is drop-in compatible with the SDKs you already use. Keep the openai SDK and point base_url at Summa's OpenAI-compatible endpoint, or keep the anthropic SDK and point it at the Anthropic-compatible endpoint. Your existing code barely changes.

install

pip install openai anthropic

Create an API key in API Keys, then export it so the SDK picks it up. Summa authenticates with the same Authorization: Bearer <API_KEY> header both SDKs already send.

shell

export SUMMA_API_KEY="YOUR_API_KEY"
  • OpenAI-compatible base: https://alpha.backend.summachat.com/api/v1

  • Anthropic-compatible base: https://alpha.backend.summachat.com/api (the SDK appends /v1/messages)

  • The Anthropic endpoint also accepts an x-api-key header — either works.

2

Single mode

Start with summa-fast: one fast model with full tool support (file edits, shell) — the best default for agentic coding. Everything you know about the openai SDK works unchanged.

single.py — openai SDK

from openai import OpenAI

client = OpenAI(base_url="https://alpha.backend.summachat.com/api/v1", api_key="YOUR_API_KEY")

r = client.chat.completions.create(
    model="summa-fast",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(r.choices[0].message.content)

Want a specific catalog model instead of the fast default? Pass summa/<slug> — for example model="summa/openai/gpt-5". Single models keep full tool support.

3

Debate mode

Switch model to summa-debate and a whole panel of models each answers, then a moderator synthesizes ONE answer. It's slower and pricier than a single model, but the quality on hard problems is the point. Turn on stream=True to watch the panel deliberate live.

debate_stream.py — openai SDK

from openai import OpenAI

client = OpenAI(base_url="https://alpha.backend.summachat.com/api/v1", api_key="YOUR_API_KEY")

stream = client.chat.completions.create(
    model="summa-debate",
    stream=True,
    messages=[{"role": "user", "content": "Design a rate limiter for a public API."}],
)
for chunk in stream:
    delta = chunk.choices[0].delta.content or ""
    print(delta, end="", flush=True)

You'll feel the debate. On a summa-debate request the panel streams a live transcript — a short header, then each model's turn as it finishes, then a ── Synthesized answer ── divider before the moderator's final answer streams token by token. No more staring at a frozen stream while the panel thinks.

A non-streaming debate returns the synthesized answer only — no transcript. Stream if you want to watch the panel think. Tools are accepted in debate mode but are NOT invoked.

Prefer a curated panel? Two presets ship ready to go: summa-debate-coding (Claude Sonnet 4.5 moderator + GPT-5 + Gemini 2.5 Pro) and summa-debate-reasoning (GPT-5 moderator + Claude Opus 4.1 + Gemini 2.5 Pro). Just change the model string.

Switching modes is literally one string — nothing else in your code changes:

  • Fast single model: model="summa-fast"

  • A specific catalog model: model="summa/openai/gpt-5"

  • Preset debate: model="summa-debate" (or summa-debate-coding / summa-debate-reasoning)

  • A fully custom panel: add extra_body with a summa block — it overrides model entirely.

4

Custom panel

This is where the Python SDK shines. Pass a summa block via extra_body — the openai SDK forwards it verbatim — and you get full control of exactly which models debate. The summa block OVERRIDES the model string, so model can be anything.

custom_panel.py — openai SDK

from openai import OpenAI

client = OpenAI(base_url="https://alpha.backend.summachat.com/api/v1", api_key="YOUR_API_KEY")

stream = client.chat.completions.create(
    model="summa-debate",
    stream=True,
    messages=[{"role": "user", "content": "Review this schema migration for foot-guns."}],
    extra_body={
        "summa": {
            "panel": ["openai/gpt-5", "anthropic/claude-sonnet-4.5"],
            "moderator": "anthropic/claude-sonnet-4.5"
        }
    },
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="", flush=True)

The block itself is just JSON:

the summa block

{
  "summa": {
  "panel": ["openai/gpt-5", "anthropic/claude-sonnet-4.5"],
  "moderator": "anthropic/claude-sonnet-4.5"
}
}
  • panel: 2 to 8 distinct model slugs. These are the same ids as summa/<slug> but WITHOUT the summa/ prefix.

  • moderator is optional and MUST be one of the panel slugs — it reads every panelist's turn and writes the single final answer. Omit it and panel[0] moderates by default; a moderator that isn't on the panel is a 400.

  • The same extra_body works on chat.completions and the responses endpoint too.

The anthropic SDK

Already on the anthropic SDK? Re-point base_url and pass the same summa block through extra_body. On the Anthropic protocol the debate is even richer: each panelist's turn streams as a native thinking block, then the synthesized answer streams as text.

anthropic_debate.py — anthropic SDK

import anthropic

client = anthropic.Anthropic(base_url="https://alpha.backend.summachat.com/api", api_key="YOUR_API_KEY")

with client.messages.stream(
    model="summa-debate",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Compare optimistic vs pessimistic locking."}],
    extra_body={
        "summa": {
            "panel": ["openai/gpt-5", "anthropic/claude-sonnet-4.5"],
            "moderator": "anthropic/claude-sonnet-4.5"
        }
    },
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

You'll feel the debate. On a summa-debate request each panelist's turn streams as a thinking block as it lands — you watch the models deliberate in real time — and then the moderator's synthesized answer streams as normal text. In Claude Code, press Ctrl+O to expand the live thinking.

Get models

List everything you can route to. With the openai SDK call client.models.list(); or hit GET /models directly with search, limit, and offset to filter and page.

models.py — openai SDK

from openai import OpenAI

client = OpenAI(base_url="https://alpha.backend.summachat.com/api/v1", api_key="YOUR_API_KEY")

for m in client.models.list().data:
    print(m.id)

or straight over HTTP

curl -s "https://alpha.backend.summachat.com/api/v1/models?search=gpt&limit=50&offset=0" \
  -H "Authorization: Bearer $SUMMA_API_KEY"

The response is { object: "list", data: [{ id, display_name, ... }], has_more }. Use any id as your model string. To put that model in a custom panel, drop the leading summa/ from its id.

Next

Browse everything you can route to in Models, and manage your prepaid balance in Credits. Building an agent that integrates Summa on its own? Point it at https://summachat.com/llms.txt — a machine-readable llms.txt describing every endpoint and mode.

Common errors: 401 means a missing or invalid key; 402 means you're out of API credit — top up at Credits; 400 means a bad summa block. Billing is prepaid: model token cost plus a 30% platform fee, so a 3-model debate costs roughly 3x a single model.