DeepSeek Chat Completions API: guia completo para criar chats, agents e automações

A DeepSeek Chat Completions API é a interface backend da DeepSeek para gerar respostas de chat usando o endpoint POST /chat/completions. Ela é usada por desenvolvedores para criar chatbots, copilots, automações, agents, classificadores e fluxos de extração de dados. Neste guia, você verá como chamar a API com cURL, Python e Node.js, como usar streaming, Thinking Mode, JSON Output, Tool Calls, usage, cache, tratamento de erros e boas práticas de produção. A documentação oficial define esse endpoint como responsável por criar uma resposta do modelo para uma conversa de chat.

O que é a DeepSeek Chat Completions API?

A DeepSeek Chat Completions API é uma interface de geração de texto baseada em conversa. Em vez de enviar apenas um prompt isolado, você envia um array messages, com papéis como system, user, assistant e tool. O modelo usa esse histórico para gerar a próxima resposta.

Ela é útil para:

  • chatbots de atendimento;
  • copilots internos;
  • assistentes para times de suporte, vendas e operações;
  • agents com chamadas de ferramentas;
  • classificação de texto;
  • extração estruturada de dados;
  • geração de conteúdo;
  • análise de documentos;
  • automações de produto.

É importante separar duas coisas: a DeepSeek Chat Completions API não é a interface web de chat. A API é um recurso backend. Você precisa de uma API key, envia requisições HTTP e recebe respostas em JSON ou em streaming.

Outro ponto importante é a compatibilidade. A documentação oficial diz que a DeepSeek API usa formato compatível com OpenAI e Anthropic. No formato OpenAI, o base_url é https://api.deepseek.com; no formato Anthropic, o base_url é https://api.deepseek.com/anthropic.

Isso facilita a migração. Em muitos projetos, você usa o OpenAI SDK e troca apenas três coisas: api_key, base_url e model.

Resposta rápida: como chamar POST /chat/completions

O exemplo mínimo com cURL fica assim:

curl https://api.deepseek.com/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${DEEPSEEK_API_KEY}" \
-d '{
"model": "deepseek-v4-flash",
"messages": [
{
"role": "system",
"content": "Você é um assistente técnico. Responda de forma objetiva."
},
{
"role": "user",
"content": "Explique a DeepSeek Chat Completions API em uma frase."
}
],
"thinking": { "type": "disabled" },
"max_tokens": 200,
"stream": false
}'

O que cada parte faz:

ParteFunção
https://api.deepseek.com/chat/completionsEndpoint de chat no formato OpenAI-compatible
Authorization: Bearer ${DEEPSEEK_API_KEY}Autenticação com variável de ambiente
modelModelo usado para gerar a resposta
messagesLista de mensagens da conversa
thinkingLiga ou desliga Thinking Mode
max_tokensLimita o tamanho da resposta
streamDefine resposta completa (false) ou incremental (true)

A documentação oficial mostra exemplos de chamada não-streaming e informa que stream pode ser definido como true para receber resposta em streaming.

Endpoint, base URL, autenticação e modelos atuais

ItemValor atualObservação prática
EndpointPOST /chat/completionsCria uma resposta para uma conversa de chat
Base URL OpenAI-compatiblehttps://api.deepseek.comUse com OpenAI SDK e rota /chat/completions
Base URL Anthropic-compatiblehttps://api.deepseek.com/anthropicÚtil para ferramentas e SDKs do ecossistema Anthropic
Authentication headerAuthorization: Bearer ${DEEPSEEK_API_KEY}Nunca exponha a chave no frontend
Campos obrigatóriosmodel, messagesmessages precisa ter pelo menos uma mensagem
Model IDs atuaisdeepseek-v4-flash, deepseek-v4-proSão os IDs atuais documentados para Chat Completions
Aliases legadosdeepseek-chat, deepseek-reasonerExistem por compatibilidade
Depreciaçãodeepseek-chat e deepseek-reasoner serão descontinuados em 24/07/2026Em projetos novos, prefira os IDs V4
Uso típico de deepseek-v4-flashChat rápido, FAQ, classificação, automações econômicasMelhor quando custo e velocidade são prioridades
Uso típico de deepseek-v4-proTarefas complexas, agents, raciocínio, código, planejamentoMelhor quando qualidade e raciocínio pesam mais

