EN ▾
Get API key

DeepSeek API SDK: Use the OpenAI SDK and Swap Endpoints

There is no special client you must install for a DeepSeek API SDK setup: DeepSeek-style APIs follow the OpenAI format, so the OpenAI SDK works with a different base URL. That same fact lets you swap to another endpoint by changing three values.

Updated

One connector block feeding several server towers, illustrating swapping endpoints with one SDK

Key points

  • The OpenAI Python and Node SDKs work with any OpenAI-compatible endpoint; you change base URL, key and model name.
  • Keep those three values in environment variables so switching endpoints needs no code edit.
  • Swapping is safe for plain chat, streaming and tool calls, but test model-specific features before relying on them.
  • For this endpoint use https://api.deepseekapi.top/v1 and the model id uncensored.

Why the OpenAI SDK is the DeepSeek API SDK

When people search for a DeepSeek API SDK, they expect a package with the vendor's name on it. In practice, DeepSeek's own documentation describes calling its API through the OpenAI SDK with a different base URL, because the API follows the OpenAI request and response format. Check their current docs for the exact base URL and model names; they are the authority on their service.

The consequence is useful. Any code written against the OpenAI client library can talk to any server that implements the same endpoints, which here are POST /v1/chat/completions, POST /v1/responses and GET /v1/models. Moving between providers becomes a configuration change rather than a rewrite. The rest of this article shows the pattern in Python, Node and curl, then a structure that makes the swap trivial.

Python setup

Install the official package and point it at the endpoint:

pip install openai
from openai import OpenAI

client = OpenAI(
    base_url="https://api.deepseekapi.top/v1",
    api_key="YOUR_KEY",
)

resp = client.chat.completions.create(
    model="uncensored",
    messages=[
        {"role": "system", "content": "You are a concise technical assistant."},
        {"role": "user", "content": "Explain idempotency in two sentences."},
    ],
)
print(resp.choices[0].message.content)
print(resp.usage)

Get a key on the API key page. New users can claim $0.50 of trial credit with one click, with no card. The DeepSeek API Python article goes deeper on this language, including error handling.

Node.js setup

npm install openai
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.deepseekapi.top/v1",
  apiKey: process.env.API_KEY,
});

const stream = await client.chat.completions.create({
  model: "uncensored",
  stream: true,
  messages: [{ role: "user", content: "List four uses of a message queue." }],
});

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

The pattern is identical: base URL, key, model. Streaming returns Server-Sent Events, and the library turns them into an async iterator. Tool calling follows the same schema as other OpenAI-compatible APIs: pass tools, read streamed tool_calls, and return results as role: "tool" messages.

Make the endpoint swappable

Do not hard-code the three values. Read them from the environment and wrap client creation in one function. Then moving from one endpoint to another means editing a .env file, not source code.

import os
from openai import OpenAI

def make_client():
    return OpenAI(
        base_url=os.environ.get("LLM_BASE_URL", "https://api.deepseekapi.top/v1"),
        api_key=os.environ["LLM_API_KEY"],
    )

MODEL = os.environ.get("LLM_MODEL", "uncensored")

def ask(prompt: str) -> str:
    r = make_client().chat.completions.create(
        model=MODEL,
        messages=[{"role": "user", "content": prompt}],
        temperature=0.7,
    )
    return r.choices[0].message.content

Now a different provider only needs three environment variables. The official SDKs also read OPENAI_API_BASE and OPENAI_API_KEY in some versions, but explicit variables are clearer and avoid surprises when you run several providers at once.

If you use TypeScript or another language, the idea is the same: one factory function, three variables, no provider names scattered through the codebase. A common mistake is to let the vendor name leak into function names, log messages and variable names, which makes a later swap harder than it needs to be. Name things after the job (ask, summarise) instead of the provider.

Keep a small test that sends one fixed prompt through ask() and checks for a non-empty answer. Run it after every endpoint change; it catches wrong URLs and keys in seconds.

What stays the same and what changes when you swap

