Referência da API
O SUB&SUB expõe um relay multi-provedor em https://api.subnsub.com/v1. Clientes OpenAI acessam /v1/chat/completions; clientes Anthropic acessam /v1/messages. A mesma chave sk-cf-... roteia ambos — escolha o modelo no corpo da requisição e o relay escolhe o upstream.
Início rápido
Três coisas de que você precisa:
- Base URL:
https://api.subnsub.com/v1(clientes OpenAI) ouhttps://api.subnsub.com(clientes Anthropic — o SDK acrescenta/v1/messagespor conta própria) - Chave API:
sk-cf-...emitida no console - Modelo: um dos 21 modelos verificados — ex.:
gpt-5.4-miniouclaude-haiku-4.5
Autenticação
Toda requisição deve carregar um cabeçalho Authorization: Bearer sk-cf-.... As chaves são emitidas no console e armazenadas como hashes SHA-256 — assim que você sai da tela de criação, o texto plano se perde para sempre, então salve-o imediatamente.
Endpoints
POST /v1/chat/completions
Envie uma requisição de chat completion. O formato da requisição corresponde à API OpenAI Chat Completions — os SDKs da OpenAI funcionam sem modificações.
| Parâmetro | Tipo | Descrição |
|---|---|---|
| model | string | Um dos IDs de modelo verificados. |
| messages | array | Histórico da conversa. Cada item: {role, content} com role ∈ system / user / assistant. |
| stream | boolean | Se true, a resposta é enviada como chunks SSE. Veja Streaming. |
| stream_options | object | Opcional. O relay sempre força {include_usage: true} no upstream para que o chunk final carregue o bloco de uso de tokens — sobrescrevê-lo não tem efeito. |
| max_tokens | integer | Limita o tamanho da completion. O padrão é o máximo do modelo. |
| temperature | number | 0 – 2. Maior = mais aleatório. |
POST /v1/messages
Endpoint nativo da Anthropic para os modelos claude-* — o SDK da Anthropic (anthropic-sdk-python, @anthropic-ai/sdk, claude-code) funciona sem modificações contra este caminho. Aponte sua base URL para https://api.subnsub.com e autentique pelo cabeçalho x-api-key (a forma Authorization-Bearer também funciona, se o seu cliente preferir).
| Parâmetro | Tipo | Descrição |
|---|---|---|
| model | string | Um ID de modelo claude-* (veja Modelos disponíveis). Passar um modelo OpenAI aqui retorna 400 invalid_request_error. |
| max_tokens | integer | Obrigatório pela Anthropic — limita o tamanho da resposta do assistente. |
| messages | array | Histórico da conversa, formato Anthropic: {role, content} com role ∈ user / assistant. |
| stream | boolean | Se true, retorna a sequência padrão de eventos SSE da Anthropic: message_start, content_block_delta, message_delta, message_stop. |
| thinking | object | Encaminhado tal e qual. Combine com uma variante de modelo -thinking para habilitar o extended thinking. |
| cache_control | object | O prompt-caching é suportado. Tokens de escrita em cache são cobrados a 1.25× e tokens de leitura em cache a 0.10× da tarifa de entrada do tier. |
GET /v1/models
Lista os modelos que você pode de fato chamar. O relay mescla os catálogos OpenAI e Anthropic do sub2api e filtra para os 21 que testamos de ponta a ponta contra o pool de contas atual — IDs fantasma que dão 503 no momento do roteamento, ou 400 de upstream no primeiro token, ficam ocultos. Se todo upstream configurado estiver inacessível, o endpoint retorna 502 models_unreachable em vez de uma lista vazia enganosa.
# sample response (truncated)
{
"object": "list",
"data": [
{ "id": "gpt-5.4-mini", "type": "model", ... },
{ "id": "gpt-5.4", "type": "model", ... },
{ "id": "claude-sonnet-4.5", "type": "model", ... },
{ "id": "claude-haiku-4.5", "type": "model", ... },
...
]
}
Modelos disponíveis
Duas famílias de upstream. Os 7 modelos OpenAI roteiam para contas compartilhadas de nível ChatGPT; os 14 modelos Claude roteiam por um proxy reverso Kiro até o AWS CodeWhisperer. As tarifas por token dependem do tier (veja Preços) — a mesma chave funciona para ambos.
OpenAI
| ID do modelo | Família | Tier | Notas |
|---|---|---|---|
| gpt-5.4-mini | GPT-5.4 | Mini | Rápido & barato. Padrão recomendado para chat & programação. |
| gpt-5.3-codex | Codex | Mini | 5.3 ajustado para programação. Mesmo preço do mini. |
| gpt-5.2 | GPT-5.2 | Standard | 5.2 estável. |
| gpt-5.2-chat-latest | GPT-5.2 | Standard | Acompanha automaticamente o ajuste de chat mais recente do 5.2 (atualmente mapeia para gpt-5.2 no upstream). |
| gpt-5.4 | GPT-5.4 | Standard | GPT-5.4 completo — mais lento, raciocínio mais forte. |
| gpt-5.4-2026-03-05 | GPT-5.4 | Standard | Snapshot datado do gpt-5.4. |
| gpt-5.5 | GPT-5.5 | Premium | Flagship mais recente. |
Anthropic
| ID do modelo | Família | Tier | Notas |
|---|---|---|---|
| claude-haiku-4.5 | Haiku 4.5 | Mini | O menor Claude — mesma tarifa por token do gpt-5.4-mini. |
| claude-haiku-4.5-thinking | Haiku 4.5 | Mini | Variante de extended-thinking do haiku-4.5. Combine com o campo de requisição thinking. |
| claude-sonnet-4.5 | Sonnet 4.5 | Standard | Claude de nível intermediário — mesma tarifa por token do gpt-5.4. |
| claude-sonnet-4.5-thinking | Sonnet 4.5 | Standard | Variante de extended-thinking do sonnet-4.5. |
| claude-sonnet-4.6 | Sonnet 4.6 | Standard | Ajuste mais recente do Sonnet — tier Standard, mesma tarifa do sonnet-4.5. |
| claude-sonnet-4.6-thinking | Sonnet 4.6 | Standard | Variante de extended-thinking do sonnet-4.6. |
| claude-opus-4.5 | Opus 4.5 | Ultra | Claude de fronteira. Cobrado ao preço de lista da Anthropic — sem margem (veja Preços). |
| claude-opus-4.5-thinking | Opus 4.5 | Ultra | Variante de extended-thinking do opus-4.5 (thinking adaptativo). |
| claude-opus-4.6 | Opus 4.6 | Ultra | Ajuste mais recente do Opus. |
| claude-opus-4.6-thinking | Opus 4.6 | Ultra | Variante de extended-thinking do opus-4.6. |
| claude-opus-4.7 | Opus 4.7 | Ultra | Snapshot anterior do Opus. |
| claude-opus-4.7-thinking | Opus 4.7 | Ultra | Variante de extended-thinking do opus-4.7. |
| claude-opus-4.8 | Opus 4.8 | Ultra | Snapshot mais recente do Opus. |
| claude-opus-4.8-thinking | Opus 4.8 | Ultra | Variante de extended-thinking do opus-4.8. |
gpt-5.2-pro, gpt-5.2-pro-2025-12-11), gpt-4o, gpt-4o-mini, gpt-5, gpt-5-mini, variantes de imagem / áudio / realtime, claude-haiku-4-6 e IDs de upstream datados (ex.: claude-sonnet-4-5-20250929). Chamá-los retorna 400 model_not_available. Os modelos Pro estão fora do cardápio porque as contas de nível social subjacentes no pool esgotariam suas cotas minúsculas em um punhado de requisições.
Esforço de raciocínio
Cada modelo OpenAI acima é um modelo de raciocínio — o backend pode gastar mais ou menos tokens de "pensamento" antes de emitir a saída visível. Defina reasoning_effort no corpo da requisição OpenAI /v1/chat/completions para controlar o orçamento. Para o Claude, use o campo de requisição nativo da Anthropic thinking (ou escolha uma variante de modelo -thinking) — veja a seção /v1/messages. Os modelos OpenAI aceitam os mesmos cinco valores de esforço:
| Valor | Comportamento |
|---|---|
| none | Sem pensamento — direto para a resposta. O mais barato e rápido. |
| low | Uma passagem curta de raciocínio. |
| medium | Padrão se você não passar o campo. Equilibrado. |
| high | Raciocínio mais profundo. Recomendado para programação não trivial / problemas com múltiplas etapas. |
| xhigh | Esforço máximo. O mais lento e caro; reserve para análises difíceis em que você realmente precise dele. |
# Two equivalent forms — pick whichever your SDK supports
{
"model": "gpt-5.4-mini",
"reasoning_effort": "high",
"messages": [ ... ]
}
{
"model": "gpt-5.5",
"reasoning": { "effort": "xhigh" },
"messages": [ ... ]
}
'minimal', mas os modelos do nosso pool o rejeitam: "'minimal' is not supported with this model". Atenha-se aos cinco valores acima.
Streaming
Defina "stream": true para receber Server-Sent Events. O chunk final carrega um bloco usage (forçamos stream_options.include_usage no upstream para que as contagens de tokens sejam sempre emitidas), e então um literal data: [DONE] encerra o stream.
# Streaming format (line by line)
data: {"id":"resp_...","choices":[{"delta":{"content":"Hi"}}]}
data: {"id":"resp_...","choices":[{"delta":{"content":"!"}}]}
data: {"id":"resp_...","choices":[],"usage":{"prompt_tokens":18,"completion_tokens":11,"total_tokens":29}}
data: [DONE]
Busca na web
Acrescente :online a qualquer ID de modelo suportado pelo endpoint e o relay executará uma busca na web antes de encaminhar ao modelo, prefixando os resultados na conversa para que a resposta se baseie em dados frescos. O sufixo funciona em /v1/chat/completions e /v1/messages (este último ainda exige uma base claude-*); nenhum campo de requisição específico de busca é necessário.
# Same call as before — just :online on the model
curl https://api.subnsub.com/v1/chat/completions \
-H "Authorization: Bearer sk-cf-xxx" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.4-mini:online",
"messages": [
{"role": "user", "content": "What did Anthropic ship this week?"}
]
}'
Como funciona: o relay remove o :online, toma a mensagem de usuário mais recente como consulta (limitada a 400 caracteres), chama o Tavily para até 3 resultados com o texto da página extraído quando disponível, mais um resumo opcional gerado pelo Tavily, e então os prefixa nesse mesmo turno do usuário como um bloco <search_results> claramente delimitado antes de enviar a requisição ao upstream. A chamada de busca tem um timeout de 8 segundos. Os resultados são deliberadamente injetados no papel de usuário — nunca no system prompt — para que trechos não confiáveis não possam ser elevados a instruções de prioridade de sistema.
O bloco <search_results> tem esta aparência. Ele é precedido por uma instrução de uma linha dizendo ao modelo para tratar o bloco como dados externos não confiáveis e citar os itens numerados em linha:
<search_results query="What did Anthropic ship this week?" retrieved="2026-05-21">
Summary: <short LLM-generated synthesis of the result set>
[1] Anthropic launches Opus 4.8
URL: https://www.anthropic.com/news/opus-4-8
<extracted page text, or short snippet if extraction failed — up to ~2000 chars>
[2] ...
</search_results>
| Comportamento | Detalhe |
|---|---|
| Custo | Sem sobretaxa hoje — você paga a tarifa por token normal do modelo; o relay absorve a chamada de busca. O bloco <search_results> injetado conta como tokens de entrada, então espere uma conta de tokens de prompt mais alta do que a mesma pergunta sem :online. |
| Modo de falha | Suave. Se o Tavily der timeout ou erro, a requisição continua para o modelo sem contexto de busca (você ainda recebe uma resposta, apenas sem embasamento). A única falha grave é 503 search_unavailable quando a busca não está configurada no relay de jeito nenhum. |
| count_tokens | /v1/messages/count_tokens remove o sufixo mas nunca chama o Tavily — a contagem reflete o seu prompt original, não o aumentado. |
| Multi-turno | Apenas o último turno do usuário é consultado & aumentado; turnos anteriores ficam intocados. Para buscar de novo, envie uma nova mensagem de usuário com :online ainda no modelo. |
Quando usar :online
O relay faz uma única chamada ao Tavily por requisição e injeta os resultados — não é um loop de busca agêntico. O modelo não decide buscar de novo com base no que vê, do jeito que o Perplexity Sonar ou a ferramenta de navegação do ChatGPT fazem. Planeje considerando essa limitação:
| Boa escolha | Má escolha |
|---|---|
| Fatos sensíveis ao tempo (notícias, preços, números de versão, datas de lançamento) | Código privado ou colado que não está na web pública — adiciona ruído ao prompt sem embasamento |
| Localizar um documento ou anúncio oficial | Matemática, raciocínio, tradução, escrita criativa — nada a embasar |
| Qualquer coisa que você de outra forma verificaria pesquisando no Google | Conhecimento estável já presente nos dados de treinamento ("o que é uma árvore binária") |
Formule a última mensagem de usuário como uma consulta de busca autônoma. A busca é executada contra o texto literal do seu turno de usuário mais recente (limitado a 400 caracteres), então perguntas conversacionais de acompanhamento como "e quanto à versão mais recente?" viram consultas inúteis sem contexto. Em um chat multi-turno, reformule o tópico ao adicionar :online — ex.: "versão mais recente do SDK Python da Anthropic" em vez de "a mais recente".
Para perguntas que precisam de síntese em múltiplas etapas (comparar e contrastar, pesquisa aprofundada), divida-as em vários turnos e adicione :online a cada um. O modelo lerá os resultados frescos de cada turno; você direciona a próxima consulta manualmente. Observe que o bloco <search_results> injetado é enviado apenas ao upstream — não é devolvido ao seu cliente nem preservado na próxima requisição, então se um turno posterior depender de detalhes de fontes anteriores, peça ao modelo para resumi-los na sua resposta visível. O modo de pesquisa em uma única tacada não é suportado.
reasoning_effort: "high") para que o modelo realmente pondere as fontes retornadas em vez de se apoiar no primeiro resultado. A instrução injetada pede ao modelo que cite as fontes numeradas como [1], [2] em linha, então a saída geralmente trará tais citações — embora o modelo não esteja estritamente vinculado a esse formato.
Erros
O envelope depende de qual endpoint você chamou — o relay retorna erros no protocolo que corresponde ao SDK do chamador, e os erros de upstream são repassados tal e qual.
Caminhos OpenAI (/v1/chat/completions, /v1/responses, /v1/models) — envelope OpenAI:
{ "error": { "message": "...", "type": "...", "code": "..." } }
Caminhos Anthropic (/v1/messages, /v1/messages/count_tokens) — envelope Anthropic:
{ "type": "error", "error": { "type": "...", "message": "..." } }
O envelope Anthropic usa um formato diferente — sem o campo code, e o discriminador type: "error" fica no nível superior (com o error.type interno informando a categoria, ex.: authentication_error, invalid_request_error, permission_error, api_error). Os SDKs da Anthropic já analisam esse formato; os tratadores de erro do SDK OpenAI puro não, então chame /v1/messages com um SDK da Anthropic (ou faça HTTP cru).
Os códigos de status são os HTTP canônicos em ambos os protocolos:
| Status | OpenAI code / Anthropic error.type | Significado |
|---|---|---|
| 401 | invalid_api_key / authentication_error | Chave sk-cf-... ausente ou desconhecida. |
| 402 | insufficient_balance / permission_error | O saldo da conta está negativo. Recarregue na aba de cobrança do console. |
| 403 | key_revoked / permission_error | A chave foi revogada. |
| 400 | model_not_available / invalid_request_error | O model que você enviou não está no catálogo verificado, ou está errado para o endpoint (ex.: um modelo OpenAI em /v1/messages) — confira Modelos disponíveis. |
| 503 | — | Nenhuma conta de upstream atende a requisição no momento — geralmente uma janela de rate-limit que afeta todo o pool, não um problema de configuração. |
| 503 | search_unavailable / api_error | Você usou :online mas a busca na web não está configurada neste relay. Veja Busca na web. |
| 502 | upstream_unreachable / api_error | O relay não conseguiu alcançar o backend. Tente novamente após um curto backoff. |
Preços e cobrança
Pague pelo uso, cobrado por token em microdólares (1 micro = $0.000001 = 1/10,000 de um centavo) para que requisições abaixo de um centavo sejam rastreadas com precisão. As tarifas são por 1M tokens, por tier — veja a tabela de modelos para qual tier cada modelo mapeia.
| Tier | Modelos | Entrada / 1M | Saída / 1M |
|---|---|---|---|
| Mini | gpt-5.4-mini, gpt-5.3-codex, claude-haiku-4.5, claude-haiku-4.5-thinking | $0.20 | $1.60 |
| Standard | gpt-5.2, gpt-5.2-chat-latest, gpt-5.4, gpt-5.4-2026-03-05, claude-sonnet-4.5, claude-sonnet-4.5-thinking, claude-sonnet-4.6, claude-sonnet-4.6-thinking | $0.75 | $6.00 |
| Premium | gpt-5.5 | $1.10 | $8.80 |
| Ultra | claude-opus-4.5, claude-opus-4.5-thinking, claude-opus-4.6, claude-opus-4.6-thinking, claude-opus-4.7, claude-opus-4.7-thinking, claude-opus-4.8, claude-opus-4.8-thinking | $5.00 | $25.00 |
As tarifas do tier Ultra correspondem ao preço de lista do Opus publicado pela Anthropic — repasse direto, sem margem. Os outros tiers operam abaixo de suas tarifas de upstream graças ao respaldo da assinatura compartilhada.
Os tokens de raciocínio (quando você define reasoning_effort na OpenAI, ou usa uma variante -thinking do Claude) contam como tokens de saída à tarifa do tier do modelo — não há sobretaxa separada para esforço alto, mas uma requisição de pensamento profundo pode facilmente emitir 10–50× mais tokens de saída do que uma sem esforço, então a conta em dólares escala junto.
O prompt-caching da Anthropic é cobrado como um item separado: escritas em cache a 1.25× e leituras em cache a 0.10× da tarifa de entrada do tier. Então um cache hit do haiku-4.5 custa 0.20 × 0.10 = $0.02 per 1M tokens, e um cache hit do sonnet-4.5 custa 0.75 × 0.10 = $0.075 per 1M tokens. As colunas de cache são registradas em cada linha de liquidação para que o console possa mostrar o detalhamento.
O saldo é descontado em tempo real conforme cada requisição retorna — para requisições em streaming, a liquidação ocorre depois que o chunk [DONE] chega. Veja seu saldo ao vivo e as liquidações por requisição em /console#billing.
Limites de taxa
Sem limites de taxa por chave hoje. Aplicam-se a concorrência do pool de contas de upstream & o throttling do lado do servidor da OpenAI; se você esbarrar neles, o relay retorna 429 com um cabeçalho retry-after. Limites de RPM / TPM por chave chegarão pós-MVP.