A página inicial da documentação lista deepseek-v4-flash e deepseek-v4-pro como modelos e informa que deepseek-chat e deepseek-reasoner serão descontinuados em 24 de julho de 2026. Ela também explica que esses aliases correspondem, por compatibilidade, aos modos non-thinking e thinking de deepseek-v4-flash.

A página de preços reforça que os modelos atuais têm contexto de 1M, máximo de output de 384K, suporte a JSON Output e Tool Calls, e que deepseek-v4-flash e deepseek-v4-pro suportam modos thinking e non-thinking.

Sobre /v1: alguns SDKs e ferramentas esperam uma URL com /v1 por convenção do ecossistema OpenAI. No entanto, os exemplos oficiais atuais da DeepSeek usam https://api.deepseek.com como base_url no SDK e chamam /chat/completions diretamente.

Estrutura do request: model, messages e papéis

O body básico tem dois campos centrais:

{
"model": "deepseek-v4-flash",
"messages": [
{
"role": "system",
"content": "Você é um assistente técnico."
},
{
"role": "user",
"content": "Como funciona a DeepSeek Chat Completions API?"
}
]
}

A referência oficial define messages como uma lista de mensagens que compõem a conversa até aquele momento, e model como o ID do modelo usado. O schema documenta os papéis system, user, assistant e tool.

RoleQuando usarExemplo curtoErro comum
systemDefinir comportamento, regras e estilo“Responda em português do Brasil.”Colocar instruções contraditórias ou longas demais
userEnviar a solicitação do usuário“Resuma este texto.”Misturar histórico antigo sem controle
assistantReenviar respostas anteriores do modelo em conversas multi-turn“Claro, aqui está…”Esquecer que isso aumenta tokens
toolDevolver ao modelo o resultado de uma ferramenta executada pela aplicaçãoResultado de get_order_statusUsar sem tool_call_id correto

Exemplo de request com parâmetros comuns:

{
"model": "deepseek-v4-flash",
"messages": [
{
"role": "system",
"content": "Você é um assistente de suporte para um SaaS B2B."
},
{
"role": "user",
"content": "Explique como redefinir minha senha."
}
],
"thinking": {
"type": "disabled"
},
"max_tokens": 300,
"temperature": 0.3,
"top_p": 1,
"stream": false
}

Para tarefas simples, como FAQ e classificação curta, normalmente faz sentido começar com Thinking Mode desativado. Para tarefas complexas, debug, raciocínio ou agentes, Thinking Mode pode ser testado com métricas de qualidade e custo.

Exemplo em Python com OpenAI SDK

Instale o SDK:

pip install openai

Exemplo production-friendly:

import os
from typing import List, Dict

from openai import OpenAI, APIError, APITimeoutError, RateLimitError


client = OpenAI(
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com",
)


def get_deepseek_answer(prompt: str) -> str:
messages: List[Dict[str, str]] = [
{
"role": "system",
"content": "Você é um assistente técnico. Responda em português do Brasil.",
},
{
"role": "user",
"content": prompt,
},
]

try:
response = client.chat.completions.create(
model=os.getenv("DEEPSEEK_MODEL", "deepseek-v4-flash"),
messages=messages,
max_tokens=500,
stream=False,
extra_body={"thinking": {"type": "disabled"}},
)

return response.choices[0].message.content or ""

except RateLimitError as exc:
raise RuntimeError("Rate limit da DeepSeek atingido. Tente novamente com backoff.") from exc

except APITimeoutError as exc:
raise RuntimeError("Timeout ao chamar a DeepSeek API.") from exc

except APIError as exc:
raise RuntimeError(f"Erro da DeepSeek API: {exc}") from exc


if __name__ == "__main__":
answer = get_deepseek_answer("O que é a DeepSeek Chat Completions API?")
print(answer)

A documentação oficial mostra o uso do OpenAI SDK com base_url="https://api.deepseek.com" e api_key carregada de DEEPSEEK_API_KEY. Para passar thinking no OpenAI SDK em Python, a própria documentação usa extra_body.

Exemplo em Node.js/TypeScript

Instale:

npm install openai

Exemplo server-side:

import OpenAI from "openai";

type ChatMessage = {
role: "system" | "user" | "assistant" | "tool";
content: string;
tool_call_id?: string;
};

const client = new OpenAI({
apiKey: process.env.DEEPSEEK_API_KEY,
baseURL: "https://api.deepseek.com",
});