ItemStays the sameMay change
Request shapemessages, roles, temperature, top_p, stopOptional parameters a provider does not support
StreamingSSE with data chunksWhere usage appears in the stream
Tool callingtools, tool_choice, tool_callsHow well the model follows a schema
Model nameRequired fieldThe value itself: here it is uncensored
Context windowPrompt plus completionSize: 100,000 tokens here
BehaviourChat formatStyle, strengths, refusal behaviour

The last row is the one that catches people. An endpoint is compatible at the protocol level, not the behaviour level. Two providers can accept identical requests and give very different answers. The model here is a single open-weight model from an independent provider, tuned to answer without content refusals for lawful adult use, and it is not the official API of DeepSeek or any other lab. Re-test prompts that you tuned for another model.

Features this endpoint has, and does not

  • Supported: chat completions, the Responses format, model listing, streaming, tool calling, JSON mode (response_format with json_object), and passthrough of temperature, top_p, stop, seed and the penalties.
  • Not offered: image, audio or video generation, embeddings, fine-tuning.
  • Limits: a 100,000-token window, an 8 MB maximum body, 8 concurrent requests and 300 per minute on a full key (2 and 60 on a trial key).
  • Errors: HTTP 429 with the code rate_limited or concurrency, and a Retry-After: 5 header on temporary overload.

If your code calls an embeddings endpoint, you will need another provider for that part and can keep chat here. Splitting by task is a common reason for the environment-variable pattern above.

A migration checklist

When you swap one endpoint for another in an existing project, work through a short list instead of changing everything at once.

  1. Prove the endpoint. Send one request with curl and confirm you get text back. Call GET /v1/models and check that the id uncensored is listed.
  2. Change the three values. Base URL, key, model name, nothing else. Do not touch prompts yet.
  3. Run your existing tests. If you have prompt regression tests, run them and note which fail. Failures are usually behavioural, such as a different output format, not protocol errors.
  4. Check parameters. Remove options the endpoint does not need. Keep temperature, top_p, stop and seed if you use them.
  5. Test streaming and tools separately. Streaming bugs often hide in client code that assumes a specific chunk layout. Tool calls need a schema that the model follows well, so test with your real functions.
  6. Measure cost and latency on real traffic. Compare a day of requests, not one prompt.

Do this in a branch or with a feature flag that routes a small share of traffic to the new endpoint. Because the client code is shared, rolling back is changing an environment variable.

Handle retries and read usage

The SDKs retry some failures by default, but you should still handle 429 yourself, since concurrency limits are real in production. Catch the rate-limit exception, wait the number of seconds in Retry-After (5 on overload), and retry a few times. Failed requests are not charged, so retries are safe for your balance.

Log usage.prompt_tokens and usage.completion_tokens on every call. Pricing is $0.15 per 1M input tokens and $0.50 per 1M output tokens, so a call with 2,000 input and 600 output tokens costs 2,000 × $0.15 / 1M + 600 × $0.50 / 1M = $0.0003 + $0.0003 = $0.0006. The response headers also include X-Balance-USD for the remaining credit. See the pricing page for top-ups and bonuses, and the docs for the full parameter list.

Editors and other tools

The three values carry over to any tool with an OpenAI-compatible provider setting. The article on using a DeepSeek-style API in Cursor walks through one such editor. In each tool, the fields are labelled slightly differently, but you always enter the base URL ending in /v1, the key, and the model name.

Questions and answers

Is there an official DeepSeek SDK I must install?

You do not need a vendor-specific package. DeepSeek documents using the OpenAI SDK with a different base URL; check their docs for current details.

What three values do I change to use this endpoint?

The base URL (https://api.deepseekapi.top/v1), your API key, and the model id uncensored.

Will my existing OpenAI code work unchanged?

Chat, streaming, JSON mode and tool calling follow the same format, so mostly yes. Embeddings, images and audio are not offered, and answers differ because the model differs.

Does the SDK send the key correctly?

Yes, it sends Authorization: Bearer with your key automatically.

Your key is one form away

Create an account, copy the key, change the base URL. That is the whole setup.

Get API key