Endpoints
Create an endpoint over pinned data, serve it with a serve-scoped key, refresh when the source changes, and upgrade when a new base ships.
An endpoint is the persistent, per-customer product object: { base, pinned dataset snapshots, configuration, system prompts, held-out report } at a stable URL. Compose in the Workspace or over the API, publish to a URL, hand the URL to software. Unlike a quick run, an endpoint has state, and every call runs against that state.
POST /v2/endpoints { name, data, target, task, base } -> 202 (job: pin + evaluate + expose)
│
┌──────▼──────────────────────────────────────────────────────────────┐
│ ENDPOINT churn base schema-2 · dsv_91f2 · held-out 96.1% (r_a7d0) │
│ url: /v2/serve/{endpoint_id} yours, private, live │
│ all outputs: sector · column profile · cross-table map · │
│ missing-value imputation · predictions · held-out │
└──────┬──────────────────────────────────────────────────────────────┘
├── serve: POST /v2/serve/:id data in → full bundle
├── evolve: POST /v2/endpoints/:id/refresh re-sync data, re-score
│ POST /v2/endpoints/:id/upgrade newer base, re-score
└── operate: /v2/jobs · /v2/reports · /v2/usage · /v2/keys
An endpoint is typically live within minutes.
Identity and state
| Thing | Value | Mutable |
|---|---|---|
| Endpoint ID | Opaque unique ID, assigned at creation | Never |
| Name | Lowercase slug, for example churn | Yes, a rename |
| URL | https://api.schemalabs.ai/v2/serve/{endpoint_id} | Never |
Routes accept the id or the name; only the id survives a rename. An endpoint’s state is (base generation, data snapshot, configuration revision); each component versions independently, every change is additive, and the endpoint keeps serving throughout:
| Operation | Changes | Mints a report |
|---|---|---|
create | All three, initial | Yes |
refresh | Data snapshot (dsv_), fresh split | Yes |
upgrade | Base | Yes |
| Configuration edit (target, task, thresholds, system prompts) | Config revision | No; a target change updates the endpoint’s held-out block |
The report trail is the endpoint’s history. Configuration edits and renames are made on the endpoint page in the platform; everything else is available on both surfaces.
Create
Register the data first, or pass tables inline (they are ingested as an upload dataset). base defaults to the latest Schema model.
curl -X POST https://api.schemalabs.ai/v2/endpoints \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: <unique key>" \
-d '{ "name": "churn",
"data": ["ds_crm01", "ds_bill01"],
"target": { "column": "crm_contacts.c3" },
"task": { "type": "classification" } }'
# 202 { "endpoint": "churn", "id": "{endpoint_id}",
# "status": "creating", "job_id": "job_9a5b…" }
The id is final from this moment and the endpoint is listed immediately as creating. Poll the job or the endpoint until status is live (see Async jobs), then read the report at /v2/reports/:id: check the split, the baseline, and the weakest slice before you show the number to anyone. A new endpoint starts with one default system-prompt fragment. Shapes: Create an endpoint.
Serve
Serving is REST-only and needs a serve-scoped key. Give production a key with serve alone, so a leaked pipeline key cannot create, change, or delete anything.
curl -X POST https://api.schemalabs.ai/v2/keys \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "churn-pipeline", "scopes": ["serve"] }'
curl -X POST https://api.schemalabs.ai/v2/serve/{endpoint_id} \
-H "Authorization: Bearer $SCHEMA_SERVE_KEY" \
-H "Content-Type: application/json" \
-d '{ "tables": [ { "id": "crm_contacts",
"columns": ["c0","c1","c2","c3"],
"rows": [["ana@example.io","555-0142","1990-04-02",null]] } ] }'
A serve is live inference over the endpoint’s state: the request rows plus the pinned data, returning the full bundle scored by the endpoint. Read the current held-out report and system prompts from the endpoint object (GET /v2/endpoints/:id, read scope). Request data is validated against the pinned snapshot’s schema; a mismatch is a 400 validation_error naming the divergence. To wrap the endpoint as a tool or narrate the bundle with your own LLM, see Agents and LLMs.
A serve is distinct from reading the endpoint: GET /v2/endpoints/:id returns the stored object and the bundle already computed over the pinned data, with no inference.
Refresh: the data changed
Sync the dataset first, or let refresh do it inline:
curl -X POST https://api.schemalabs.ai/v2/endpoints/churn/refresh \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Idempotency-Key: <unique key>"
202 with a job; on completion the endpoint carries the new snapshot, a diff { rows_added, rows_changed, rows_removed, rows_unchanged }, and the new report, scored on a fresh split. Refresh is the only operation that makes an endpoint stop reflecting deleted rows. Schedule it from your data stack when the source updates (see Workflows and data stack).
Upgrade: a new base shipped
curl -X POST https://api.schemalabs.ai/v2/endpoints/churn/upgrade \
-H "Authorization: Bearer $SCHEMA_API_KEY" \
-H "Idempotency-Key: <unique key>" \
-d '{ "base": "schema-2" }'
# completed: { "base": "schema-2", "held_out": { "score": 0.961 },
# "previous": { "base": "schema-1", "held_out": 0.948 }, "delta": "+0.013",
# "report": "churn.s2.upgrade.2026-08-14" }
The same pinned data re-runs on the newer base and is re-scored. The endpoint serves the new base from completion; the trail keeps the prior report and the delta reads on the Reports page.
One mutating job runs per endpoint at a time: a second refresh or upgrade returns 409 conflict naming the running job_id.
System prompts
An endpoint owns a library of named system-prompt fragments (sp_..., each with name, body, active, order, version). Fragments steer an LLM. Read them from the endpoint object (GET /v2/endpoints/:id, the system_prompts array) and apply them in your own LLM; Chat applies them on the platform. Authored on the endpoint page (System Instructions); each edit is a config revision, applies immediately, and is audit-logged. Chat behavior: Platform.
Logs, delete, metering
GET /v2/endpoints/:id/logs returns the endpoint’s operation log (create, refresh, upgrade, job events), never row data. DELETE /v2/endpoints/:id tears the endpoint down immediately; its reports remain in the org’s audit trail and its datasets remain under Data, unpinned. What each operation costs is in Usage and billing.