Set up the example environment
You need a Lizzy workspace, an owner or admin who can create a test token, and a server-side environment for your integration. The examples use cURL, Python 3 withrequests, or Node.js 18 or newer. Start with a test token carryingdistill:read and distill:write.
mkdir lizzy-first-integration
cd lizzy-first-integration
export LIZZY_API_BASE="https://lizzy.albinilabs.com/v1"
export LIZZY_API_TOKEN="<lizzy-test-token>"
# Only needed for the Python examples
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install requests
The example value is intentionally not a usable secret. Create the real token in the Lizzy token dashboard, copy it once, then inject it through your deployment platform’s secret store.
Verify the token
GET /v1/whoami is the fastest way to prove four assumptions: the token is valid, it belongs to the intended workspace, it is in test mode, and it has the scopes your code expects. Run this check during setup and include it in an operator diagnostic, but do not call it on every application request.
curl --fail-with-body "$LIZZY_API_BASE/whoami" \
-H "Authorization: Bearer $LIZZY_API_TOKEN"
A successful token-authenticated response has this shape:
{
"object": "whoami",
"workspace": {
"id": "ws_01K2ZXQ8M4Y7V6R5T3S9N2P1A0",
"name": "Acme AI",
"plan": "prepaid"
},
"credential": {
"type": "api_token",
"id": "tok_01K2ZXQ8M4Y7V6R5T3S9N2P1B1",
"name": "developer-quickstart",
"environment": "test",
"scopes": ["distill:read", "distill:write"]
},
"livemode": false,
"api_version": "2026-07-01"
}
Create a Distill loop
A loop owns the intent and navigation context for one experiment pipeline. Sources, datasets, runs, models, reports, and deployments can be traced back to it. The loop itself is workspace-scoped; its child resources are separated by test or live mode.
- 1
Choose a stable idempotency key
Derive it from your own operation ID, such as
quickstart:loop:support-quality:v1. Reuse the exact key and exact body after a timeout. Do not generate a new key for every retry. - 2
Create the loop
Send a descriptive goal. Lizzy generates the slug when you omit it and returns HTTP 201 with the new loop.
- 3
Persist response.id
The identifier is
id, notloop_id. Later request bodies use that value in aloopfield when the operation supports loop scoping.
curl --fail-with-body -X POST "$LIZZY_API_BASE/distill/loops" \
-H "Authorization: Bearer $LIZZY_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: quickstart:loop:support-quality:v1" \
-d '{"name":"Support quality","description":"Reduce inference cost while preserving resolution quality"}'
{
"id": "dlp_01K2ZXQ8M4Y7V6R5T3S9N2P1D3",
"object": "distill_loop",
"name": "Support quality",
"slug": "support-quality",
"description": "Reduce inference cost while preserving resolution quality",
"status": "active",
"counts": {
"sources": 0,
"datasets": 0,
"runs": 0,
"live_deployments": 0,
"captured_calls": 0
},
"created_at": "2026-08-15T09:30:00Z",
"updated_at": "2026-08-15T09:30:00Z"
}
/v1/distill/loops/{loop_id}Reconcile your local record at any time. A loop can be archived and restored; deleting it does not erase its experiment artifacts.
Run the funded sandbox
The Distill sandbox is a workspace-scoped demonstration resource. It pulls a public tool-use corpus, replays examples through a platform-funded teacher within a hard spend cap, and captures the results as ordinary test-mode artifacts. It does not attach those artifacts to the loop you just created. Use it to learn states and recovery, not as your production ingest path.
- 1empty
No sandbox work exists yet.
- 2pulling
Lizzy is fetching and normalizing the public corpus.
- 3replaying
Teacher calls are running and progress is saved after each batch.
- 4ready or capped
Replay reached the available rows, call target, or spend cap.
- 5dataset version
Freeze captured calls, then poll the returned dsv_ resource to ready or failed.
# POST returns 202. replay_batch selects a replay batch size, from 1 to 500.
curl --fail-with-body -X POST "$LIZZY_API_BASE/distill/sandbox" \
-H "Authorization: Bearer $LIZZY_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"replay_batch":25}'
# Poll at a fixed interval. Stop on ready, capped, paused, or error.
curl --fail-with-body "$LIZZY_API_BASE/distill/sandbox" \
-H "Authorization: Bearer $LIZZY_API_TOKEN"
# Once calls_sent is greater than zero, freeze them into an immutable version.
curl --fail-with-body -X POST "$LIZZY_API_BASE/distill/sandbox/dataset" \
-H "Authorization: Bearer $LIZZY_API_TOKEN"
{
"object": "distill_sandbox",
"status": "replaying",
"corpus": { "rows_pulled": 10000, "rows_target": 10000 },
"replay": {
"calls_sent": 125,
"calls_target": 10000,
"teacher_spend_usd": 1.3842,
"spend_cap_usd": 20.0
},
"dataset": null,
"dataset_version": null,
"latest_run": null,
"latest_report": null,
"error": null
}
Retry requests without duplicating work
Treat the HTTP outcome, response body, diagnostic request ID, idempotency key, and any returned resource ID as one operation record. That record lets a developer explain what happened before changing anything.
- 1A read failed
Retry the same GET with exponential backoff and a deadline. Reads do not create resources.
- 2A create timed out
Retry the exact body with the original Idempotency-Key, then persist the returned ID.
- 3An async watch timed out
GET the existing resource ID. Do not POST a replacement just because your local wait ended.
- 4A terminal state failed
Inspect the resource error, fix the named prerequisite, and use the operation-specific retry path.
{
"error": {
"type": "permission_error",
"code": "insufficient_scope",
"message": "This token is missing the required scope: distill:write.",
"param": null,
"request_id": "req_0123456789abcdefabcd"
}
}
Branch on error.code, not the prose message. For authentication failures, verify the token and scopes with /v1/whoami. For sandboxerror states, inspect error.code: corpus pull, teacher replay, capture, teacher usage, and upstream teacher failures need different fixes. Continue with the authentication, capture, dataset, and error guides once this quickstart works.