export async function getDeepSeekAnswer(prompt: string): Promise<string> {
if (!process.env.DEEPSEEK_API_KEY) {
throw new Error("DEEPSEEK_API_KEY não foi definida.");
}

const messages: ChatMessage[] = [
{
role: "system",
content: "Você é um assistente técnico. Responda em português do Brasil.",
},
{
role: "user",
content: prompt,
},
];

const response = await client.chat.completions.create({
model: process.env.DEEPSEEK_MODEL ?? "deepseek-v4-flash",
messages,
max_tokens: 500,
stream: false,
thinking: { type: "disabled" },
} as any);

return response.choices[0]?.message?.content ?? "";
}

Em Node.js, o OpenAI SDK usa baseURL, não base_url. E a chamada deve acontecer no backend, não diretamente no browser. Caso contrário, a DEEPSEEK_API_KEY pode vazar para o usuário final.

Streaming com DeepSeek Chat Completions API

Streaming serve para melhorar a experiência do usuário. Em vez de esperar a resposta inteira, você recebe partes incrementais.

Na referência oficial, stream: true faz com que deltas parciais sejam enviados como Server-Sent Events, e o stream termina com data: [DONE]. A mesma referência documenta stream_options.include_usage: quando ativado, um chunk adicional chega antes de data: [DONE], com usage completo e choices vazio; os outros chunks têm usage nulo.

Streaming em Python

import os
from openai import OpenAI


client = OpenAI(
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com",
)

stream = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[
{
"role": "user",
"content": "Explique streaming na DeepSeek Chat Completions API.",
}
],
stream=True,
stream_options={"include_usage": True},
max_tokens=500,
extra_body={"thinking": {"type": "disabled"}},
)

final_usage = None

for chunk in stream:
if getattr(chunk, "usage", None) is not None:
final_usage = chunk.usage
continue

if not chunk.choices:
continue

delta = chunk.choices[0].delta
content = getattr(delta, "content", None)

if content:
print(content, end="", flush=True)

print("\n\nUsage final:", final_usage)

Streaming em Node.js/TypeScript

import OpenAI from "openai";

const client = new OpenAI({
apiKey: process.env.DEEPSEEK_API_KEY,
baseURL: "https://api.deepseek.com",
});

async function streamAnswer() {
const stream = await client.chat.completions.create({
model: "deepseek-v4-flash",
messages: [
{
role: "user",
content: "Explique streaming na DeepSeek Chat Completions API.",
},
],
stream: true,
stream_options: { include_usage: true },
max_tokens: 500,
thinking: { type: "disabled" },
} as any);

let finalUsage: unknown = null;

for await (const chunk of stream) {
if ((chunk as any).usage) {
finalUsage = (chunk as any).usage;
continue;
}

const content = chunk.choices?.[0]?.delta?.content;

if (content) {
process.stdout.write(content);
}
}

console.log("\n\nUsage final:", finalUsage);
}

streamAnswer().catch(console.error);

Não misture o chunk final de usage com o conteúdo textual. Ele serve para métricas, não para renderização.

A página de rate limit também informa que, enquanto a requisição está conectada, chamadas non-streaming podem receber linhas vazias, e chamadas streaming podem receber comentários SSE : keep-alive; quem parseia HTTP manualmente deve tratar essas linhas ou comentários.

Thinking Mode: quando ativar e quando desativar

Thinking Mode permite que o modelo gere um raciocínio antes da resposta final. A documentação oficial diz que o toggle é controlado por {"thinking": {"type": "enabled/disabled"}}, que o padrão é enabled, e que reasoning_effort aceita high ou max. Ela também informa que, em Thinking Mode, temperature, top_p, presence_penalty e frequency_penalty não têm efeito.

Exemplo:

{
"model": "deepseek-v4-pro",
"messages": [
{
"role": "user",
"content": "Analise os riscos técnicos desta arquitetura."
}
],
"thinking": {
"type": "enabled"
},
"reasoning_effort": "high",
"max_tokens": 1200
}

Na resposta, o conteúdo final vem em message.content. Quando Thinking Mode está ativo, o raciocínio pode vir em message.reasoning_content, separado de content. A documentação descreve reasoning_content como o conteúdo de raciocínio do assistant antes da resposta final.

