pleach
Integrate

Migrating from Anthropic Enterprise

Keep your Anthropic Enterprise contract. Pleach closes three downstream gaps: per-axis cost rollup, an audit row in your DB, replay-deterministic eval.

If you have an Anthropic Enterprise (or Anthropic for Work) contract, you've already been through procurement, a security questionnaire, and the vendor-side SSO/SAML and Zero Data Retention review. You should not casually add a new vendor on top of that work. Pleach is explicitly designed not to be one — it ships as an npm package and writes to your existing Postgres. There is no Pleach SaaS to add to your vendor list.

This page is for the team that built its first one to three LLM features on the existing Anthropic Enterprise contract and is now hitting one of three downstream walls: finance can't attribute cost to a meaningful axis inside a Workspace — your end customers in a SaaS product, or your employees, teams, and cost centers when the Workspace is an internal-use deployment; compliance can't produce a tamper-evident audit row from their own database; or eval/regression can't replay a turn byte-identically against a specific model snapshot. Pleach sits underneath the existing contract and closes those three gaps without changing what Anthropic does for you.

A note on shape: this page reads naturally for the multi-tenant SaaS case (Acme Corp is your customer). The same row, the same hash chain, and the same fingerprint cover internal-use deployments — set tenantId to the employee, team, or cost-center identifier you want to chargeback or audit against. The vendor contract still rolls up to the Workspace; Pleach rolls up to whichever axis your finance and audit teams actually report on.

The architecture

┌──────────────────────────────────────────────────────────────┐
│  Anthropic Enterprise (your existing contract)               │
│  - SSO / SAML                                                │
│  - Zero Data Retention                                       │
│  - Workspaces (per-workspace API keys)                       │
│  - Admin API (per-workspace usage rollup)                    │
│  - Dedicated capacity / fine-tuned snapshots                 │
│  - Prompt caching, batches API, files API                    │
│                                                              │
│  ┌────────────────────────────────────────────────────────┐  │
│  │  Pleach SessionRuntime (npm + your Postgres)           │  │
│  │  - AuditableCall row → your Postgres                   │  │
│  │    keyed (sessionId, turnId, stageId, seqWithinTurn)   │  │
│  │    carrying tenantId, modelId, tokenUsage              │  │
│  │  - Family-lock at session start (snapshot pinned)      │  │
│  │  - Replay-deterministic StreamEvent via fingerprint    │  │
│  │  - prev_hash + row_hash chain                          │  │
│  │  - Subagent rollup to parent turnId                    │  │
│  │                                                        │  │
│  │  AnthropicSdkProvider                                  │  │
│  │  (wraps @anthropic-ai/sdk; uses your workspace key)    │  │
│  └────────────────────────────────────────────────────────┘  │
│                                                              │
└──────────────────────────────────────────────────────────────┘

Anthropic's Admin API is the vendor-facing rollup — what each Workspace spent against your contract. Pleach's AuditableCall ledger is the downstream rollup — which of your end customers within that Workspace caused the spend, which turn they typed, what the agent did with it, and what each tool call cost. The two ladders compose: the Admin API tells you what the Workspace owed Anthropic; Pleach tells you which of your customers inside that Workspace owes you.

The three walls

The Anthropic Enterprise contract is comprehensive at the vendor layer. The three walls below are the places it stops — not because the contract is incomplete, but because each one is a downstream concern about your product's behavior that only your own infrastructure can answer.

Wall 1: Per-end-customer cost attribution inside a Workspace

What the contract gives you: the Admin API exposes per-Workspace usage and per-API-key usage. If you provisioned one Workspace per end customer, you already have rollup at end-customer granularity.

The gap: most enterprise deployments don't carve one Workspace per end customer. A single Workspace serves N tenants in your product because that's how your auth, your rate limits, and your prompt-caching prefixes are organized. The Admin API reports the Workspace's total — it does not know which of your tenants inside that Workspace caused which turn, which subagent spawned, or which tool called the LLM again.

What Pleach closes: every LLM call writes an AuditableCall row carrying tenantId, turnId, subagentDepth, modelId, and tokenUsage, keyed (sessionId, turnId, stageId, seqWithinTurn). A single SQL query against your Postgres gives you per-end-customer rollup; the Admin API gives you the matching Workspace total to reconcile against.

Wall 2: A tamper-evident audit row in your own database

What the contract gives you: Zero Data Retention means Anthropic does not retain your inputs or outputs past the inference window. The contract documents this and is auditable through Anthropic's SOC 2 / ISO process.

The gap: ZDR is a statement about what the vendor stores. It is not a statement about what you store, and it is not the row your downstream auditor will ask for when they want to see what your product told a specific customer on a specific day. If your compliance program needs a tamper-evident record of decisions your product made — which tool the agent invoked, which model snapshot answered, which subagent spawned — that record has to live in your database, not the vendor's.

