Lattice is in preview. It is documented and usable, but it sits outside the
release line: it is not listed in the changelog, its configuration can
change without a deprecation cycle, and it carries no compatibility
promise. The supported way to embed text on CPU is the
[bundled model menu](/docs/pro/api/embed#cpu-models); Lattice is
for workloads that have measured that menu and need something smaller.
Lattice is a static retriever — a token lookup table rather than a transformer.
It embeds text in microseconds on a CPU and adds a few megabytes to a
deployment. It scores materially below a real dense embedder on retrieval, which
is the trade it exists to make.
It is an explicit serving leg. A namespace that selects Lattice never falls back
to another leg, and an unconfigured artifact is a validation error rather than a
silent substitution.
## Provisioning
Generate a deployment artifact with the upstream
[Lattice slicer](https://github.com/ErikKaum/lattice/tree/main/slicer), place
its `model.safetensors` and `tokenizer.json` together, and set
`LAYER_LATTICE_MODEL_PATH` to the model file before starting the gateway. The
supported model id is `erikkaum/lattice-retrieval`; the requested `embed.dims`
must match the loaded artifact, and only text modality is supported.
```bash
uv run slicer slice \
--dim 512 \
--quant int4_row \
--output-dir /var/lib/hevlayer/lattice
export LAYER_LATTICE_MODEL_PATH=/var/lib/hevlayer/lattice/model.safetensors
```
```jsonc
"text": {
"type": "string",
"embed": {
"model": "erikkaum/lattice-retrieval",
"dims": 512,
"serving": { "prefer": "lattice" }
}
}
```
`prefer: lattice` selects the Lattice artifact. `prefer: local` also resolves to
it when the declared model is `erikkaum/lattice-retrieval`.
The recommended operating point is an int4-per-row, 512-dimensional artifact.
Int4 quantizes the model's lookup-table weights only. Layer writes the resulting
normalized vectors as `[512]f32`; Turbopuffer's int8 minimum for quantized
vector storage is a separate choice and is not used by this path.
## End-to-end example
Declare the Lattice profile on a string attribute, write rows, and query with
`Embed`. The gateway embeds both sides in-process — no external inference
provider is involved.
Write two rows into a namespace whose `text` attribute carries the profile
above:
```bash
curl -X POST "$LAYER_GATEWAY_URL/v2/namespaces/articles" \
-H "Authorization: Bearer $LAYER_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"upsert_rows": [
{"id": "planet-1", "title": "Planet",
"text": "Jupiter is the biggest planet in the Solar System."},
{"id": "photo-1", "title": "Photosynthesis",
"text": "Plants turn sunlight, water, and carbon dioxide into food."}
],
"schema": {
"text": {
"type": "string",
"embed": {
"model": "erikkaum/lattice-retrieval",
"dims": 512,
"serving": { "prefer": "lattice" }
}
}
}
}'
```
Query by meaning rather than exact phrase:
```bash
curl -X POST "$LAYER_GATEWAY_URL/v2/namespaces/articles/query" \
-H "Authorization: Bearer $LAYER_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"rank_by": ["text", "ANN", ["Embed", "largest planet in the solar system"]],
"top_k": 3,
"include_attributes": ["title", "text"]
}'
```
```jsonc
{
"rows": [
{ "id": "planet-1", "$dist": 0.137, "title": "Planet",
"text": "Jupiter is the biggest planet in the Solar System." }
],
"performance": {
"embedding_tokens": 7,
"embedding_ms": 1 // in-process lookup — no network hop to a provider
}
}
```
A live example of exactly this contract is the
[Wikipedia × Lattice demo](https://wiki.hevlayer.com): all 283,997 Simple
English Wikipedia articles (1.74M paragraph rows) embedded through Lattice and
searched on Turbopuffer, with the `performance` echo displayed beside each
result. Source at [github.com/hev/wiki](https://github.com/hev/wiki).
## Limits
- Text only. An image modality on a Lattice profile is a validation error.
- No [revision pins or instructions](/docs/pro/api/embed#model-settings). Those
extensions require a GPU-served profile.
- `embed.dims` must equal the sliced artifact's dimension. A mismatch is a
validation error at write time, not a silent reshape.
- A directory that fails to load stops the gateway at startup rather than
serving a namespace that cannot embed.
# License
Source: https://hevlayer.com/docs/pro/api/license
import CodeTabs from "../../../components/docs/CodeTabs.astro";
`GET /v2/license` returns the gateway's local license projection. It is an
operator and dashboard oracle: it never phones home, and it derives state from
the configured license key plus the gateway's codified grace cushion.
```bash
curl "$LAYER_GATEWAY_URL/v2/license" \
-H "Authorization: Bearer $LAYER_GATEWAY_API_KEY"
```
## Response
A valid key that is still within its licensed or grace window returns
`valid: true` and the key claims the gateway is using:
```json
{
"valid": true,
"sub": "acme-corp",
"tier": "design-partner",
"features": ["transform-runtime", "agents", "rbac", "warehouses", "doc-cache", "history", "cost"],
"limits": {"namespaces": 50, "udf_workers": 20},
"exp": "2026-12-14T00:00:00Z",
"gateway": {
"state": "licensed",
"seconds_to_deadline": 1209600,
"grace_seconds_remaining": 0
}
}
```
When the key is expired but still inside the gateway grace window,
`gateway.state` is `grace`, `valid` remains `true`, and
`grace_seconds_remaining` counts down to the floor.
Missing, invalid, or fully degraded licenses return `valid: false`:
```json
{
"valid": false,
"state": "floor",
"reason": "missing",
"gateway": {
"state": "floor",
"seconds_to_deadline": 0,
"grace_seconds_remaining": 0
}
}
```
Invalid keys use `reason` to report the verifier failure. Missing keys use
`reason: "missing"`.
## Fields
| Field | Present when | Meaning |
| --- | --- | --- |
| `valid` | Always | Whether the gateway currently treats the deployment as licensed or in grace. |
| `state` | Missing/invalid/floor key | Top-level floor marker for a missing or invalid license. |
| `reason` | Missing/invalid key | Human-readable verifier reason, or `missing`. |
| `sub` | Valid key | Licensed account or trial subject. |
| `tier` | Valid key | License tier label such as `trial` or `design-partner`. |
| `features` | Valid key | Feature strings the key enables. Absence denies the gated feature. |
| `limits` | Valid key | Numeric entitlement limits. Missing keys are unlimited for that dimension. |
| `exp` | Valid key | Key expiration timestamp. |
| `gateway.state` | Always | `licensed`, `grace`, or `floor` for the gateway surface. |
| `gateway.seconds_to_deadline` | Always | Seconds to `exp` while licensed, seconds to `exp + grace` while in grace, otherwise `0`. |
| `gateway.grace_seconds_remaining` | Always | Seconds left in gateway grace, otherwise `0`. |
Phase 1 reports the gateway surface. Operator and dashboard states use the same
`licensed` / `grace` / `floor` model, but they are not included in this response
until their enforcement surfaces ship.
## State Effects
| Gateway state | Gated route behavior | CE route behavior |
| --- | --- | --- |
| `licensed` | Feature-gated routes work if `features` includes the route's feature. | Always works. |
| `grace` | Feature-gated routes work and responses include `x-hevlayer-license-grace: true`. | Always works. |
| `floor` | Feature-gated routes return `402` with `error: "license_required"`. | Always works. |
The CE floor includes query, point read, write, scan, namespace metadata,
snapshot, and backend routing routes.
## Client Call