Não trate reasoning_content como texto para exibir automaticamente ao usuário final. Em aplicações reais, ele costuma ser melhor usado para diagnóstico interno, inspeção controlada ou continuação técnica do fluxo quando a documentação exige.

Caso de usoThinking recomendado?Configuração sugeridaObservação
FAQ simplesNão, em geralthinking.type="disabled"Menor custo e menor latência
Classificação curtaNão, em geralthinking.type="disabled" + JSON OutputUse schema simples
Geração de resumoDependeComece sem thinkingAtive se a qualidade cair em textos difíceis
Debug de códigoSimthinking.type="enabled", reasoning_effort="high"Monitore tokens e latência
Planejamento multi-etapasSimthinking.type="enabled"Útil quando há dependências entre passos
Agent com Tool CallsSim, com cuidadothinking.type="enabled", loop controladoPode aumentar subchamadas e custo

Multi-turn conversations: a API é stateless

A DeepSeek /chat/completions API é stateless. A documentação oficial diz que o servidor não registra automaticamente o contexto das requisições. Portanto, a aplicação precisa concatenar o histórico anterior e enviá-lo a cada request.

Exemplo simples de duas rodadas:

import os
from openai import OpenAI


client = OpenAI(
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com",
)

messages = [
{
"role": "system",
"content": "Você responde em português do Brasil.",
},
{
"role": "user",
"content": "Qual é a principal vantagem de usar uma API stateless?",
},
]

response_1 = client.chat.completions.create(
model="deepseek-v4-flash",
messages=messages,
max_tokens=300,
extra_body={"thinking": {"type": "disabled"}},
)

assistant_message = response_1.choices[0].message
messages.append(
{
"role": "assistant",
"content": assistant_message.content or "",
}
)

messages.append(
{
"role": "user",
"content": "E qual é o principal cuidado em conversas longas?",
}
)

response_2 = client.chat.completions.create(
model="deepseek-v4-flash",
messages=messages,
max_tokens=300,
extra_body={"thinking": {"type": "disabled"}},
)

print(response_2.choices[0].message.content)

Quando não há Tool Calls em Thinking Mode, a documentação explica que o reasoning_content intermediário não precisa participar da concatenação de contexto entre duas mensagens de usuário e será ignorado se for reenviado. Mas, quando há Tool Calls em Thinking Mode, o reasoning_content do assistant precisa ser reenviado em turnos posteriores; caso contrário, a API pode retornar erro 400.

Boas práticas para multi-turn:

  • use resumo de histórico para conversas longas;
  • mantenha uma janela móvel com as últimas mensagens relevantes;
  • controle o limite de tokens por sessão;
  • use RAG para buscar contexto sob demanda;
  • não reenvie todo o histórico sem necessidade;
  • separe instruções fixas no início para favorecer cache.

JSON Output com response_format

JSON Output serve para respostas estruturadas. A documentação oficial recomenda três coisas: definir response_format como {"type": "json_object"}, incluir a palavra “json” no prompt e fornecer um exemplo do formato desejado. Ela também recomenda configurar max_tokens de forma razoável para evitar truncamento e observa que a API pode ocasionalmente retornar conteúdo vazio nesse modo.

Exemplo em Python:

import json
import os
from typing import Any, Dict

from openai import OpenAI


client = OpenAI(
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com",
)


def classify_ticket(text: str) -> Dict[str, Any]:
response = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[
{
"role": "system",
"content": (
"Você classifica tickets de suporte. "
"Responda sempre em json válido no formato: "
'{"categoria":"billing|bug|feature|account","prioridade":"low|medium|high"}'
),
},
{
"role": "user",
"content": f"Classifique este ticket em json: {text}",
},
],
response_format={"type": "json_object"},
max_tokens=150,
extra_body={"thinking": {"type": "disabled"}},
)

content = response.choices[0].message.content or "{}"
return json.loads(content)


result = classify_ticket("Minha cobrança veio duplicada este mês.")
print(result)

Request body equivalente:

{
"model": "deepseek-v4-flash",
"messages": [
{
"role": "system",
"content": "Responda sempre em json válido no formato {\"categoria\":\"billing|bug|feature|account\",\"prioridade\":\"low|medium|high\"}."
},
{
"role": "user",
"content": "Classifique este ticket em json: Minha cobrança veio duplicada."
}
],
"response_format": {
"type": "json_object"
},
"max_tokens": 150,
"thinking": {
"type": "disabled"
}
}

