SUMMA

Developer Platform

TypeScript SDK

Drive single models and multi-model debate from TypeScript — with the official openai and @anthropic-ai/sdk clients — and take full control of the panel with the summa block.

Summa is a drop-in for the OpenAI and Anthropic APIs, so the SDKs you already use just work: point the client at Summa's base URL and drop in your key. Both SDKs forward unknown request params, which means you get full summa-block control from TypeScript — pick your own panel and moderator, not just the presets.

1

Connect & install

Install whichever SDK you prefer — they both talk to Summa. Grab an API key from API Keys and pass it as apiKey (it is sent as Authorization: Bearer <API_KEY>). Never hardcode the key in committed code — read it from an env var like process.env.SUMMA_API_KEY.

Install

npm install openai
# or, to use the Anthropic client instead:
npm install @anthropic-ai/sdk
  1. Create a key on API Keys and export it: export SUMMA_API_KEY="sk-...".

  2. Set the client baseURL to the Summa endpoint — https://alpha.backend.summachat.com/api/v1 for the openai SDK, https://alpha.backend.summachat.com/api for the anthropic SDK.

  3. Change modes by changing the model string only — everything else stays the same.

2

Single mode

One fast model with full tool support (file edits, shell) — the best default for agentic coding. Use summa-fast, or any single catalog model as summa/<slug> (for example summa/openai/gpt-5).

Single — openai SDK

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://alpha.backend.summachat.com/api/v1",
  apiKey: process.env.SUMMA_API_KEY, // from /developer/keys
});

const r = await client.chat.completions.create({
  model: "summa-fast",
  messages: [{ role: "user", content: "Hello!" }],
});

console.log(r.choices[0].message.content);
3

Debate mode

Switch the model to summa-debate and a panel of models each answer, then a moderator synthesizes a single reply. It is slower and pricier than a single model — a 3-model debate costs roughly 3× a single call — and tools are accepted but not invoked in debate. Stream it to watch the panel deliberate; a non-streaming debate returns only the synthesized answer.

Debate — openai SDK, streaming

const stream = await client.chat.completions.create({
  model: "summa-debate",
  stream: true,
  messages: [{ role: "user", content: "Design a rate limiter for our API." }],
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0].delta.content ?? "");
}

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.

Switching modes is just changing the model string — the rest of your code is identical. Keep one client in a shared module and pass the mode in per call; add a summa block for a custom panel, or remove it to fall back to the model string.

One client, any mode

async function ask(model: string, prompt: string) {
  const r = await client.chat.completions.create({
    model, // "summa-fast" | "summa/openai/gpt-5" | "summa-debate" | "summa-debate-reasoning"
    messages: [{ role: "user", content: prompt }],
  });
  return r.choices[0].message.content;
}

await ask("summa-fast", "Fast single-model answer.");
await ask("summa-debate", "Now let the panel debate it.");
  • Preset panels are also just model strings: 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).

  • The anthropic SDK streams the debate as native thinking blocks — see the custom-panel section below for the anthropic client.

4

Custom panel — the summa block

To pick the exact models, add a summa block to the request body. Both SDKs forward unknown params, so TypeScript needs one line to accept the vendor extension — annotate it with // @ts-expect-error. The block overrides the model string, and works on /chat/completions, /v1/messages, and /responses.

  • panel — 2 to 8 distinct model slugs (the same ids as summa/<slug>, without the summa/ prefix).

  • moderator — optional; reads every panelist's answer and writes the single final reply. It must be one of the ids in panel; omit it and panel[0] moderates.

  • A moderator that is not in panel, or a panel with fewer than 2 or more than 8 slugs, returns 400 bad summa block.

Custom panel — openai SDK

const stream = await client.chat.completions.create({
  model: "summa-debate", // overridden by the summa block below
  stream: true,
  messages: [{ role: "user", content: "Review this migration plan." }],
  // @ts-expect-error — summa is a Summa vendor extension
  "summa": {
    "panel": ["openai/gpt-5", "anthropic/claude-sonnet-4.5"],
    "moderator": "anthropic/claude-sonnet-4.5"
  },
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0].delta.content ?? "");
}

The same block drives the @anthropic-ai/sdk client. On the Anthropic protocol each panelist's turn streams as a thinking block, then the moderator's synthesis as text.

Custom panel — anthropic SDK

import Anthropic from "@anthropic-ai/sdk";

const anthropic = new Anthropic({
  baseURL: "https://alpha.backend.summachat.com/api",
  apiKey: process.env.SUMMA_API_KEY, // sent as x-api-key too
});

const message = await anthropic.messages.create({
  model: "summa-debate",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Review this migration plan." }],
  // @ts-expect-error — summa is a Summa vendor extension
  "summa": {
    "panel": ["openai/gpt-5", "anthropic/claude-sonnet-4.5"],
    "moderator": "anthropic/claude-sonnet-4.5"
  },
});

console.log(message.content);

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 the catalog with client.models.list() (or a raw GET https://alpha.backend.summachat.com/api/v1/models). Each entry has an id and a display_name. Use any id as your model string, or — dropping the summa/ prefix — inside a panel.

List models — openai SDK

const models = await client.models.list();
for (const m of models.data) {
  console.log(m.id); // e.g. "summa/openai/gpt-5" — use as-is, or drop "summa/" in a panel
}

Search models — HTTP

curl -s "https://alpha.backend.summachat.com/api/v1/models?search=gpt&limit=50&offset=0" \
  -H "Authorization: Bearer $SUMMA_API_KEY"
# -> { "object": "list", "data": [{ "id": "...", "display_name": "..." }], "has_more": false }

Next

Browse the full catalog on Models and manage your balance on Credits. Building an agent that integrates Summa itself? Point it at https://summachat.com/llms.txt.

  • 401 — missing or invalid key. 402 — out of API credit; top up at Credits. 400 — a malformed summa block.

  • Billing is prepaid API credit: model token cost plus a 30% platform fee, so a 3-model debate costs roughly 3× a single model.