Limai Docs
Concepts

Models and Deployments

A model holds the schema; a deployment is a named, stable pointer at it.

A model is the extraction you build: tables and columns, the instructions and settings that drive extraction, and the documents and examples accumulated against them. A project holds as many models as the work needs.

A deployment is a named pointer at a model — production and staging are the usual names. It holds no schema of its own. What it holds is a decision about which schema of its model answers a request, and a stable address you can configure an integration against once.

What a deployment decides

A deployment either tracks the model's draft schema or is pinned to a schema version.

The deploymentServesWhen you edit the model's schema
Tracking the draftWhatever the model's schema is right nowThe next document through it uses the edit
Pinned to a versionThe frozen snapshot that version holdsNothing changes until you re-pin

One model can carry several deployments at once and they need not agree: a production pinned to the version you trust, and a staging tracking the draft, let you edit the schema all afternoon without a single production document being extracted against work in progress.

A deployment's ID never changes

Re-pinning a deployment to a different version, renaming it, pausing it and resuming it all leave its ID alone. The version behind the address moves; the address does not. That is the reason to send traffic to a deployment rather than straight to a model — you get a lever you can pull without touching the caller, and a rollback that is one action on your side and none on the integration's.

Addressing a model or a deployment

Wherever a v1 path names a {deploymentId} or an {extractionSchemaId}, three identifiers resolve:

IdentifierResolves to
A model's IDThat model, serving its draft schema
A deployment's IDThe model it points at, serving whichever schema that deployment names
A model's extraction schema IDThat model, serving its draft schema

Only a deployment ID carries the deployment's decisions — the pinned version, the pause, and the stamp left on every document that arrives. Address the model directly and all three are bypassed.

Schema and configuration are edited on the model

A deployment chooses a schema; it does not own one. The endpoints that write schema or configuration — Create Table, Update Configuration, and pushing, updating or deleting a validation script — take the model's ID. A deployment ID is refused:

Response409
{
  "error": "Schema and configuration are edited on the model, not on a deployment",
  "code": "POINTER_NOT_WRITABLE",
  "deploymentId": "dpl_prod01",
  "modelId": "dep_abc123"
}

Reads are not restricted this way. Listing documents, fetching extracted data or reading the configuration through a deployment ID all work, and a pinned deployment reports the tables and columns of the version it serves rather than those of the draft.

Pausing a deployment

A deployment is ACTIVE or PAUSED. A paused deployment takes no new extraction work: process-file, process-file-async, process-files-async, revalidation and benchmark runs addressed through it are rejected.

Response409
{
  "error": "Deployment dpl_prod01 on model dep_abc123 is PAUSED. Resume it before processing documents through it.",
  "code": "DEPLOYMENT_PAUSED",
  "deploymentId": "dpl_prod01",
  "modelId": "dep_abc123",
  "status": "PAUSED"
}

Pausing is per deployment, not per model: documents sent directly to the model, or through another active deployment on it, keep processing. A document that arrived through the paused deployment stays with it — processing it is refused even when the request names the model.

Pausing is also how a deployment is retired. There is no operation that deletes one, because its ID is an address integrations hold: a deleted deployment would turn every configured caller into a 404, while a paused one answers with the reason.

Where examples land

A reviewed document whose rows are all accepted becomes an example, provided the model's configuration admits corrections as examples. The deployment it arrived through decides which pool it joins:

Corpus modeA reviewed document that arrived through the deployment
SHAREDJoins the model's example pool, where every deployment on the model draws on it
ISOLATEDJoins a pool scoped to that deployment alone
NONEJoins no pool

Isolation applies to writing, not to reading. A deployment with an isolated pool retrieves examples from the model's pool and its own, so isolating a deployment narrows what it contributes and never what it can draw on. A document addressed to the model directly behaves as SHARED.

An isolated example can be promoted into the model's pool afterwards, which is the path from "this deployment is learning something new" to "every deployment should know this".

Every document records how it arrived

A document carries the deployment it came in through and the schema version it was extracted against:

StampValue
viaDeploymentIdThe deployment the request named, or null when the request named the model directly
schemaVersionIdThe version the run resolved to, or null when the deployment tracks the draft

A document keeps its deployment for every later run. Processing it again through the model's ID — re-processing from the dashboard included — runs it through the deployment it arrived through, at that deployment's pinned version. Processing it through a deployment ID it did not arrive through is refused, as is processing a document sent directly to the model through a deployment ID:

Response409
{
  "error": "Refusing to extract through deployment dpl_prod01: file_abc123 (sent directly to the model) did not arrive through it. Address the document to the deployment it arrived through, or to the model if it was sent directly.",
  "code": "FILE_NOT_VIA_DEPLOYMENT",
  "deploymentId": "dpl_prod01",
  "mismatches": [
    {
      "fileId": "file_abc123",
      "fileViaDeploymentId": null
    }
  ]
}

Both stamps appear on webhook payloads and on the upload URL response, so an integration receiving an event knows which of a model's deployments served it and which version of the schema produced the values. That is what makes "show me everything production processed under v2" a question with an answer.

Routes fire only for the traffic they are scoped to

Webhook subscriptions, agents and notification routes listen to a model, and each of those routes can also name one of the model's deployments. The match is exact:

The route namesIt fires for
The model onlyDocuments sent directly to the model
The model and one of its deploymentsDocuments that arrived through that deployment

A deployment is isolated by default. Traffic through it never fires the model's direct routes, so creating a staging deployment feeds none of the webhooks or agents already listening to the model until a route is bound to it. The dashboard can copy a model's direct webhook, agent and notification routes onto one of its deployments; routes the deployment already has are skipped. Notification routes that name no model — project- or organization-wide ones — are not model routes and match every document in their scope, deployment traffic included.

Sending documents into a deployment

A classifier route, a splitter's output and an ingest email address can each target a deployment instead of the model. A document handed on through one is stamped with that deployment exactly as a direct upload through it is, so the pinned version, the pause and the viaDeploymentId stamp all apply.

TargetWhile the deployment is paused
Classifier routeThe route leaves the candidate set; the classifier picks among its active routes, or records the document UNCLASSIFIED with a reason
Splitter outputThe splitter refuses documents at intake
Ingest email addressMail to the address is rejected and logged

A classifier can hold a route to a model and a route to one of its deployments at once — "Invoices" and "Invoices → production" are two routes. A deployment has at most one ingest email address.

Names

A deployment's name is unique within its model, at most 64 characters, and may not be blank. Creating a deployment, renaming it, releasing into it, pausing and resuming it, and setting its corpus mode are dashboard actions; the API takes the resulting ID as an address.

On this page