Checklist para JSON Output:

  • inclua a palavra json no prompt;
  • dê um exemplo do formato;
  • limite max_tokens, mas não de forma agressiva;
  • faça parse no backend;
  • valide campos obrigatórios;
  • trate conteúdo vazio;
  • trate finish_reason="length";
  • registre amostras inválidas para melhorar o prompt.

Tool Calls e function calling

Tool Calls permitem que o modelo solicite a execução de uma função externa. A aplicação executa a função, devolve o resultado como mensagem tool, e o modelo gera a resposta final. A documentação oficial deixa claro que a função precisa ser fornecida e executada pelo usuário; o modelo não executa a função sozinho.

Fluxo simplificado:

User
-> Model
-> tool_calls
-> App executa a ferramenta
-> tool message
-> Model gera a resposta final

Exemplo em Python:

import json
import os
from typing import Any, Dict

from openai import OpenAI


client = OpenAI(
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com",
)


def get_order_status(order_id: str) -> str:
fake_database = {
"A123": "enviado",
"B456": "em separação",
"C789": "cancelado",
}
return fake_database.get(order_id, "pedido não encontrado")


tools = [
{
"type": "function",
"function": {
"name": "get_order_status",
"description": "Consulta o status de um pedido pelo ID.",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "ID do pedido informado pelo usuário.",
}
},
"required": ["order_id"],
},
},
}
]


messages: list[Dict[str, Any]] = [
{
"role": "user",
"content": "Qual é o status do pedido A123?",
}
]

response = client.chat.completions.create(
model="deepseek-v4-flash",
messages=messages,
tools=tools,
tool_choice="auto",
extra_body={"thinking": {"type": "disabled"}},
)

message = response.choices[0].message
messages.append(message)

if message.tool_calls:
for tool_call in message.tool_calls:
if tool_call.function.name == "get_order_status":
args = json.loads(tool_call.function.arguments)
status = get_order_status(order_id=args["order_id"])

messages.append(
{
"role": "tool",
"tool_call_id": tool_call.id,
"content": status,
}
)

final_response = client.chat.completions.create(
model="deepseek-v4-flash",
messages=messages,
tools=tools,
extra_body={"thinking": {"type": "disabled"}},
)

print(final_response.choices[0].message.content)
else:
print(message.content)

Campos importantes:

ParâmetroFunçãoErro comum
toolsLista de funções disponíveisEnviar tools demais sem necessidade
function.nameNome da funçãoUsar nome fora do padrão permitido
function.descriptionAjuda o modelo a escolher a funçãoDescrição vaga
function.parametersJSON Schema dos argumentosSchema permissivo demais
tool_choiceControla se e como o modelo chama toolsForçar tool quando não é necessário
tool_call_idLiga o resultado da tool à chamada corretaEsquecer no retorno tool

A referência oficial também alerta que os argumentos gerados pela model em Tool Calls podem não ser JSON válido ou podem conter parâmetros não definidos; por isso, valide os argumentos antes de executar funções reais.

Strict mode

O strict mode é Beta. Segundo a documentação, ele faz o modelo aderir ao JSON Schema da função, funciona em thinking e non-thinking mode, exige base_url="https://api.deepseek.com/beta" e exige strict: true em todas as funções enviadas.

Use strict mode quando:

  • a função mexe com dados sensíveis;
  • o schema precisa ser previsível;
  • você quer reduzir erros de formato;
  • sua aplicação valida tudo antes de executar.

Campos importantes da resposta

Uma resposta non-streaming típica vem como um chat.completion com id, choices, created, model, object e usage. A referência oficial também documenta system_fingerprint, message.content, message.reasoning_content, message.tool_calls e o objeto usage.

Exemplo simplificado:

{
"id": "chatcmpl_example",
"object": "chat.completion",
"created": 1760000000,
"model": "deepseek-v4-flash",
"system_fingerprint": "fp_example",
"choices": [
{
"index": 0,
"finish_reason": "stop",
"message": {
"role": "assistant",
"content": "A DeepSeek Chat Completions API gera respostas de chat via backend.",
"reasoning_content": null,
"tool_calls": null
}
}
],
"usage": {
"prompt_tokens": 120,
"prompt_cache_hit_tokens": 80,
"prompt_cache_miss_tokens": 40,
"completion_tokens": 20,
"total_tokens": 140,
"completion_tokens_details": {
"reasoning_tokens": 0
}
}
}

