# LLM API Data Retention vs Zero Data Retention: A Route-Level Audit

> Limited retention can fit an approved workload. ZDR requires evidence for the exact account, model, endpoint, features, and data path—and a gate that rejects unapproved changes.

- URL: https://blog.laozhang.ai/en/posts/llm-api-data-retention-vs-zero-data-retention
- Published: 2026-07-27
- Updated: 2026-10-07
- Author: LaoZhang AI Team (https://blog.laozhang.ai/en/about)
- Topic: API Guides
- Tags: LLM API, Zero Data Retention, API Privacy, Data Governance, Developer Guides

---
![An API route review connecting training, safety logs, stored state, features, third parties, and application logs to a release decision](https://blog.laozhang.ai/posts/en/llm-api-data-retention-vs-zero-data-retention/img/cover.webp)

**Use standard, limited retention when its purposes, storage locations, and maximum windows fit your workload's policy. Require verified zero data retention (ZDR) when that policy prohibits routine provider storage of submitted content.** In either case, approve a specific API route: the account, endpoint, model, features, intermediaries, and application logging configuration that will actually handle the request.

Start by writing one sentence: “This workload permits [storage owner] to retain [content] for [maximum window], subject to [conditions].” A requirement that permits encrypted customer-controlled storage differs from one that prohibits content anywhere at rest. That distinction now matters even for arrangements labeled ZDR.

The practical result of an audit should be an approved configuration with evidence references and enforceable limits. A vendor comparison or a list of reasons to stop is insufficient. The record and offline gate below show how to turn your decision into something another engineer can check.

## Data Retention and ZDR Answer Different Questions

No-training terms describe whether data can improve models or products. Retention terms describe what remains after a request, where it remains, and for how long. An API can offer no training while retaining abuse logs, uploaded files, conversation history, or search data.

ZDR usually concerns eligible customer content under a particular service arrangement. It need not exclude every transient memory cache, operational counter, safety exception, or customer-owned database. Read the provider's definition against your own requirement before treating the two as equivalent.

For example, Claude's ZDR-compatible structured outputs can retain schemas for up to 24 hours after their last use. Keep sensitive names and values out of those schemas. [Claude feature rules](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention)

A request's `store=false` can disable one form of application state. It does not establish a ZDR agreement or necessarily disable safety logging. Encryption protects stored content; it does not make that content unretained. Likewise, a successful response establishes that a feature worked, rather than that its retention policy met your requirements.

## When Standard Retention Is the Better Decision

Limited retention is a usable choice when you can approve its entire storage path. Low sensitivity helps, but the determining condition is permission: some organizations allow a bounded retention period for proprietary content, while others prohibit it.

| Workload and requirement | Suitable starting point | Conditions for approval |
| --- | --- | --- |
| Classifying public documentation or synthetic support questions | Standard retention | Approved monitoring window; no hidden private fields; controlled logs and exports |
| Summarizing internal material that policy permits a supplier to retain briefly | Limited retention under the applicable agreement | Named storage purposes, maximum windows, access rules, feature exceptions, and an accountable owner |
| Processing unreleased source code under a prohibition on routine provider content storage | Verified ZDR | Approval covers the deployed account, model, endpoint, features, and every intermediary |
| Processing content under a prohibition on any durable copy, including customer-controlled safety storage | A route assessed against that stricter prohibition | Provider-side ZDR alone is insufficient; all content storage and exceptions must fit the requirement |

For a public FAQ classifier, accepting bounded monitoring may avoid unnecessary restrictions on features. For an unreleased-code assistant, removing background jobs or stored conversations may be the necessary price of meeting policy. If an essential feature requires disallowed retention, choose a different approved architecture or keep that data out of the service. Do not silently weaken the requirement to obtain the feature.

This is an engineering and procurement decision, not a legal certification. Data minimization, access controls, contractual duties, and applicable law still require their own assessment.

## Current Route Matrix: What the Official Docs Actually Establish

The following starting points were checked on **October 6, 2026**. They do not establish that your account has an approval or that a deployed request follows the documented route.

| Service that handles the request | Documented starting point | What must match your approval |
| --- | --- | --- |
| OpenAI API | Default abuse-monitoring logs may contain content for up to 30 days, with exceptions. ZDR and Modified Abuse Monitoring require approval; organization and project settings matter. ZDR forces `store=false` for Responses and Chat Completions. [OpenAI data controls](https://developers.openai.com/api/docs/guides/your-data) | Endpoint, model, and feature eligibility. Stored conversations, files, batch, and other stateful surfaces are excluded; Responses background polling is incompatible with strict ZDR. Cache, tool, and safety rules require their own checks. |
| Anthropic-handled Claude API | ZDR is enabled separately for each organization under an arrangement. Eligible Messages and token-counting calls still depend on the model and features. [Claude retention documentation](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention) | Certain covered models, including Fable 5/5.1 and Mythos 5/5.1, require 30-day retention unless explicitly authorized otherwise. Files, Managed Agents, batch, code execution, and the MCP connector have exclusions. Ineligible features can succeed in a ZDR organization. |
| Gemini Developer API | Paid-service no-training terms do not establish zero storage. Current guidance directs customers needing guaranteed ZDR or an enterprise DPA to Vertex AI. [Gemini Developer ZDR guidance](https://ai.google.dev/gemini-api/docs/zdr) | Developer Search and Maps grounding retain data for 30 days. Interactions defaults to stored state; files, explicit caches, and live-session resumption have separate persistence. Do not assume paying enables ZDR. |
| Google Cloud / Vertex route | In-scope abuse-monitoring exceptions can be requested, but Advanced AI models or features may have additional safety terms that prevent ZDR. [Google Cloud retention documentation](https://docs.cloud.google.com/gemini-enterprise-agent-platform/resources/zero-data-retention?hl=en) | Cloud Search grounding can retain derived queries and context, unassociated with the customer or end user, for up to three days; this differs from Developer API's 30 days. Maps, Deep Research, session state, and logging need separate review. |
| Models sold by Azure in Microsoft Foundry | Microsoft describes separate Azure processing and storage; this path does not call OpenAI's services. Approved modified abuse monitoring removes content storage and human review while automated review continues. [Microsoft data privacy](https://learn.microsoft.com/en-us/azure/foundry/responsible-ai/openai/data-privacy) | When disabled, `ContentLogging=false` is evidence for that control; an absent capability is not false. Stateful resources and customer diagnostics remain separate. “Claude in Foundry” can have a different processor and contract. |
| Amazon Bedrock | Retention has explicit modes. Effective settings depend on Region and, where applicable, project; model defaults can require safety retention. `none` prevents durable content storage and provider sharing under the documented mode. [AWS retention modes](https://docs.aws.amazon.com/bedrock/latest/userguide/data-retention.html) | The model's `allowed_modes`, approvals, and effective setting must support `none`. A default-mode request with `store=false` is not equivalent. Under `none`, stored Responses and background execution are unavailable. Check cross-Region destinations too. |
| OpenRouter | ZDR controls restrict inference routing to endpoints classified as ZDR. An enforced requirement cannot be undone with a request-level false value. [OpenRouter ZDR routing](https://openrouter.ai/docs/guides/features/zdr) | Inference routing does not automatically cover plugins or tools. BYOK and private-deployment declarations can be customer attestations rather than independent verification. Review upstream selection, fallbacks, gateway logging, and tool recipients. |

### OpenAI ZDR with PSP can still involve stored content

[Private Safety Processing](https://developers.openai.com/api/docs/guides/private-safety-processing) places selected, doubly encrypted interactions in customer-controlled regional cloud storage for automated safety processing. Original records and encrypted results have a 30-day TTL. OpenAI maintains an operational reference rather than a separate content copy; the processing design excludes human access to the content.

That may fit a requirement prohibiting provider-held content while permitting a controlled customer safety bucket. It conflicts with a requirement prohibiting all durable content. Record the bucket's owner, access permissions, encryption authority, and TTL in the audit. Revoking a key does not delete existing records or undo completed processing.

Do not confuse this arrangement with **Private Retention with PSP**, which uses OpenAI-managed storage, or with Safety Retention. Those are distinct arrangements in the [OpenAI data-control documentation](https://developers.openai.com/api/docs/guides/your-data).

![Illustration comparing provider-content ZDR with a policy prohibiting all durable content, including customer storage](https://blog.laozhang.ai/posts/en/llm-api-data-retention-vs-zero-data-retention/img/storage-boundary.webp)

### Claude's standard window is not a universal per-request timer

The [commercial retention page](https://privacy.claude.com/en/articles/7996866-how-long-do-you-store-my-organization-s-data) gives a maximum 30-day backend deletion window for API inputs and outputs, with feature, agreement, safety, and legal exceptions. The feature documentation describes conversation content that does not require storage as unstored by default, while identifying model-specific requirements.

These statements have different scopes. Neither supports a universal “every Claude request is stored for 30 days” rule or an unconditional default-ZDR claim. For a procurement record, use the applicable agreement and the actual model and feature behavior. Safety or legal exceptions can retain flagged content longer, including under ZDR; a strict requirement must account for them.

### Product logs are a separate retention decision

Gemini Developer paid-project logs illustrate the distinction. GenerateContent logging defaults off; Interactions defaults on, with request or project controls. Enabled logs default to 55 days and offer 7-, 14-, 28-, or 55-day settings. Saving logs into a dataset removes automatic expiration. These windows describe that product logging feature, not all requests or abuse-monitoring logs. [Gemini logs and datasets](https://ai.google.dev/gemini-api/docs/logs-datasets)

## Build a Route Evidence Card

Fill this record for each approved workload. Link to protected evidence instead of pasting credentials, personal information, or prompt bodies into the ticket.

```text
Workload / owner:
Allowed data classes / prohibited fields:
Requirement: limited retention / provider-content ZDR / no content at rest
Permitted storage owners, purposes, locations, and maximum windows:
Accepted safety and legal exceptions:

Service and contractual processor:
Organization / project / workspace / resource reference:
Endpoint / API version / exact model version / Region:
Features / request-state flags / cache settings:
Gateway / upstream endpoint / tools / permitted fallback routes:

Training and feedback-use terms:
Safety monitoring: content, access, window, approval reference:
Stateful features: stored objects, TTL, deletion controls:
Customer-controlled safety storage, if any:
Project logs / datasets / exports / sharing:
Application logs / traces / queues / backups / support systems:
Metadata and in-memory artifacts permitted by policy:

Evidence for each answer: source, scope, checked date, protected reference
Account-specific approval and effective-configuration references:
Customer logging/expiry checks and their verification dates:
Unknowns or conflicting evidence:

Decision: APPROVED / APPROVED WITH LIMITS / NOT APPROVED
Approved route version / limits / reviewer / review date:
Change triggers / next review / rollback or alternative route:
```

For each content destination, record **who holds it, why, maximum retention, and how that answer was established**. “ZDR: yes” cannot substitute for those four answers. Distinguish a policy document from account approval, a configuration export from runtime behavior, and a customer log check from proof of provider deletion.

Three steps turn the card into an approval:

1. **Choose the permitted boundary.** Enumerate input fields and decide which storage purposes are acceptable. If policy allows bounded retention, write the maximum rather than merely choosing “standard.”
2. **Match evidence to the deployed path.** Identify the effective tenant setting and exact model, endpoint, Region, feature set, and fallback chain. Review every recipient, including search and tools, as well as your own telemetry. Leave unsupported answers unknown.
3. **Approve limits and enforce them.** Bind the record to a route version. Apply an allowlist before dispatch, review customer logging separately, and invalidate approval when evidence or configuration changes.

A useful customer check uses synthetic markers to inspect your own log destinations, redaction, expiration, backups, and support exports. Such a check cannot prove deletion inside a provider. No account settings, real API calls, or provider deletion experiments were performed for this article.

## Reject Unapproved Model, Feature, and Fallback Changes

![Illustration of a request gate comparing an approved configuration and blocking unreviewed model, tool, and fallback changes](https://blog.laozhang.ai/posts/en/llm-api-data-retention-vs-zero-data-retention/img/route-gate.webp)

The following complete Python example uses only synthetic local data and the standard library. It demonstrates a dispatch gate after a human review; **the example's approval flag is fictional**. It makes no API call and cannot discover whether a real account has ZDR.

Save it as `route_gate.py` and run `python3 route_gate.py`. The approved record lists the exact destination and permitted behaviors. In production, construct the request description from the actual dispatch configuration and tie the reviewed record to the protected evidence card.

```python
from copy import deepcopy
from datetime import date

# Fictional review for an unreleased-code workload.
approved = {
    "reviewed": True,
    "valid_through": "2026-10-31",
    "requirement": "provider-content-zdr",
    "route": {
        "owner": "example-direct-service",
        "tenant": "example-production-project",
        "endpoint": "example-stateless-endpoint",
        "model": "example-pinned-model-v1",
        "region": "example-region",
    },
    "allowed_data_classes": ["unreleased-code"],
    "allowed_features": [],
    "allowed_fallbacks": [],
    "store": False,
    "telemetry_profile": "metadata-only-v1",
}


def gate(record, request, today):
    reasons = []
    if record.get("reviewed") is not True:
        reasons.append("review missing")
    try:
        if date.fromisoformat(record["valid_through"]) < today:
            reasons.append("review expired")
    except (KeyError, TypeError, ValueError):
        reasons.append("review date missing or invalid")
    if record.get("requirement") != "provider-content-zdr":
        reasons.append("wrong policy")
    expected = record.get("route")
    if not isinstance(expected, dict) or not expected:
        reasons.append("approved route missing")
    elif request.get("route") != expected:
        reasons.append("route changed")
    for field, allowed_field in (
        ("features", "allowed_features"),
        ("fallbacks", "allowed_fallbacks"),
    ):
        actual = request.get(field)
        allowed = record.get(allowed_field)
        if not isinstance(actual, list) or not isinstance(allowed, list):
            reasons.append(field + " unknown")
        elif any(item not in allowed for item in actual):
            reasons.append(field + " outside approval")
    if request.get("data_class") not in record.get("allowed_data_classes", []):
        reasons.append("data class outside approval")
    if record.get("store") is not False or request.get("store") is not False:
        reasons.append("stored state not approved")
    profile = record.get("telemetry_profile")
    if not profile or request.get("telemetry_profile") != profile:
        reasons.append("telemetry changed or unknown")
    return ("REJECT", reasons) if reasons else ("ALLOW", [])


base = {
    "route": deepcopy(approved["route"]),
    "data_class": "unreleased-code",
    "features": [],
    "fallbacks": [],
    "store": False,
    "telemetry_profile": "metadata-only-v1",
}
checks = [("approved configuration", base)]
for label, field, value in (
    ("new code-execution feature", "features", ["code-execution"]),
    ("unreviewed fallback", "fallbacks", ["backup-route"]),
    ("unknown storage flag", "store", None),
    ("body logging enabled", "telemetry_profile", "full-content"),
):
    changed = deepcopy(base)
    changed[field] = value
    checks.append((label, changed))
changed = deepcopy(base)
changed["route"]["model"] = "example-pinned-model-v2"
checks.append(("new model", changed))

for label, request in checks:
    result, reasons = gate(approved, request, date(2026, 10, 6))
    print(label + ": " + result, "; ".join(reasons))
```

The approved fixture prints `ALLOW`; all five changed fixtures print `REJECT` with a reason. We checked those outcomes locally. The code checks the supplied descriptions, so it must sit on the actual dispatch path: an independent client that bypasses it also bypasses its protection. Enforcing the telemetry profile likewise requires real logging controls; a matching string does not configure them.

Reopen the evidence card when a tenant, model version, Region, feature, retention setting, gateway, tool, or fallback changes. Also invalidate the approval when the underlying agreement or policy changes. Do not let an automatic retry choose a different route merely because the original one is unavailable.

## Worked example: approving an unreleased-code assistant

Suppose the team's requirement forbids routine provider content storage but permits specifically approved customer storage. It selects an eligible stateless route, obtains approval for its production tenant and model, excludes tools and stored conversations, and configures metadata-only application telemetry.

The review can reach **APPROVED WITH LIMITS** once the evidence card establishes those conditions and accounts for applicable safety and legal exceptions. Its allowed data class is unreleased code; credentials and unrelated customer records remain prohibited. If the route uses PSP customer safety storage, that bucket and its retention must be explicitly included in the permitted boundary.

Now an engineer adds code execution to improve the assistant. A successful call does not extend approval—Claude's ineligible features, for example, need not fail automatically. The gate rejects the new feature. The team can assess a different eligible implementation, keep execution local under separately approved controls, or obtain a new retention decision. It cannot assume that an existing ZDR account covers the change.

If the chosen Bedrock model requires a retention mode outside policy, changing the setting to `aws_review` merely to make the model available would change the approved boundary. Select a model authorized for the required mode, obtain the appropriate exception, or withhold that workload. Availability is a constraint to resolve, rather than evidence that retention is acceptable.

Once the data conditions are cleared, use the [LLM API provider cost comparison](https://blog.laozhang.ai/en/posts/cheapest-llm-api-provider) to compare purchase paths and cost per accepted output. A cheaper route still needs its own retention approval. No verified ZDR scope for laozhang.ai was established in this audit, so it is not recommended here for a workload requiring ZDR.

*Disclosure: [laozhang.ai is our own service](https://blog.laozhang.ai/en/about#laozhang). Its prices are platform pricing, not an independent comparison.*

## FAQ

### Does “not used for training” mean zero data retention?

No. It answers a data-use question. Monitoring, conversation state, files, grounding, product logs, and your application's telemetry can still retain content. Review storage purposes and windows separately.

### Does `store=false` prove that an API request is ZDR?

No. It can control response or conversation storage without changing monitoring policy, account eligibility, or attached features. OpenAI's approval-based controls and [Bedrock's retention modes](https://docs.aws.amazon.com/bedrock/latest/userguide/data-retention.html) demonstrate why the effective service arrangement also matters.

### Can an encrypted customer bucket coexist with ZDR?

Yes, under OpenAI's documented [ZDR with Private Safety Processing](https://developers.openai.com/api/docs/guides/private-safety-processing) arrangement. That does not satisfy a policy prohibiting all durable content. Evaluate the customer bucket as a storage destination rather than overlooking it because the provider calls the arrangement ZDR.

### Is paid Gemini Developer API automatically a guaranteed-ZDR route?

No. Google's [current Developer guidance](https://ai.google.dev/gemini-api/docs/zdr) directs guaranteed-ZDR and enterprise-DPA requirements to Vertex AI. The Cloud route still needs account, model, feature, and exception checks; moving platforms does not approve the resulting configuration.

### Is an approved route permanently approved?

No. Approval remains useful only while its evidence and configuration match deployment. Block unreviewed changes and expired records, then review the exact changed path. Keep a permitted alternative or synthetic-only mode available if the approved route cannot serve the workload.

## Sources

External pages this guide links to, in the order they appear. Last updated 2026-10-07.

- [Claude feature rules](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention) (platform.claude.com)
- [OpenAI data controls](https://developers.openai.com/api/docs/guides/your-data) (developers.openai.com)
- [Gemini Developer ZDR guidance](https://ai.google.dev/gemini-api/docs/zdr) (ai.google.dev)
- [Google Cloud retention documentation](https://docs.cloud.google.com/gemini-enterprise-agent-platform/resources/zero-data-retention?hl=en) (docs.cloud.google.com)
- [Microsoft data privacy](https://learn.microsoft.com/en-us/azure/foundry/responsible-ai/openai/data-privacy) (learn.microsoft.com)
- [AWS retention modes](https://docs.aws.amazon.com/bedrock/latest/userguide/data-retention.html) (docs.aws.amazon.com)
- [OpenRouter ZDR routing](https://openrouter.ai/docs/guides/features/zdr) (openrouter.ai)
- [Private Safety Processing](https://developers.openai.com/api/docs/guides/private-safety-processing) (developers.openai.com)
- [commercial retention page](https://privacy.claude.com/en/articles/7996866-how-long-do-you-store-my-organization-s-data) (privacy.claude.com)
- [Gemini logs and datasets](https://ai.google.dev/gemini-api/docs/logs-datasets) (ai.google.dev)
