LizzyDocs
Docs navigation Capture traffic

Stage 01 · Capture

Capture model traffic

Configure an upstream source, proxy OpenAI-compatible requests, label calls for later filtering, and verify that capture is working.

Required scope

distill:writeUse distill:read to inspect sources and captured-call metadata.

Secret boundary

Human → APIThe upstream key is write-only and never belongs in Pilot context.

Join key

External IDCarry your request or ticket ID through capture, feedback, and diagnosis.

Owner and boundary

A source tells Lizzy where teacher requests should go and which calls may be retained. Your server sends traffic through the OpenAI-compatible proxy. Lizzy forwards the request, returns the provider response, and records non-body metadata even when body sampling is off.

Source creation is a human-controlled operation because it containsupstream_key. Pilot can inspect an existing source and explain its state, but policy forbids it from reading captured bodies or creating and updating credentials.

Configure a source

Create the source with the same live or test token that will call the proxy. The optional loop groups provenance, while name becomes the stable value used byX-Lizzy-Source. Capture resources are mode-isolated even though the loop itself spans modes.

cURLexample
curl -sS -X POST "https://lizzy.albinilabs.com/v1/distill/sources" \
  -H "Authorization: Bearer $LIZZY_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: source-production-teacher-v1" \
  --data '{
  "loop": "dlp_REPLACE_ME",
  "name": "production-teacher",
  "base_url": "https://api.openai.com/v1",
  "upstream_key": "<upstream-provider-key>",
  "default_capture": true,
  "capture_sample_rate": 1,
  "redaction": {
    "mode": "patterns",
    "patterns": ["email", "ssn"],
    "drop_fields": ["metadata.email", "messages[].metadata.ssn"]
  }
}'

Persist the returned id. The response never echoes the upstream key. Pattern redaction recognizes email, phone, credit_card,ssn, and ip_address. A drop path uses dot-separated object keys and [] for array traversal, as in messages[].metadata.ssn. Unknown redaction fields are rejected as unknown_parameter; they never silently switch redaction off.

json201 response
{
  "id": "dsc_01K...",
  "object": "distill_source",
  "loop": "dlp_01K...",
  "name": "production-teacher",
  "base_url": "https://api.openai.com/v1",
  "default_capture": true,
  "capture_sample_rate": 1,
  "status": "active",
  "livemode": true,
  "captured_count": 0
}

Proxy an OpenAI-compatible request

Change only the client base URL and credential. Keep the upstream model name in the body.X-Lizzy-External-Id is the join key back to your system; tags are comma-separated labels for later filtering. The response body remains OpenAI-compatible.

cURLexample
curl -sS "https://lizzy.albinilabs.com/v1/proxy/chat/completions" \
  -H "Authorization: Bearer $LIZZY_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Lizzy-Source: production-teacher" \
  -H "X-Lizzy-Tags: support,refund" \
  -H "X-Lizzy-External-Id: ticket-123" \
  --data '{"model":"gpt-4.1-mini","messages":[{"role":"user","content":"Can I change my delivery address?"}]}'
X-Lizzy-Call-IdThe captured call ID. Log it beside your own request ID.
X-Lizzy-Served-ByWhether upstream, student, shadow, or upstream fallback served the request.
X-RateLimit-*Current proxy limit, remaining allowance, and reset time.

Label the outcome and verify capture

  1. 1

    List metadata, not bodies

    Call GET /v1/distill/calls?external_id=ticket-123. Lists expose model, tokens, latency, tags, source, feedback, and body status without returning prompts or answers.

  2. 2

    Attach the product outcome

    Post feedback with exactly one of call or external_id. A score is a number from -1 to 1; thumbs_up and thumbs_down are also accepted.

  3. 3

    Use the same labels in data filters

    Source IDs, tags, served-by values, and feedback scores let a later dataset describe why each row belongs in training instead of relying on an opaque export.

bashfeedback
curl -sS -X POST "https://lizzy.albinilabs.com/v1/distill/feedback" \
  -H "Authorization: Bearer $LIZZY_API_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"external_id":"ticket-123","score":1,"comment":"Address updated","tags":["resolved"]}'

Posting feedback again updates the current opinion on the newest matching external ID. It is not an append-only event log, so keep your own history if the sequence matters.

Redaction and retention are observable states

  1. 1
    stored

    The body was sampled, redacted according to policy, and remains available to an authorized human.

  2. 2
    sampled_out

    Metadata exists, but the body was intentionally never stored.

  3. 3
    redacted

    A deletion request purged the body while preserving metrics and provenance.

  4. 4
    expired

    Retention removed the body; the metadata row remains for audit and aggregate use.

GET /calls/{call_id}/body distinguishes an unknown call from a body that never existed and one that was removed. DELETE /calls/{call_id} is a body purge, not a wholesale removal of metering or provenance.

Diagnose capture without retry loops

source_not_foundCheck token mode, workspace, and the exact source ID or X-Lizzy-Source name. Test and live sources are isolated.
insufficient_scopeUse distill:write for source creation, proxying, feedback, and redaction; distill:read is enough for metadata reads.
body_not_capturedSampling skipped the body. Increase future sampling deliberately; the old body cannot be recovered.
body_expiredThe body existed but was redacted or expired. Do not retry the read.
429Respect the rate-limit reset, retry the same inference request only if your application can tolerate a repeated provider call, and keep the external ID stable.
Provider 4xx/5xxInspect the relayed provider body and provider request ID. Changing Lizzy idempotency state cannot fix an upstream model or credential error.
GET/v1/distill/calls?external_id={your_id}

The safest first diagnostic: it proves whether the call reached capture and shows source, served-by, body status, latency, and feedback metadata.