finish_reason deve ser tratado com atenção:

finish_reasonO que significaO que fazer
stopO modelo parou naturalmente ou encontrou uma stop sequenceFluxo normal
lengthO limite de tokens foi atingidoAumente max_tokens ou reduza contexto
content_filterConteúdo omitido por filtroMostre fallback seguro
tool_callsO modelo chamou uma ferramentaExecute a tool e envie uma mensagem tool
insufficient_system_resourceA inferência foi interrompida por recurso insuficienteFaça retry com backoff

A referência oficial lista esses valores de finish_reason e explica o significado de cada um.

Token usage, custo e Context Caching

A cobrança da API depende de tokens. A página oficial de Token & Token Usage define tokens como unidades básicas usadas pelos modelos para representar texto e também como unidades de cobrança. Ela também reforça que o número real de tokens processados deve ser visto no resultado de usage.

Campos que você deve registrar:

CampoSignificado
prompt_tokensTokens de entrada
completion_tokensTokens gerados na resposta
total_tokensSoma de entrada e saída
prompt_cache_hit_tokensTokens de entrada que bateram no cache
prompt_cache_miss_tokensTokens de entrada que não bateram no cache
completion_tokens_details.reasoning_tokensTokens de raciocínio, quando aplicável

A referência oficial informa que prompt_tokens equivale a prompt_cache_hit_tokens + prompt_cache_miss_tokens, e que reasoning_tokens representa tokens gerados pelo modelo para raciocínio.

Preços verificados em 4 de maio de 2026. Confirme sempre a página oficial de Models & Pricing antes de produção.

ModeloInput cache hit / 1MInput cache miss / 1MOutput / 1M
deepseek-v4-flashUS$ 0.0028US$ 0.14US$ 0.28
deepseek-v4-proUS$ 0.003625US$ 0.435US$ 0.87

A página oficial informa que os preços são por 1 milhão de tokens, que a despesa é calculada como número de tokens multiplicado pelo preço, que o cache hit de input foi reduzido em 26 de abril de 2026 e que o desconto de 75% do deepseek-v4-pro foi estendido até 31 de maio de 2026.

Exemplo de cálculo simples com deepseek-v4-flash:

ComponenteTokensPreço por 1MCusto
Input cache hit20.000US$ 0.0028US$ 0.000056
Input cache miss5.000US$ 0.14US$ 0.000700
Output2.000US$ 0.28US$ 0.000560
Total27.000US$ 0.001316

Context Caching

O Context Caching da DeepSeek é ativado por padrão para todos os usuários. A documentação explica que cada request pode construir cache em disco e que requisições posteriores com prefixos sobrepostos podem reutilizar a parte em cache, gerando cache hit.

SituaçãoImpacto no cacheComo otimizar
System prompt fixoBomMantenha instruções estáveis no início
Documento longo repetidoBom após persistênciaReuse o mesmo prefixo
Pergunta variável no finalBomColoque o contexto estável antes da pergunta
Timestamp no inícioRuimMova para o final ou remova
JSON schema repetidoBomPadronize ordem e formato
Tools longasPode ajudar se forem estáveisEnvie apenas tools necessárias

A documentação também diz que cache hit depende de prefixos persistidos, que o sistema funciona em best effort e que o cache pode ser limpo automaticamente após algumas horas ou dias sem uso.

Rate limits, timeouts e retry strategy

A DeepSeek aplica limite dinâmico de concorrência conforme a carga do servidor. Ao atingir esse limite, a API retorna HTTP 429. A documentação também informa que, se uma requisição não iniciar inferência após 10 minutos, o servidor fecha a conexão.

Estratégia prática:

  1. aplique timeout client-side;
  2. use exponential backoff;
  3. adicione jitter;
  4. faça retry apenas em erros transitórios;
  5. use fila para controlar picos;
  6. registre número de retries;
  7. implemente circuit breaker em sistemas grandes;
  8. tenha fallback de UX para indisponibilidade.
CódigoCausa provávelAção recomendada
400Formato inválido do bodyCorrija payload e roles
401API key incorretaVerifique segredo e ambiente
402Saldo insuficienteVerifique billing
422Parâmetros inválidosCorrija campos conforme erro
429Rate limit/concurrency limitBackoff, fila e redução de paralelismo
500Erro internoRetry com backoff
503Servidor sobrecarregadoRetry com backoff e fallback