What Pleach closes: the AuditableCall row in your Postgres carries a prev_hash + row_hash chain. Any reordering or deletion of a row breaks the chain at the next verifier pass. The ZDR contract continues to govern what Anthropic stores; Pleach governs what you store and how you defend the chain when asked.

Wall 3: Replay determinism across model snapshots

What the contract gives you: dedicated capacity and pinned model snapshots (claude-sonnet-4-5, claude-opus-4-7) let you control which model version serves your traffic. You can hold a snapshot for the length of a contract term.

The gap: holding a snapshot doesn't make a turn replayable. A recorded turn replayed two months later against the same snapshot can still drift if any input changed — prompt cache invalidation, tool definition reordering, a system-prompt edit. The vendor contract gives you the snapshot; it does not give you a cache key that says "this exact input produced this exact output."

What Pleach closes: every turn produces a Fingerprint covering the prompt, tool schemas, family, snapshot id, and runtime config. A recorded turn replays byte-identically when the fingerprint matches; when it diverges, the diff tells you which input changed. This is the substrate eval and regression testing run against before a new snapshot rolls out to production.

The code shape

import {
  createPleachRuntime,
  AnthropicSdkProvider,
  type StreamEvent,
} from "@pleach/core";
import { SupabaseAdapter } from "@pleach/core/sessions";

// Your existing Anthropic Enterprise workspace key. SSO, ZDR, and
// the rest of the vendor contract continue to govern this key
// exactly as before — Pleach reads it, doesn't replace it.
const WORKSPACE_API_KEY = process.env.ANTHROPIC_WORKSPACE_API_KEY!;

const runtime = createPleachRuntime({
  // tenantId is YOUR end customer inside the Workspace. The Admin
  // API doesn't see this field; Pleach stamps it on every row.
  tenantId: "acme-corp",
  userId:   "alice@example.com",
  storage:  new SupabaseAdapter({ client: supabase }),
  provider: new AnthropicSdkProvider({
    apiKey:    WORKSPACE_API_KEY,
    model:     "claude-sonnet-4-5",
    maxTokens: 4096,
  }),
});

// Family-lock pins tokenizer, prompt-cache key, tool-call dialect,
// and refusal pattern to the snapshot at session start. A
// long-running session never silently widens to a different
// snapshot mid-conversation — important when you run sonnet-4-5
// for one tier of customer and opus-4-7 for another.
const session = await runtime.sessions.create({
  provider: { type: "anthropic" },
  model:    { id: "claude-sonnet-4-5" },
});

for await (const event of runtime.executeMessage(
  session.id,
  "Summarize last quarter's filings.",
)) {
  // event: StreamEvent — paired with an AuditableCall row in your
  // Postgres carrying tenantId, turnId, modelId, tokenUsage.
}

The per-end-customer rollup falls out of one SQL query against your own database:

-- Per-end-customer cost rollup inside a single Anthropic Workspace.
-- Reconcile the SUM against the Admin API's per-workspace total for
-- the same window.
SELECT
  tenant_id,
  COUNT(DISTINCT turn_id)                  AS turns,
  SUM((token_usage->>'input_tokens')::int) AS input_tokens,
  SUM((token_usage->>'output_tokens')::int) AS output_tokens
FROM harness_auditable_calls
WHERE created_at >= now() - interval '30 days'
  AND model_id   =  'claude-sonnet-4-5'
GROUP BY tenant_id
ORDER BY output_tokens DESC;

Three things this pattern gives you that the Anthropic Enterprise contract alone doesn't:

  1. End-customer cost rollup inside a shared Workspace. The Admin API tells you what the Workspace spent. Pleach's (workspace_key, tenant_id, turn_id, token_usage) row tells you which of your customers inside that Workspace spent it, joinable to your billing pipeline today.
  2. A hash-chained audit row in your own Postgres. ZDR continues to govern what Anthropic retains. Pleach's prev_hash / row_hash chain governs what your downstream auditor sees when they ask what your product told a customer on a specific day.
  3. Replay-deterministic eval across snapshots. Before promoting claude-sonnet-4-5 to claude-opus-4-7 for a regulated tier, you can replay last quarter's recorded turns against both snapshots and read the divergence diff. The fingerprint is the cache key; the StreamEvent log is the replay record.

A note on prompt caching: Anthropic's cache_control: { type: "ephemeral" } breakpoints on system prompts and tool definitions keep working unchanged — the SDK speaks to the API, Pleach does not intercept the request body. Pleach's own fingerprint is the cache key for replay, a different concern from vendor-side prefix reuse. See Prompt caching for the distinction.

