Getting Started¶
This walks you from a built binary to your first time-travel query in about ten minutes.
1. Run the server¶
# Create a data directory and an API key (prints the plaintext key ONCE)
telha api-key create --tenant <tenant-uuid> --org <org-uuid> --data-dir ./data
# Start serving
telha serve --data-dir ./data --rest-addr 127.0.0.1:8080
Notes:
- On Windows dev machines the release binary currently needs
C:\msys64\mingw64\binon PATH (packaging work in PR-084 removes this). - Configuration layers: defaults, then
telha.toml, thenTELHA_*environment variables (double underscore nests sections:TELHA_GRPC__TOKEN_KEY=...), then flags. - To enable gRPC and MCP, set
grpc.token_keyto a 64-hex secret. Gotcha: the value must contain at least one letter (an all-digit value is parsed as an integer by the config layer). - Health probes:
GET /healthz(liveness) andGET /readyz(readiness).
2. Write your first records¶
Everything is authenticated with the x-api-key header. Create a record with a validity interval and a relationship in one call:
curl -s -X POST http://127.0.0.1:8080/v1/records \
-H "x-api-key: $TELHA_API_KEY" -H "content-type: application/json" \
-d '{
"records": [{
"label": "CONTRACT_VERSION",
"properties": { "number": "C-1042", "clause": "Net 30", "riskScore": 2 },
"validTime": { "start": "2026-01-01T00:00:00Z" }
}]
}'
The response returns the record's logical id. Update it later with new properties: Telha appends a new version and closes the old one's transaction time. Nothing is edited in place.
3. Read it back, three ways¶
# Current state
curl -s http://127.0.0.1:8080/v1/records/<id> -H "x-api-key: $KEY"
# Full version history (paginated)
curl -s http://127.0.0.1:8080/v1/records/<id>/history -H "x-api-key: $KEY"
# Query with time travel: what did we BELIEVE on Feb 1 about what was TRUE on Jan 15?
curl -s -X POST http://127.0.0.1:8080/v1/query \
-H "x-api-key: $KEY" -H "content-type: application/json" \
-d '{
"find": "CONTRACT_VERSION",
"where": { "number": { "$eq": "C-1042" } },
"atValidTime": "2026-01-15T00:00:00Z",
"atTxTime": "2026-02-01T00:00:00Z"
}'
That last call is the heart of the product: two independent time axes. atValidTime asks about the world; atTxTime asks about what Telha knew at that moment. Corrections made after Feb 1 are invisible to it, exactly as an auditor would require.
4. Ingest a document¶
curl -s -X POST http://127.0.0.1:8080/v1/ingest \
-H "x-api-key: $KEY" -H "content-type: application/json" \
-d '{ "name": "supplier-review.pdf", "format": "docling", "contentBase64": "<...>" }'
# → { "jobId": "...", "status": "queued" } poll GET /v1/ingest/<jobId>
Formats: docling (PDF/DOCX/PPTX), tabular (CSV/XLSX), web (URL crawl), email (.eml/.msg), code, and json (structured records, applied synchronously with no worker round-trip). Document formats need at least one Python worker running: python -m workers_common.run docling_worker pointed at the server's gRPC address with a worker token (telha api-key worker-token --worker-id w1).
5. Use an SDK instead¶
import { TelhaClient } from "@telha/sdk";
const telha = new TelhaClient({ url: "http://127.0.0.1:8080", apiKey: process.env.TELHA_API_KEY });
const rows = await telha.query({ find: "CONTRACT_VERSION", where: { number: { $eq: "C-1042" } } });
from telha import TelhaClient
t = TelhaClient(url="http://127.0.0.1:8080", api_key=os.environ["TELHA_API_KEY"])
rows = t.query(find="CONTRACT_VERSION", where={"number": {"$eq": "C-1042"}})
Where to go next¶
- Understand what you just did: Core Concepts
- Connect real sources and write richer queries: Working with Data
- Ask questions in natural language with verified answers: AI Answers