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:
| Parte | Função |
|---|---|
https://api.deepseek.com/chat/completions | Endpoint de chat no formato OpenAI-compatible |
Authorization: Bearer ${DEEPSEEK_API_KEY} | Autenticação com variável de ambiente |
model | Modelo usado para gerar a resposta |
messages | Lista de mensagens da conversa |
thinking | Liga ou desliga Thinking Mode |
max_tokens | Limita o tamanho da resposta |
stream | Define 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
| Item | Valor atual | Observação prática |
|---|---|---|
| Endpoint | POST /chat/completions | Cria uma resposta para uma conversa de chat |
| Base URL OpenAI-compatible | https://api.deepseek.com | Use com OpenAI SDK e rota /chat/completions |
| Base URL Anthropic-compatible | https://api.deepseek.com/anthropic | Útil para ferramentas e SDKs do ecossistema Anthropic |
| Authentication header | Authorization: Bearer ${DEEPSEEK_API_KEY} | Nunca exponha a chave no frontend |
| Campos obrigatórios | model, messages | messages precisa ter pelo menos uma mensagem |
| Model IDs atuais | deepseek-v4-flash, deepseek-v4-pro | São os IDs atuais documentados para Chat Completions |
| Aliases legados | deepseek-chat, deepseek-reasoner | Existem por compatibilidade |
| Depreciação | deepseek-chat e deepseek-reasoner serão descontinuados em 24/07/2026 | Em projetos novos, prefira os IDs V4 |
Uso típico de deepseek-v4-flash | Chat rápido, FAQ, classificação, automações econômicas | Melhor quando custo e velocidade são prioridades |
Uso típico de deepseek-v4-pro | Tarefas complexas, agents, raciocínio, código, planejamento | Melhor 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.
| Role | Quando usar | Exemplo curto | Erro comum |
|---|---|---|---|
system | Definir comportamento, regras e estilo | “Responda em português do Brasil.” | Colocar instruções contraditórias ou longas demais |
user | Enviar a solicitação do usuário | “Resuma este texto.” | Misturar histórico antigo sem controle |
assistant | Reenviar respostas anteriores do modelo em conversas multi-turn | “Claro, aqui está…” | Esquecer que isso aumenta tokens |
tool | Devolver ao modelo o resultado de uma ferramenta executada pela aplicação | Resultado de get_order_status | Usar 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 uso | Thinking recomendado? | Configuração sugerida | Observação |
|---|---|---|---|
| FAQ simples | Não, em geral | thinking.type="disabled" | Menor custo e menor latência |
| Classificação curta | Não, em geral | thinking.type="disabled" + JSON Output | Use schema simples |
| Geração de resumo | Depende | Comece sem thinking | Ative se a qualidade cair em textos difíceis |
| Debug de código | Sim | thinking.type="enabled", reasoning_effort="high" | Monitore tokens e latência |
| Planejamento multi-etapas | Sim | thinking.type="enabled" | Útil quando há dependências entre passos |
| Agent com Tool Calls | Sim, com cuidado | thinking.type="enabled", loop controlado | Pode 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
jsonno prompt; - dê um exemplo do formato;
- limite
max_tokens, mas não de forma agressiva; - faça
parseno 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âmetro | Função | Erro comum |
|---|---|---|
tools | Lista de funções disponíveis | Enviar tools demais sem necessidade |
function.name | Nome da função | Usar nome fora do padrão permitido |
function.description | Ajuda o modelo a escolher a função | Descrição vaga |
function.parameters | JSON Schema dos argumentos | Schema permissivo demais |
tool_choice | Controla se e como o modelo chama tools | Forçar tool quando não é necessário |
tool_call_id | Liga o resultado da tool à chamada correta | Esquecer 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_reason | O que significa | O que fazer |
|---|---|---|
stop | O modelo parou naturalmente ou encontrou uma stop sequence | Fluxo normal |
length | O limite de tokens foi atingido | Aumente max_tokens ou reduza contexto |
content_filter | Conteúdo omitido por filtro | Mostre fallback seguro |
tool_calls | O modelo chamou uma ferramenta | Execute a tool e envie uma mensagem tool |
insufficient_system_resource | A inferência foi interrompida por recurso insuficiente | Faç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:
| Campo | Significado |
|---|---|
prompt_tokens | Tokens de entrada |
completion_tokens | Tokens gerados na resposta |
total_tokens | Soma de entrada e saída |
prompt_cache_hit_tokens | Tokens de entrada que bateram no cache |
prompt_cache_miss_tokens | Tokens de entrada que não bateram no cache |
completion_tokens_details.reasoning_tokens | Tokens 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.
| Modelo | Input cache hit / 1M | Input cache miss / 1M | Output / 1M |
|---|---|---|---|
deepseek-v4-flash | US$ 0.0028 | US$ 0.14 | US$ 0.28 |
deepseek-v4-pro | US$ 0.003625 | US$ 0.435 | US$ 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:
| Componente | Tokens | Preço por 1M | Custo |
|---|---|---|---|
| Input cache hit | 20.000 | US$ 0.0028 | US$ 0.000056 |
| Input cache miss | 5.000 | US$ 0.14 | US$ 0.000700 |
| Output | 2.000 | US$ 0.28 | US$ 0.000560 |
| Total | 27.000 | — | US$ 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ção | Impacto no cache | Como otimizar |
|---|---|---|
| System prompt fixo | Bom | Mantenha instruções estáveis no início |
| Documento longo repetido | Bom após persistência | Reuse o mesmo prefixo |
| Pergunta variável no final | Bom | Coloque o contexto estável antes da pergunta |
| Timestamp no início | Ruim | Mova para o final ou remova |
| JSON schema repetido | Bom | Padronize ordem e formato |
| Tools longas | Pode ajudar se forem estáveis | Envie 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:
- aplique timeout client-side;
- use exponential backoff;
- adicione jitter;
- faça retry apenas em erros transitórios;
- use fila para controlar picos;
- registre número de retries;
- implemente circuit breaker em sistemas grandes;
- tenha fallback de UX para indisponibilidade.
| Código | Causa provável | Ação recomendada |
|---|---|---|
| 400 | Formato inválido do body | Corrija payload e roles |
| 401 | API key incorreta | Verifique segredo e ambiente |
| 402 | Saldo insuficiente | Verifique billing |
| 422 | Parâmetros inválidos | Corrija campos conforme erro |
| 429 | Rate limit/concurrency limit | Backoff, fila e redução de paralelismo |
| 500 | Erro interno | Retry com backoff |
| 503 | Servidor sobrecarregado | Retry 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_usagepara 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
- Usar modelo antigo sem verificar deprecation
Em projetos novos, prefiradeepseek-v4-flashoudeepseek-v4-pro. - Usar
base_urlem Node.js em vez debaseURL
O OpenAI SDK em Node usabaseURL. - Usar API key da OpenAI com endpoint da DeepSeek
A chave precisa ser da plataforma DeepSeek. - Expor
DEEPSEEK_API_KEYno frontend
Isso permite abuso da sua conta e consumo indevido de saldo. - Esquecer que a API é stateless
O histórico precisa ser reenviado quando for relevante. - Reenviar histórico completo sem controle
Isso aumenta tokens, custo e latência. - Confundir
/chat/completionscom/completions/chat/completionsé para conversa moderna;/completionsé usado para FIM Completion Beta em base beta. - Ativar JSON Output sem pedir JSON no prompt
A documentação alerta que isso pode gerar whitespace até o limite de tokens. - Não tratar
finish_reason="length"
A resposta pode vir truncada. - Não executar Tool Calls no backend
O modelo apenas solicita a tool. Sua aplicação executa. - Achar que todos os chunks de streaming têm
content
Chunks podem terreasoning_content,usageou arrays vazios. - Ignorar
usagee custos
Sem métricas, você não sabe qual feature está consumindo mais. - 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
| Interface | Melhor para | Endpoint/base | Observação |
|---|---|---|---|
| Chat Completions API | Chatbots, copilots, agents, JSON, tools, streaming | POST /chat/completions com https://api.deepseek.com | Caminho principal para chat moderno |
| Completions API | Fill-in-the-middle em código | /completions com base beta | Documentada como FIM Completion Beta |
| Anthropic API | Ferramentas e SDKs do ecossistema Anthropic | https://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.



