# Blueprints & your schema

> The customer-defined schema behind every dataset — discover it, never guess it


A **Blueprint** is the schema of one DeepSieve workspace: which entities exist
(e.g. `companies`, `funds`), their columns, and their relationships. It's
defined by the workspace owner during onboarding — **it is different for every
customer and can change after you integrate**.

**The boundary in one sentence:** an agent can build a *new* workspace's
Blueprint end-to-end, but can never alter a *live* one — editing the active
schema is human-only, enforced at the auth gate regardless of scopes.

That has one hard consequence for integrators: **never hardcode entity or
column names**. Discover them — `GET /v1/blueprints` lists the ids and marks
the active one, then read the schema of the one you mean:

```bash
curl -s $BASE_URL/v1/blueprints/{blueprint_id} -H "Authorization: Bearer $DEEPSIEVE_API_KEY"
```

```json-response
{"object": "blueprint",
 "blueprint": {"domain_name": "…", "entities": ["companies", "funds"]},
 "entities": [{"key": "companies",
               "columns": [{"name": "name", "type": "text"},
                           {"name": "hq_city", "type": "text"}]}]}
```

Exports embed the same schema metadata so downstream consumers stay
self-describing.

## Creating a Blueprint (agent-drivable)

A key with `blueprint:create` can take a **new** workspace through onboarding
end-to-end — describe, review the inferred draft, request adjustments, approve:

```bash
# 1. Start: describe the research domain in natural language → 202
curl -s -X POST $BASE_URL/v1/blueprints/drafts \
  -H "Authorization: Bearer $DEEPSIEVE_API_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"prompt": "Track industrial-automation vendors: products, funding, key people"}'

# 2. Poll until status is "ready" (or "awaiting_input"), then REVIEW the draft
curl -s $BASE_URL/v1/blueprints/drafts/{id} -H "Authorization: Bearer $DEEPSIEVE_API_KEY"
#    → { "draft_blueprint": {...}, "follow_up_questions": [...] }

# 3. Answer follow-ups and/or ask the inference agent for adjustments — one
#    synchronous chat turn: the reply, the measured changes, and `applied`
curl -s -X POST $BASE_URL/v1/blueprints/drafts/{id}/chat \
  -H "Authorization: Bearer $DEEPSIEVE_API_KEY" -H "Content-Type: application/json" \
  -d '{"message": "add a founded_year column to companies"}'
#    → { "reply": { "content": "...", "questions": [], "not_done": [] },
#        "changes": [ { "kind": "add_column", "entity": "companies", "tier": "green", ... } ],
#        "applied": true, "draft_revision": 2, ... }
#    (send your own "message_id" UUID to make retries idempotent; without one a
#     retry is a second model call. `/adjust` — 202 → poll — is deprecated.)

# 4. Approve → real tables are created and the workspace activates
curl -s -X POST $BASE_URL/v1/blueprints/drafts/{id}/approve \
  -H "Authorization: Bearer $DEEPSIEVE_API_KEY"                # 202 → poll until "active"
```

Statuses: `interpreting | awaiting_input | ready | adjusting | instantiating |
active | failed`. Approval creates real schema — an agent acting for a human
should show them the draft before approving.

## Editing the active schema — human-only

Edits to an **already-active** Blueprint are refused for API-key callers at the
gate itself, regardless of role or scopes — an agent may *propose* a change to
its human, never apply one. Humans edit in-app at **Edit Blueprint**
(`/blueprint`) with data-safety tiers (green auto, amber confirm, red refused).