A página oficial de Error Codes documenta 400, 401, 402, 422, 429, 500 e 503 com causas e ações sugeridas.

Segurança da API key e arquitetura recomendada

Nunca coloque DEEPSEEK_API_KEY em código frontend, browser ou mobile app público. A arquitetura recomendada é:

Frontend -> Backend -> DeepSeek API -> Backend -> Frontend

Exemplo simples com Express:

import express from "express";
import OpenAI from "openai";

const app = express();
app.use(express.json());

const client = new OpenAI({
apiKey: process.env.DEEPSEEK_API_KEY,
baseURL: "https://api.deepseek.com",
});

app.post("/api/chat", async (req, res) => {
try {
const userMessage = String(req.body.message ?? "").slice(0, 4000);

if (!userMessage.trim()) {
return res.status(400).json({ error: "Mensagem vazia." });
}

const response = await client.chat.completions.create({
model: "deepseek-v4-flash",
messages: [
{
role: "system",
content: "Você é um assistente do produto. Responda com clareza.",
},
{
role: "user",
content: userMessage,
},
],
max_tokens: 500,
thinking: { type: "disabled" },
} as any);

res.json({
answer: response.choices[0]?.message?.content ?? "",
usage: response.usage ?? null,
});
} catch (error) {
console.error("Erro ao chamar DeepSeek API:", error);
res.status(500).json({ error: "Falha ao gerar resposta." });
}
});

app.listen(3000, () => {
console.log("Servidor rodando na porta 3000");
});

Boas práticas de segurança:

  • use variáveis de ambiente;
  • prefira secret manager em produção;
  • não grave API keys em logs;
  • aplique rate limit por usuário;
  • valide tamanho e tipo do input;
  • controle orçamento por conta;
  • registre auditoria;
  • mascare dados sensíveis;
  • separe chaves por ambiente;
  • rotacione chaves quando necessário.

Boas práticas de produção

Use este checklist antes de lançar:

  • use modelos atuais, não aliases antigos em projetos novos;
  • mantenha a API key no backend;
  • defina max_tokens;
  • escolha Thinking Mode por caso de uso;
  • use streaming para melhorar UX;
  • use include_usage para medir custos em streaming;
  • valide JSON no backend;
  • trate Tool Calls em loop seguro;
  • valide argumentos antes de executar ferramentas;
  • resuma histórico longo;
  • use Context Caching com prefixos estáveis;
  • monitore latência, tokens, custo e finish_reason;
  • implemente retry com backoff;
  • não armazene prompts sensíveis sem necessidade;
  • versione prompts;
  • adicione testes de integração;
  • registre p50, p90 e p95 de tokens;
  • monitore 429, 500 e 503 separadamente;
  • tenha fallback para indisponibilidade.

Erros comuns ao usar DeepSeek Chat Completions API

  1. Usar modelo antigo sem verificar deprecation
    Em projetos novos, prefira deepseek-v4-flash ou deepseek-v4-pro.
  2. Usar base_url em Node.js em vez de baseURL
    O OpenAI SDK em Node usa baseURL.
  3. Usar API key da OpenAI com endpoint da DeepSeek
    A chave precisa ser da plataforma DeepSeek.
  4. Expor DEEPSEEK_API_KEY no frontend
    Isso permite abuso da sua conta e consumo indevido de saldo.
  5. Esquecer que a API é stateless
    O histórico precisa ser reenviado quando for relevante.
  6. Reenviar histórico completo sem controle
    Isso aumenta tokens, custo e latência.
  7. Confundir /chat/completions com /completions
    /chat/completions é para conversa moderna; /completions é usado para FIM Completion Beta em base beta.
  8. Ativar JSON Output sem pedir JSON no prompt
    A documentação alerta que isso pode gerar whitespace até o limite de tokens.
  9. Não tratar finish_reason="length"
    A resposta pode vir truncada.
  10. Não executar Tool Calls no backend
    O modelo apenas solicita a tool. Sua aplicação executa.
  11. Achar que todos os chunks de streaming têm content
    Chunks podem ter reasoning_content, usage ou arrays vazios.
  12. Ignorar usage e custos
    Sem métricas, você não sabe qual feature está consumindo mais.
  13. Não tratar 429/503
    Sistemas de produção precisam de backoff e fallback.

