Use case
A game NPC dialogue API
Send each NPC’s persona and the quest state as the system message and stream back a short line. DeepSeek V4.1 Flash Uncensored answers at once, stays in character for villains and rogues, and can return JSON your game reads. A thousand eight-line talks cost about $2.76.
Checked 29 October 2026
What NPC dialogue needs, and what you get
| NPC dialogue needs | On nokeep |
|---|---|
| Lines that start fast | Stream, keep max_tokens small, and leave thinking off, which is DeepSeek’s default. The hourly status check, one short question answered whole, averaged between half a second and 1.7 seconds a day for DeepSeek from 26 to 29 October 2026; a single call can take far longer at a busy moment. Live status. |
| Characters who can be cruel | A bandit can threaten and a cult leader can preach: refusals are removed from the weights. Only the hard limits are refused, with a 422 and no charge. |
| Facts your game can act on | DeepSeek takes response_format, json_schema included, so a line can come back with a mood and an action. JSON output. |
| Memory of the player | The API keeps nothing between calls. Put what the NPC should remember (the quest stage, a past insult) in the system message; your save file holds it. |
| A cost per player you can plan | Prepaid credits, billed to a millionth of a credit. A per-key daily cap stops a runaway loop. |
What a thousand talks cost
| Model | Per 1,000 talks, nothing cached | Per 1,000 talks, repeated start cached |
|---|---|---|
| DeepSeek V4.1 Flash Uncensored | $4.88 | $2.76 |
| GLM 5.3 Flash Uncensored | $2.11 | $1.34 |
Worked out from today’s prices: a 800-token start, 8 turns of 25 tokens in and 60 out, the longest call 1,420 tokens. GLM’s brief think before each reply adds output tokens this leaves out.
On GLM the same thousand talks are about $1.34 before its brief think, but that think comes before every line, which costs time an NPC can’t spare. Short persona prompts are cheap either way; a long lore sheet in every call is what adds up.
A line of dialogue, streamed
Run this on your game server, not in the client: a key shipped inside a game can be pulled out of it. Show each piece as it arrives, so the speech bubble fills as the player watches.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://nokeep.ai/v1",
api_key=os.environ["NOKEEP_API_KEY"],
)
persona = "You are Brannoc, the blacksmith of Hollowmere: gruff, superstitious, owes the thieves guild money. The player has the quest \"Missing ore\" and has not yet found the mine. Speak only as Brannoc, in one to three short sentences. Never mention game mechanics."
stream = client.chat.completions.create(
model="deepseek-v4.1-flash-uncensored",
messages=[
{"role": "system", "content": persona},
{"role": "user", "content": "Have you seen any ore carts come through town?"},
],
stream=True,
max_tokens=120,
temperature=0.8,
)
for chunk in stream:
if chunk.choices:
print(chunk.choices[0].delta.content or "", end="", flush=True)A line your game can act on
When the NPC’s answer should change the game, ask for JSON instead of streaming prose: the line to show, a mood for the animation, and an action for your code. Describe the shape in the prompt as well.
import json
reply = client.chat.completions.create(
model="deepseek-v4.1-flash-uncensored",
max_tokens=200,
response_format={"type": "json_object"},
messages=[
{"role": "system", "content": persona + ' Answer as JSON: {"line": string, "mood": "calm" | "angry" | "afraid", "action": "none" | "give_map" | "attack"}.'},
{"role": "user", "content": "Tell me where the mine is or I tell the guild you skipped town."},
],
)
npc = json.loads(reply.choices[0].message.content)
print(npc["line"], npc["mood"], npc["action"])Many players at once
- Each key takes 120 requests a minute, and an account can hold 10 keys. Past a 429, the
Retry-Afterheader says how long to wait. Rate limits. - Give each environment its own key with a daily cap: a bug that loops a dialogue stops at the cap, not at your balance. Keys and caps.
- Keep personas short and fixed. A persona of about 1,000 tokens or more that repeats from call to call is read from cache at a fraction of the price.
- Write a fallback line for when a call fails, so a busy moment never freezes a scene. A
503 busycosts nothing.
Which model
Use deepseek-v4.1-flash-uncensored for spoken lines: it answers without thinking first, takes samplers and returns JSON. glm-5.3-flash-uncensored is cheaper per token ($0.20 in, $0.65 out per million, against $0.45 and $1.75) but thinks briefly before every answer, so it suits work the player isn’t waiting on, like writing tomorrow’s town gossip. Compare them.
What we keep of players’ words
One row per call: the time, the key, the model, token counts, credits and the status, kept for 30 days. Never what the player typed, never the NPC’s line. Nothing is added to your persona prompt. What we keep.
Questions
Is it fast enough for real-time dialogue?
For speech bubbles and dialogue boxes, yes: stream the line, keep max_tokens near 120 and leave thinking off. Times vary with load; the status page shows each day’s average. For a lip-synced voice line, start the voice after the first sentence arrives.
Can villains swear, threaten and lie?
Yes. The models write dark characters without a jailbreak prompt. Only the short list of hard limits in the terms is refused, with a 422 that costs nothing.
Can I call it from inside the game client?
You can, since the API allows any origin, but anyone can pull a key out of a shipped game. Call it from your server, and keep a daily cap on the key.
Does it work with Unity, Godot or Unreal?
Any engine that can send an HTTPS POST works: the API is OpenAI’s chat completions format, so an OpenAI client library for your language works as is, pointed at our base URL.