API Reference
Base URL: https://lattice-gateway.<your-subdomain>.workers.dev (or http://localhost:8787 in development)
Health Check
Section titled “Health Check”GET /healthReturns system status. No authentication required.
curl https://lattice-gateway.workers.dev/health{ "status": "ok", "version": "0.1.0", "environment": "development", "timestamp": "2026-03-27T12:00:00.000Z"}Explorer UI
Section titled “Explorer UI”GET /Returns the Lattice Explorer — a single-page HTML application for browsing the entity hierarchy, viewing Telos state, and switching roles. Served directly from the Gateway Worker via raw HTML import.
curl https://lattice-gateway.workers.dev/List Entities
Section titled “List Entities”GET /api/v1/entitiesReturns a paginated list of entity summaries (metadata only, no Telos state).
Query Parameters
Section titled “Query Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
type | string | — | Filter by entity type |
parentId | string | — | Filter by parent entity ID |
status | string | — | Filter by status (active, inactive, archived) |
limit | number | 50 | Results per page (max 200) |
offset | number | 0 | Pagination offset |
Response Type
Section titled “Response Type”interface ListEntitiesResponse { entities: Array<{ id: string; metadata: EntityMetadata; }>; total: number; limit: number; offset: number;}Examples
Section titled “Examples”# List all entitiescurl https://lattice-gateway.workers.dev/api/v1/entities
# List all teamscurl "https://lattice-gateway.workers.dev/api/v1/entities?type=team"
# List children of the Engineering Departmentcurl "https://lattice-gateway.workers.dev/api/v1/entities?parentId=lat_dep_eng"
# List active people, page 2curl "https://lattice-gateway.workers.dev/api/v1/entities?type=person&status=active&limit=10&offset=10"Get Entity
Section titled “Get Entity”GET /api/v1/entities/:idReturns the full entity with Telos state, filtered by the caller’s role. Uses KV cache (5-minute TTL) with D1 fallback.
Response Type
Section titled “Response Type”interface GetEntityResponse { entity: Entity; _meta: { cachedAt: string | null; // ISO 8601 if served from cache, null if fresh from D1 version: number; };}Examples
Section titled “Examples”# Get the company entity as CEO (sees everything)curl -H "X-Lattice-Role: ceo" \ https://lattice-gateway.workers.dev/api/v1/entities/lat_com_meridian
# Get the same entity as a team member (budget hidden, strategies redacted)curl -H "X-Lattice-Role: team_member" \ https://lattice-gateway.workers.dev/api/v1/entities/lat_com_meridian
# Get a specific personcurl -H "X-Lattice-Role: ceo" \ https://lattice-gateway.workers.dev/api/v1/entities/lat_per_chen
# Get the Platform Teamcurl -H "X-Lattice-Role: dept_head" \ https://lattice-gateway.workers.dev/api/v1/entities/lat_tem_platformError Response (404)
Section titled “Error Response (404)”{ "error": "NOT_FOUND", "message": "Entity lat_per_nonexistent not found", "entityId": "lat_per_nonexistent"}Create Entity
Section titled “Create Entity”POST /api/v1/entitiesCreates a new entity under an existing parent. Generates a typed ID, emits an entity.created event, and returns the full entity.
Request Type
Section titled “Request Type”interface CreateEntityRequest { type: EntityType; parentId: string; metadata: { name: string; tags?: string[]; }; extension: EntityExtension["data"]; // Type-specific data}Response Type
Section titled “Response Type”interface CreateEntityResponse { entity: Entity; _meta: { version: 1 };}Example
Section titled “Example”# Create a new person under the Platform Teamcurl -X POST \ -H "Content-Type: application/json" \ -H "X-Lattice-Role: ceo" \ https://lattice-gateway.workers.dev/api/v1/entities \ -d '{ "type": "person", "parentId": "lat_tem_platform", "metadata": { "name": "Alex Rivera", "tags": ["backend", "new-hire"] }, "extension": { "email": "[email protected]", "title": "Platform Engineer", "reportsTo": "lat_per_chen", "directReports": [] } }'Validation Errors
Section titled “Validation Errors”400 VALIDATION_ERROR— missingtype,parentId, ormetadata.name400 VALIDATION_ERROR— invalid entity type404 PARENT_NOT_FOUND— parent entity does not exist
Update Entity
Section titled “Update Entity”PATCH /api/v1/entities/:idPartially updates an entity using optimistic concurrency control. The version field is required — if it does not match the current version in D1, the update is rejected with a 409 VERSION_CONFLICT.
Request Type
Section titled “Request Type”interface PatchEntityRequest { version: number; // Required: must match current version metadata?: Partial<Omit<EntityMetadata, "type" | "createdAt">>; telos?: Partial<TelosState>; extension?: { data: Partial<EntityExtension["data"]> };}Response Type
Section titled “Response Type”interface PatchEntityResponse { entity: Entity; _meta: { version: number; // New version after update eventsEmitted: string[]; // IDs of events created by this update };}Telos Update Behavior
Section titled “Telos Update Behavior”problemsandmission: updated directly on theentitiestable- Relational telos fields (
goals,challenges,strategies,metrics,work,budget,team): full replace — the existing rows are deleted and replaced with the new array - JSON telos fields (
narratives,projects,journal,ideas,beliefs,skills,documentation,sops,logs): upserted into thetelos_jsontable
Extension Update Behavior
Section titled “Extension Update Behavior”Shallow merge with existing extension data.
Examples
Section titled “Examples”# Update entity metadata (rename, add tags)curl -X PATCH \ -H "Content-Type: application/json" \ -H "X-Lattice-Role: ceo" \ https://lattice-gateway.workers.dev/api/v1/entities/lat_tem_platform \ -d '{ "version": 1, "metadata": { "name": "Core Platform Team", "tags": ["platform", "backend", "core", "v3"] } }'
# Update a team's goals (full replace)curl -X PATCH \ -H "Content-Type: application/json" \ -H "X-Lattice-Role: ceo" \ https://lattice-gateway.workers.dev/api/v1/entities/lat_tem_platform \ -d '{ "version": 2, "telos": { "goals": [ { "id": "goal_plat_engine", "title": "Complete v3 engine beta with 10x throughput", "description": "Deliver the beta release of the v3 orchestration engine", "measurable": "Beta passes load testing at 10x current peak with p99 < 100ms", "targetDate": "2026-07-31", "status": "in_progress", "parentGoalId": "goal_prod_platform" } ] } }'
# Update a person's missioncurl -X PATCH \ -H "Content-Type: application/json" \ -H "X-Lattice-Role: ceo" \ https://lattice-gateway.workers.dev/api/v1/entities/lat_per_priya \ -d '{ "version": 1, "telos": { "mission": "Make the v3 engine the fastest orchestration runtime on the market" } }'Version Conflict Error (409)
Section titled “Version Conflict Error (409)”{ "error": "VERSION_CONFLICT", "entityId": "lat_tem_platform", "currentVersion": 3, "requestedVersion": 1}Get Entity Events
Section titled “Get Entity Events”GET /api/v1/entities/:id/eventsReturns the event log for a specific entity, using sequence-based cursor pagination.
Query Parameters
Section titled “Query Parameters”| Parameter | Type | Default | Description |
|---|---|---|---|
after | number | 0 | Return events with seq > after |
limit | number | 50 | Max events to return (max 200) |
types | string | — | Comma-separated event type filter |
Response Type
Section titled “Response Type”interface GetEventsResponse { events: LatticeEvent[]; cursor: { lastSeq: number; hasMore: boolean; };}Examples
Section titled “Examples”# Get all events for the companycurl https://lattice-gateway.workers.dev/api/v1/entities/lat_com_meridian/events
# Poll for new events (long-polling pattern)curl "https://lattice-gateway.workers.dev/api/v1/entities/lat_com_meridian/events?after=42"
# Filter by event typecurl "https://lattice-gateway.workers.dev/api/v1/entities/lat_com_meridian/events?types=entity.updated,telos.field.updated"
# Paginate through event historycurl "https://lattice-gateway.workers.dev/api/v1/entities/lat_com_meridian/events?after=0&limit=20"Get Hierarchy Tree
Section titled “Get Hierarchy Tree”GET /api/v1/tree/:idReturns a recursive tree of entities starting from the given root. Each node contains the entity’s metadata and an array of children. Useful for rendering the full organizational chart from any starting point.
Response Type
Section titled “Response Type”interface EntityTreeNode { entity: { id: string; metadata: EntityMetadata }; children: EntityTreeNode[];}Examples
Section titled “Examples”# Get the full company tree (all tiers)curl https://lattice-gateway.workers.dev/api/v1/tree/lat_com_meridian
# Get the Products Division sub-treecurl https://lattice-gateway.workers.dev/api/v1/tree/lat_div_products
# Get the Engineering Department sub-treecurl https://lattice-gateway.workers.dev/api/v1/tree/lat_dep_engNote: Archived entities (status = "archived") are excluded from tree results. The tree is built recursively — for large hierarchies this may incur multiple D1 queries.
Check Policy
Section titled “Check Policy”POST /api/v1/entities/:id/policy/checkEvaluates a policy check against the policies table. Returns the decision (allow or deny), the matched policy ID (if any), and a human-readable reason.
Request Type
Section titled “Request Type”interface PolicyCheckRequest { subject: string; // Entity ID or role action: string; // "read", "write", "execute", etc. object: string; // Entity ID or pattern context?: Record<string, unknown>;}Response Type
Section titled “Response Type”interface PolicyCheckResponse { decision: "allow" | "deny"; matchedPolicy: string | null; reason: string;}Evaluation Logic
Section titled “Evaluation Logic”- Query policies where
subjectmatches the request subject OR the caller’s role, ANDactionmatches, ANDobjectmatches the request object or is*(wildcard) - Sort deny rules before allow rules
- Return the first match
- If no match: default deny
Example
Section titled “Example”# Check if a team member can read the budget entitycurl -X POST \ -H "Content-Type: application/json" \ -H "X-Lattice-Role: team_member" \ https://lattice-gateway.workers.dev/api/v1/entities/lat_com_meridian/policy/check \ -d '{ "subject": "team_member", "action": "read", "object": "budget" }'Default Deny Response
Section titled “Default Deny Response”{ "decision": "deny", "matchedPolicy": null, "reason": "No matching policy found — default deny"}