Comparação rápida: Chat Completions API vs Completions API vs Anthropic API

InterfaceMelhor paraEndpoint/baseObservação
Chat Completions APIChatbots, copilots, agents, JSON, tools, streamingPOST /chat/completions com https://api.deepseek.comCaminho principal para chat moderno
Completions APIFill-in-the-middle em código/completions com base betaDocumentada como FIM Completion Beta
Anthropic APIFerramentas e SDKs do ecossistema Anthropichttps://api.deepseek.com/anthropicÚtil para Claude Code e compatibilidade Anthropic

A documentação Anthropic da DeepSeek diz que esse formato foi adicionado para atender ao ecossistema Anthropic, com base_url em https://api.deepseek.com/anthropic. Ela também mostra exemplo com o SDK anthropic usando model="deepseek-v4-pro".

FAQ sobre DeepSeek Chat Completions API

1. O que é DeepSeek Chat Completions API?

É a API backend da DeepSeek para gerar respostas de chat usando o endpoint POST /chat/completions. Ela recebe model, messages e parâmetros opcionais como stream, max_tokens, thinking, tools e response_format.

2. Qual é o endpoint da DeepSeek Chat Completions API?

O endpoint é POST /chat/completions. No formato OpenAI-compatible, use a base https://api.deepseek.com.

3. Quais campos são obrigatórios no request?

Os campos centrais obrigatórios são model e messages. A referência oficial marca ambos como required.

4. Posso usar o OpenAI SDK com DeepSeek?

Sim. A DeepSeek documenta compatibilidade com o formato OpenAI. Em Python, configure base_url="https://api.deepseek.com". Em Node.js, configure baseURL: "https://api.deepseek.com".

5. Qual modelo devo usar: deepseek-v4-flash ou deepseek-v4-pro?

Use deepseek-v4-flash para tarefas econômicas, rápidas e de alto volume. Use deepseek-v4-pro para tarefas mais complexas, agentes, raciocínio, código e análises profundas. Valide com testes de qualidade, latência e custo.

6. Ainda devo usar deepseek-chat ou deepseek-reasoner?

Em projetos novos, não é recomendado depender desses aliases. A documentação informa que deepseek-chat e deepseek-reasoner serão descontinuados em 24 de julho de 2026.

7. Como fazer streaming?

Defina stream: true. Para medir tokens no fim do streaming, use stream_options: {"include_usage": true}. O usage final chega em um chunk adicional antes de data: [DONE].

8. Como obter JSON válido?

Use response_format: {"type": "json_object"}, peça explicitamente JSON no prompt, forneça um exemplo e valide a resposta no backend.

9. Como funcionam Tool Calls?

O modelo retorna uma solicitação de função em tool_calls. A aplicação executa a função, envia o resultado como mensagem tool com tool_call_id, e depois chama o modelo novamente para gerar a resposta final.

10. A API lembra o histórico da conversa?

Não automaticamente. A API é stateless. Você precisa reenviar o histórico relevante no array messages a cada request.

11. Como medir tokens e custo?

Leia o objeto usage, especialmente prompt_tokens, completion_tokens, prompt_cache_hit_tokens, prompt_cache_miss_tokens, total_tokens e reasoning_tokens. Depois aplique os preços oficiais por 1 milhão de tokens.

12. Como proteger a API key?

Mantenha a API key no backend, use variáveis de ambiente ou secret manager, não registre a chave em logs e aplique rate limit por usuário.

Conclusão

A DeepSeek Chat Completions API é o endpoint central para criar chats, copilots, agents e automações com modelos DeepSeek. O fluxo básico é simples: envie model e messages para POST /chat/completions, usando o formato OpenAI-compatible quando quiser aproveitar SDKs existentes.

Para produção, o diferencial está nos detalhes: escolher o modelo atual correto, controlar Thinking Mode, usar streaming para UX, ativar include_usage para custo, validar JSON, executar Tool Calls com segurança, resumir histórico, aproveitar Context Caching e tratar erros como 429, 500 e 503.

Comece com um endpoint backend simples, registre usage desde o primeiro dia e só depois adicione streaming, Tool Calls e Thinking Mode conforme a necessidade real do produto.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *