apps/opik-documentation/documentation/fern/docs-v2/cost_intelligence/data-privacy-security.mdx
Cost Intelligence sits in the path of your developers' coding agent traffic, so it is reasonable to want a precise answer to "what leaves the machine". This page is that answer, field by field.
The short version: only counts, costs, and structural metadata are reported. Prompt and response content is not collected unless someone explicitly turns it on, and an organization can prevent that from ever happening.
Each section below lists the fields and includes an expandable example of the real payload, shown with content capture off (the default). Values are illustrative.
| Field | What it is |
|---|---|
| Session ID | Identifier for one coding session |
| Working directory | Path the session ran in |
| Project name | Resolved project label |
| User identity | Email, username, display name, org |
| Billing attribution | Plan, seat tier, billing mode |
| Git repository | Remote URL, branch, commit SHA |
| Commit statistics | File and line counts per turn. No diffs, no filenames |
{
"schema_version": 3,
"harness": "claude_code",
"session_id": "9f2c1e84-3b7a-4d21-9c05-71e4a8b6d033",
"cwd": "/Users/dev/src/payments-api",
"transcript_path": "/Users/dev/.claude/projects/payments-api/9f2c1e84.jsonl",
"project": { "name": "payments-api", "source": "git_remote" },
"identity": {
"email": "[email protected]",
"username": "dev",
"display_name": "Dev Example",
"org_name": "Example Inc",
"plan": "max",
"seat_tier": "priority",
"billing_mode": "subscription"
},
"repository": {
"remote": "[email protected]:example/payments-api.git",
"branch": "feature/idempotency-keys",
"head_sha": "4c1b9a7e2f8d3a15b6c07e94d2af8b31c5e7d902",
"dirty": true,
"commits_in_trace": 1,
"files_added": 2,
"files_deleted": 0,
"lines_added": 148,
"lines_deleted": 23
},
"capture_content": false
}
Note the commit delta carries counts only. No filenames and no diff content.
</Accordion>| Field | What it is |
|---|---|
| Model | Model that served the call |
| Request ID | Provider's own request identifier |
| Token counts | Input, output, cache-creation, cache-read, per-tier cache split. Read verbatim from the provider's usage payload, never estimated |
| Service tier | Standard, batch, or priority |
| Model configuration | Effort level, thinking mode, token limits, context management |
| Errors | Status code and retry count. No error bodies |
| Call structure | Trigger, turn and trace identifiers, parent links |
{
"provider": "anthropic",
"model": "claude-opus-5",
"request_id": "req_011CSb4RtqK8vN3wXyZ7Lm2P",
"trigger": "user_turn",
"turn_key": "b91f7c3d5a2e08461fd7c9b8e05a3d2f",
"trace_id": "0193f4c2-8a1e-7b3d-9f05-2c6e8a4b1d77",
"usage": {
"input_tokens": 412,
"cache_creation_input_tokens": 2048,
"cache_read_input_tokens": 31744,
"output_tokens": 1893,
"service_tier": "standard",
"cache_creation": {
"ephemeral_5m_input_tokens": 2048,
"ephemeral_1h_input_tokens": 0
}
},
"config": {
"effort": "high",
"thinking_type": "adaptive",
"max_tokens": 32000
},
"total_chars": 138204
}
Token counts are read straight from the provider's own usage block, so they reconcile with your invoice.
One row per classifiable region of the request or response. This is what makes cost attribution possible.
| Field | What it is |
|---|---|
| Position | Where in the request structure the block sits (a wire coordinate, not a file path) |
| Cost bucket | Which of the ~20 categories it belongs to |
| Size | Characters or bytes |
| Content hash | One-way hash of the block's content |
| Media type | For binary blocks (images, PDFs) |
| Tool / resource name | Tool, MCP server, skill or agent name. Not arguments or results |
| Cache status | Whether the block was a cache read, write, or fresh |
| Body | Only present when content capture is explicitly enabled |
[
{
"path": "system[0]",
"side": "input",
"kind": "text",
"category": "system_prompt",
"sha256": "3f8a1c9e77b204d6",
"chars": 8432,
"cache_control": "1h",
"cache_status": "read"
},
{
"path": "tools[3]",
"side": "input",
"kind": "tool_schema",
"category": "mcp_tools_active",
"tool_server": "github",
"tool_name": "create_issue",
"sha256": "b1d47e0a92c5f386",
"chars": 612,
"cache_status": "read"
},
{
"path": "messages[6].content[0]",
"side": "input",
"kind": "text",
"category": "memory_files",
"resource": "CLAUDE.md",
"sha256": "77c2e5b8104af9d3",
"chars": 1904,
"cache_status": "read"
},
{
"path": "messages[11].content[0]",
"side": "input",
"kind": "text",
"category": "user_input",
"sha256": "e904b71c3d8f26a5",
"chars": 214,
"cache_status": "fresh"
},
{
"path": "response.content[0]",
"side": "output",
"kind": "thinking",
"category": "thinking",
"sha256": "5a3f8c11e7b90d42",
"chars": 4120
},
{
"path": "response.content[2]",
"side": "output",
"kind": "tool_use",
"category": "builtin_tool_call",
"tool_name": "Edit",
"tool_use_id": "toolu_01A9bC3dEf5GhJ7k",
"sha256": "c60b2d9741ea8f35",
"chars": 806
}
]
Every block carries a category, a size and a hash. None carries a body field, because content capture is off. That one field is the only place prompt or response text would ever appear.
| Prompt and response text | Unless content capture is explicitly enabled |
| Thinking text | Unless content capture is explicitly enabled |
| Tool arguments and results | Names only |
| Source file contents, diffs, filenames | Counts only |
| Coding agent transcript contents | Path only. The file is never read |
| API keys and credentials | Redacted at capture, before anything is written |
| Request and response headers | Not shipped |
One setting governs whether any prompt or response text leaves the device.
| Default | Off. No configuration needed to get the private posture |
| Where it is set | CIPX_CAPTURE_CONTENT, delivered via managed settings or MDM |
| Org veto | Setting it to false explicitly is a hard veto. No individual user can override it |
| Auditable | Every session records the decision, so you can query which sessions (if any) reported content |
| Destination | Purpose | Control |
|---|---|---|
| Your model provider or gateway | The original API call, forwarded byte for byte unchanged | Inherent |
| Your Opik workspace | The payloads described above | Self-host Opik to keep this inside your own infrastructure |
| Error telemetry | Crash and error reports with stack traces. No request or response bodies | Set CIPX_SENTRY to off to disable |
| Plugin distribution | Plugin auto-update | Disable marketplace auto-update |
In transit. The coding agent talks to the proxy over the loopback interface only, so that traffic never touches a network. The proxy originates its own TLS connection to the model provider with full certificate validation, and ships to Opik over HTTPS. The proxy, admin and viewer listeners refuse to bind anything other than 127.0.0.1 and fail to start rather than binding a public address.
Credentials. Authorization headers are masked at capture, before anything is written to disk. The original headers are forwarded upstream untouched, so the proxy is transparent to authentication and never rewrites a caller's credentials.
On disk. The local spool lives at ~/.opik-cipx/ with directory mode 0700 and files 0600. It is a buffer, not an archive, and it is bounded by a total disk cap and a retention window, whichever binds first.
TLS interception. The recommended plugin rollouts (managed settings and MDM) do not terminate, decrypt or inspect TLS, and install no certificate. The optional macOS app does terminate TLS locally, using a per-device certificate authority whose private key is hardware-backed and non-extractable, constrained to the model provider hostnames.
For a formal review we can provide the full Cost Intelligence data security and privacy document, covering the complete field inventory, on-disk retention characteristics, the full outbound destination list, subprocessors, and current compliance attestations.
Email [email protected] and we will route it to the right team.