Skip to content
NewDeepSeek V4.1 Flash 1017 Uncensored is live, with 1M tokens of context.Read the launch
Journal

Zero retention doesn't mean zero records

Exactly what XField keeps for each API request, what it never stores, why the record exists, and the questions to ask any provider about retention.

"Zero retention" is a phrase that does a lot of work on API websites, and it usually means something narrower than it sounds. Here is what it means at XField: we do not store your prompts or your completions, and we do not train on your content. Every request still leaves a record. This post lists what is in that record, what is not, why it exists, and what that means for the work you send us.

What we keep for each request

Each API request leaves one usage record. It holds:

FieldWhat it tells us
ModelWhich model id you called
Token countsInput and output tokens, including cached input tokens and reasoning tokens
TimingHow long the request took, including time to first token
CostWhat the request cost
KeyWhich of your API keys made the call

That is the whole record. It describes the request. It does not contain it.

What we don't keep

  • The prompt. System prompts, messages, tool definitions, tool results, and images you send are not stored.
  • The completion. Generated text, reasoning text, and tool calls the model writes are not stored.
  • Training data. We do not train on your content.

The trade-off is real and worth stating plainly. We cannot show you what you sent last Tuesday. There is no history to search and no request to replay. If you need a transcript of a session, for an audit, a report, or a bug you want to reproduce, keep it yourself.

Why the record exists

Billing

You pay per request, so we have to count. Token counts and cost per key are how your bill adds up, and how you can check it does. Cached tokens are counted separately because they are billed differently, and reasoning tokens are counted because they are generated output, even when you hide the reasoning text from the response.

Abuse handling

The record lets us see patterns without seeing content: a key suddenly sending ten times its usual traffic, an account whose usage changes shape overnight, a key from a finished project that suddenly wakes up again. Often that means a leaked key, and the record is what lets us tell you which one. Not storing text does not change the rules. The acceptable use policy applies to every request.

Debugging latency

When you tell us responses feel slow, timing is what turns that into something we can fix. A slow first token and a slow generation have different causes. Time to first token, total duration, and token counts per model and per key show which one you have, and cached-token counts show whether prompt caching is working for you. None of that needs your prompt.

What this means for sensitive work

Not storing text is about what happens after a request. During the request, your content is processed, because that is how a response gets generated. So the old advice still holds: send what the task needs and nothing more.

  • Minimize. Send the function, not the repository. Send the log lines around the failure, not the whole dump.
  • Redact customer data. Replace names, emails, account numbers, and access tokens with consistent placeholders like CUSTOMER_1 or EMAIL_A. The model can still reason about the structure, and you can map the answer back locally.
  • Handle samples with care. For malware or phishing analysis, send the strings, the decompiled function, or the sandbox report rather than the live artifact. Defang URLs and IP addresses.
  • Check your own logs. Your side is usually the bigger retention risk. SDK debug logging, proxies, CI output, and agent transcripts written to disk can all keep full prompts for as long as nobody deletes them.

If you want your own records, copy our approach and log usage, not text:

log_usage.py
Python
import logging, os, time
from openai import OpenAI
 
log = logging.getLogger("llm")
client = OpenAI(base_url="https://xfield.cloud.brutal.ai/api/v1", api_key=os.environ["XFIELD_API_KEY"])
 
def ask(prompt: str) -> str:
    start = time.monotonic()
    resp = client.chat.completions.create(
        model="glm-5.3-flash-uncensored",
        messages=[{"role": "user", "content": prompt}],
    )
    u = resp.usage
    cached = u.prompt_tokens_details.cached_tokens if u.prompt_tokens_details else 0
    log.info("model=%s in=%d cached=%d out=%d ms=%d",
             resp.model, u.prompt_tokens, cached, u.completion_tokens,
             int((time.monotonic() - start) * 1000))
    return resp.choices[0].message.content

Key hygiene matters more than you think

The record names the key, which makes keys your unit of attribution. One shared key for everything gives you one undifferentiated line of usage. Separate keys give you answers.

  • One key per project, and a separate one for CI. When usage spikes, you know where to look, and you can revoke one key without breaking everything else.
  • Set an expiry on short-lived keys. CI runners, a contractor, a two-week engagement. An expired key returns a 401, which is a much better failure than a forgotten key that still works.
  • Delete keys you no longer use. Do it in Settings › API keys. A key is shown once; if you lose it, create a new one and delete the old one rather than hunting for it.
  • Keep keys out of prompts and code. Load them from XFIELD_API_KEY. Coding agents read files in your project, so a key pasted into a config file can end up in a prompt.
  • Check which key a machine is using. GET /api/v1/key describes the key you call it with.

Questions to ask any provider

Retention claims are easy to write and hard to verify. Whoever you use, these questions get past the headline:

  1. Do you store prompts or completions at all? If so, for how long?
  2. What exactly is in the per-request record you do keep? Ask for the field list.
  3. Do you train on API content? Is that never, or opt-out?
  4. Does the policy cover every model and every route, or only some? If you pass requests to another company to serve, does their policy match yours?
  5. Are there exceptions, such as flagged content, abuse review, or extra logging while support investigates a ticket?
  6. Can I see usage per key, set expiry, and delete keys myself?
  7. If a guarantee cannot be met for a request, does the request fail, or does it quietly go somewhere the guarantee does not hold?

Our answers are in this post. If you want to try the API under these terms, request access and start with the quickstart.

Keep your stack.
Lose the refusals.

Tell us what you are building. We reply with an invitation, a key and pricing for your volume.