Surfaces
The gateway
Your gateway host: four wire formats, model resolution, and the only path that moves money.
Each application gets its own gateway host (https://<slug>.gw.ourseams.com). Seams runs it; your clients call it. It authenticates the key, checks the bundle, resolves your model name (and any router behind it), meters and holds the money, calls the provider, settles the actual cost, and writes the usage row. The console and portal read from that record.
seams gateway show
# url https://<app>.gw.ourseams.com/v1
# status healthy
# p50 ms 612
# protocols openai.chat, openai.responses, anthropic.messages, google.generate
# models fast, smart, cheapYour client does not change
Point an existing OpenAI, Anthropic, or Gemini client at your gateway host and give it an end user's ak_ instead of your provider key. Same SDKs, two lines, and no Seams package on the inference call. Full non-streaming, streaming, curl, and cross-protocol examples live on Calling the gateway.
import OpenAI from "openai"
import Anthropic from "@anthropic-ai/sdk"
import { GoogleGenAI } from "@google/genai"
new OpenAI({ baseURL: "https://<app>.gw.ourseams.com/v1", apiKey: endUserKey })
new Anthropic({ baseURL: "https://<app>.gw.ourseams.com", apiKey: endUserKey })
new GoogleGenAI({
apiKey: endUserKey,
httpOptions: { baseUrl: "https://<app>.gw.ourseams.com" },
})Anything built on those SDKs works the same way. Vercel’s ai-sdk needs no provider package from us; createOpenAI (or the Anthropic / Google helpers) takes the base URL, and streamText behaves as it always did.
import { createOpenAI } from "@ai-sdk/openai"
import { streamText } from "ai"
const seams = createOpenAI({
baseURL: "https://<app>.gw.ourseams.com/v1",
apiKey: endUserKey,
})
const result = streamText({
model: seams("acme/fast"),
prompt: "Outline the plan",
})The model name is yours, not the provider’s. acme/fast resolves through the bundle the key belongs to, so changing what serves it needs no redeploy for your callers. The inbound wire can differ from the model provider that answers; that is cross-protocol routing.
Protocols
| Id | Speaks |
|---|---|
openai.chat | /v1/chat/completions, the default most clients use |
openai.responses | /v1/responses, tools and images on the OpenAI wire |
anthropic.messages | /v1/messages |
google.generate | generateContent and its streaming form |
Any of them can reach any model provider you have connected, which is what lets a customer keep their client while you change what serves it. Where a pivot cannot be lossless it is listed, not glossed over.
seams gateway set --protocols openai.chat,anthropic.messages,google.generateNarrowing the protocol list is a real reduction in what the base URL answers. A call in a protocol you have turned off is refused at the edge rather than translated.
What it will not do
The gateway has no route that stores a prompt or a completion, and the log record has no field able to hold one. It answers text and agent traffic; embeddings, images and audio are not served here.
Inference goes through the gateway. Administration goes through the API and the console. Keeping the two apart is why a hung billing call cannot slow down a customer's request.