What stays the same

Pleach does not replace any of these. Your existing contract and the vendor primitives it governs continue to work unchanged:

  • SSO / SAML for Console access.
  • Zero Data Retention as negotiated.
  • Workspaces and per-Workspace API keys.
  • Admin API for per-Workspace usage rollup.
  • Dedicated capacity and fine-tuned snapshots.
  • Prompt-caching breakpoints (cache_control: { type: "ephemeral" }).
  • Batches API, files API, tool-use beta flags.
  • Extended thinking (surfaced through Pleach as thinking.delta StreamEvents, content unchanged).

What changes

Before PleachWith Pleach
End-customer cost rollup inside a WorkspaceAdmin API gives Workspace total; per-tenant split is your code's problemSELECT … GROUP BY tenant_id against your Postgres
Audit row for what your product decidedAnthropic's request log (vendor-shaped)AuditableCall row in your DB with prev_hash + row_hash
Replay a recorded turn against a new snapshotRe-run and eyeballFingerprint match → byte-identical; divergence → diff
Multi-snapshot deployment without silent fallbackManual disciplinelocked at runtime.sessions.create({ provider, model })
Subagent cost attribution to the parent turnManualSpawnTreeState rolls up to parent turnId

No new vendor

Pleach is npm install @pleach/core plus the Postgres you already run. There is no Pleach SaaS, no new ZDR contract to negotiate, no new security questionnaire, no new SOC 2 review to wait on, and nothing for your procurement team to onboard. The license is FSL-1.1-Apache-2.0 — source-available, usable in production, auto-transitions to permissive Apache 2.0 two years after first stable publish.

Where each is load-bearing

ConcernAnthropic Enterprise's slotPleach's slot
SSO / SAML for Console accessyes (vendor primitive)None — out of scope
Zero Data Retention contractyes (vendor primitive)None — governs vendor, not your DB
Per-Workspace usage rollupAdmin APINone — composes with Admin API
Per-end-customer rollup inside a WorkspaceNoneAuditableCall row keyed on tenantId
Dedicated capacity / fine-tuned snapshotsyes (vendor primitive)None — referenced by modelId on the row
Prompt-caching breakpointsyes (cache_control: ephemeral)None — passes through unchanged
Tools API, batches, files, extended thinkingyes (vendor primitive)None — surfaced as StreamEvents
Tamper-evident audit row in YOUR databaseNoneprev_hash + row_hash chain
Family-locked, snapshot-pinned routingSingle-vendor by constructionlocked at runtime.sessions.create({ provider, model })
Replay-deterministic evalNone (snapshot only)Fingerprint replays byte-identical StreamEvents
Subagent cost rollup to parent turnIdNoneSpawnTreeState
OTel spans threaded by tenantIdNoneruntime.spans facet

The two coverage maps barely overlap. The Anthropic Enterprise contract is the right tool for everything the vendor owes you; Pleach is the right tool for everything your product owes its own downstream auditors and finance team. Neither does the other's job.

When you don't need Pleach

  • Single-tenant enterprise app where finance doesn't need a per-end-customer rollup, the Admin API's per-Workspace total is the answer they want, and there's no downstream auditor asking for a row in your own database. The Anthropic Enterprise contract is sufficient.
  • One Workspace per end customer, no subagents, no replay requirement, eval is "we eyeball the latest snapshot." The vendor-side primitives carry the load.
  • Internal tooling where the SDK's request log is a good-enough audit trail and you're not going to run regression replay across snapshots.

Sibling SKUs that ride alongside the contract

Two SKUs reach the same Enterprise-contract reader through adjacent doors. Neither is required by the migration above; both get raised by the same buying conversation.

  • @pleach/coding-agent — the sandboxed coding-agent surface for the internal dev-tools team that often sits inside the same Enterprise contract footprint. The typed CodingAgentRuntime contract ships today at 0.2.0-alpha.0 on the /runtime subpath; method bodies and sandbox-provider wiring land in the next phase. The audit row is the same row, the tenantId axis is the same axis — an internal coding-agent's per-employee or per-team spend rolls up under the same GROUP BY as the rest of your Workspace traffic. See Coding agent.
  • Language-agnostic contract. The runtime substrate is wire shapes (HTTP+SSE, StreamEvent, AuditableCall, checkpoint envelope, version vector), not a TypeScript surface. A Go implementation round-trips a shared corpus of recorded turns against the contract today; the official @pleach Go runtime SKU is the next planned published implementation. This is the procurement-visible answer when Enterprise IT asks "is this TypeScript-only?" — the same contract supports a Java or Python runtime built against the same wire shapes. See Language-agnostic contract.

Where to go next

On this page