API
Introduction
Layer matches the Turbopuffer wire contract so existing clients keep working when you point them at the gateway. Where a route has an upstream equivalent, the site documents what Layer adds — not the upstream behavior itself. Follow the Upstream docs link on each page for the underlying request/response shape.
Install
There are four ways to call Layer: the Python client, the Go client, the
TypeScript client, and the REST API itself. The clients are generated
from apps/layer-gateway/openapi.yaml, so all four expose the same
operations — every endpoint page on this site shows them side by side.
Anything the clients can do, plain HTTP can do.
pip install hevlayer # Python 3.11+
go get github.com/hev/layer/clients/go # Go 1.22+
npm install hevlayer # Node 18+
Point a client at the gateway:
import os
from hevlayer import AsyncHevlayer
client = AsyncHevlayer(
base_url=os.environ["LAYER_GATEWAY_URL"],
api_key=os.environ["LAYER_GATEWAY_API_KEY"],
)import (
"os"
hevlayer "github.com/hev/layer/clients/go"
)
client := hevlayer.NewClient(
hevlayer.WithBaseURL(os.Getenv("LAYER_GATEWAY_URL")),
hevlayer.WithAPIKey(os.Getenv("LAYER_GATEWAY_API_KEY")),
)import { Hevlayer } from "hevlayer";
const client = new Hevlayer({
baseUrl: process.env.LAYER_GATEWAY_URL,
apiKey: process.env.LAYER_GATEWAY_API_KEY,
});curl "$LAYER_GATEWAY_URL/v2/namespaces" \
-H "Authorization: Bearer $LAYER_GATEWAY_API_KEY" Code examples across these pages assume this client — and in Go, a
ctx context.Context. The cURL tab on each page is the bare REST
contract; any HTTP stack works the same way.
Authentication
Every request carries Authorization: Bearer <key>. The gateway accepts
two kinds of bearer:
- The store key. The default
VectorStorecredential (the Turbopuffer key you already own) is accepted as an admin bearer. This is the drop-in default: point an existing client at the gateway and keep your key. No setup, full access. - A minted key. Admin can mint keys scoped to a set of namespaces
crossed with
read/write— hand one to a team or a service without exposing the rest of the store. Minted keys are gateway-only and never work against the upstream directly. See API keys.
Routes are classified read, write, or admin; each endpoint page
notes anything beyond the obvious (GET/query-shaped routes are read,
namespace writes are write, Pipeline/Function/key management is
admin). A request past a key’s scope or namespace grant answers 403
with the reason named.
Connection environment variables:
| Variable | Purpose |
|---|---|
LAYER_GATEWAY_URL | Base URL of the gateway. |
LAYER_GATEWAY_API_KEY | Bearer token sent on every gateway request. In deriveFromStore mode this is the default VectorStore credential; in keys mode it is one of the configured inbound keys. |
TURBOPUFFER_API_KEY | Optional direct fallback key for Turbopuffer-compatible SDK calls when the gateway is unreachable. |
TURBOPUFFER_API_URL | Optional direct fallback base URL; defaults to https://aws-us-east-1.turbopuffer.com. |
Additional language targets are added through the SDK harness rather than maintained by hand.
Client fall-through
The Python, Go, and TypeScript SDKs can fall through to Turbopuffer direct when the
gateway is unreachable. The fallback is limited to calls that can be
satisfied without Layer state: simple vector queries and raw
Turbopuffer-compatible methods such as write_namespace /
WriteNamespace / writeNamespace, query_turbopuffer_namespace /
QueryTurbopufferNamespace / queryTurbopufferNamespace, and namespace schema/listing calls. The
clients emit a log warning and set the perf fallback field to
turbopuffer_direct when perf collection is enabled.
Fetches, warm jobs, pipelines, UDFs, nearest_to_id queries, and other
Layer-only workflows still fail fast because they depend on gateway-owned
cache, queue, history, or consistency state. Set
fallback_to_turbopuffer=False on AsyncHevlayer, or
WithFallbackToTurbopuffer(false) on the Go client, or
fallbackToTurbopuffer: false on the TypeScript client, to disable
direct fallback.
Enhancements to upstream routes
Each of the routes below is wire-compatible with Turbopuffer. The body of each section describes only what Layer overlays on top.
Write — POST /v2/namespaces/{ns}
- Best-effort Aerospike document-cache mirror before explicit-id upstream writes.
- Server-stamped
_hevlayer_upserted_aton every upsert and patch, which powers the consistency watermark on the query path. _hevlayer_*attributes are reserved — writes to them are rejected.
Page: Write.
Query — POST /v2/namespaces/{ns}/query
- Stable reads via an injected
_hevlayer_upserted_at <= watermarkpredicate while the upstream index isupdating. - One-shot 429 retry with the watermark filter forced on, for queries that race a write storm.
x-layer-stable-as-ofreturned on stable-read responses so callers can correlate freshness across reads.
Page: Query.
Metadata — GET /v2/namespaces/{ns}/metadata
- Proxied upstream verbatim, then enriched with a
layerblock containingstable_as_ofandis_stable.
Page: Namespace metadata.
Cache warm hint — GET /v1/namespaces/{ns}/hint_cache_warm
- With no query parameters: a raw upstream passthrough, response returned verbatim.
- With any warm option supplied: forwards the hint upstream and runs Layer-side warm steps — a warm job to backfill the Aerospike document cache from origin, plus a mirror of the latest S3 snapshot body into Aerospike. Each step is independently toggleable per request.
Page: Warm cache.
Cross-cutting conventions
These apply to every endpoint Layer proxies, whether the route is upstream-compatible or Layer-only.
_hevlayer_*reserved. Document attributes prefixed with_hevlayer_are reserved for the proxy layer. Writing to them is a validation error; reading them is fine when explicitly requested. The gateway stamps_hevlayer_upserted_atitself on every upsert and patch — a caller-supplied value is ignored and overwritten with the server’s epoch-ms watermark.- Hard vs soft failures. Turbopuffer write/query failures are hard failures and return 5xx. Aerospike document-cache failures are soft and never block the response.
x-layer-cacheheader. Fetch responses includehit,miss, ormiss-on-errorso callers can distinguish a cold cache from an outage.- Response headers. Reads that go through the watermark path include
x-layer-stable-as-of; query pagination usesx-layer-next-cursor. See Response headers.
Compatibility posture
Layer aims to be a drop-in for existing Turbopuffer clients. Routes that
the upstream does not implement are namespaced under /v2/ and do not
shadow upstream behavior. If a Turbopuffer client sends a request to a
route Layer doesn’t proxy, the gateway returns 404 — it does not
silently re-route to an upstream that might handle it differently.