Skip to content

Observability Event Schema

This page is the data reference for what Lander reports to the control plane: the observability event, and the device registration and inventory payloads. For how these are produced and consumed, see Observability events. For the HTTP endpoints, see the API Reference.

One event describes one MCP tool call. Events are sent in batches to POST /v1/devices/events and stored for the event browser and summary.

FieldTypeDescription
event_timetimestampWhen the call occurred (endpoint clock)
agent_typestringCalling agent, e.g. claude-code, gemini-cli
mcp_namestringMCP server invoked
toolstringTool called on that server
event_typestringKind of event (invocation, result, error)
resultenumallowed, denied, or error
deny_codestringMachine code for a deny (when result = denied)
deny_reasonstringHuman-readable deny explanation
error_messagestringError detail (when result = error)
rule_appliedstringThe rule/policy that produced a deny
modelstringModel driving the agent, when known
session_idstringGroups calls within one agent session
groupstringOrganizational grouping
actor_emailstringHuman owner of the device/agent
tokens_inintegerInput tokens attributed to the call
tokens_outintegerOutput tokens attributed to the call
duration_msintegerCall duration in milliseconds
skillsstring[]Skill names involved
promptstringRequest prompt, optionally truncated
metadataobjectArbitrary additional fields

On the server, each stored event is also stamped with received_at (server clock), the verified device_id / serial_number, and the source IP.

{
"event_time": "2026-06-22T15:04:05Z",
"agent_type": "claude-code",
"mcp_name": "github",
"tool": "list_issues",
"event_type": "result",
"result": "allowed",
"model": "claude-opus-4-8",
"session_id": "s_8f2c…",
"actor_email": "dev@example.com",
"tokens_in": 1820,
"tokens_out": 340,
"duration_ms": 412,
"skills": [],
"prompt": "list open issues in the repo",
"metadata": {}
}
{
"event_time": "2026-06-22T15:06:10Z",
"agent_type": "claude-code",
"mcp_name": "github",
"tool": "delete_repo",
"event_type": "invocation",
"result": "denied",
"deny_code": "TOOL_DISABLED",
"deny_reason": "Tool 'delete_repo' is disabled by policy",
"rule_applied": "disabled-tools",
"actor_email": "dev@example.com",
"duration_ms": 2
}

Sent to POST /v1/devices/register, signed with the device key and carrying the authenticated user’s bearer token — this endpoint is the one device route that requires user authentication (see Authenticated enrollment).

FieldTypeDescription
serialNumberstringHardware serial or persisted fallback UUID
brandstringApple (hardware) or lander (fallback)
modelstringHardware model or hostname
certificatestring (PEM)Self-signed device certificate
ownerEmailstringIgnored for ownership. Accepted for wire compatibility and kept in the canonical signed payload, but never resolved to a user — the owner is the authenticated caller
clientTimestamptimestamp (RFC3339)Signing timestamp
signaturestring (base64)Signature over the canonical payload

Response: deviceId, certificateFingerprint, and ownerAssigned — now always true, since the owner is taken from the token’s subject rather than matched from a claimed address. Without a valid token the request is rejected with 401 and no device is created.

Sent to POST /v1/devices/inventory (signed via the X-Device-Signature header). Reports agents and their MCPs — names and transports only, never the command/args/env that may carry secrets (see Security & audit).

{
"certificate": "-----BEGIN CERTIFICATE-----\n",
"clientTimestamp": "2026-06-22T15:00:00Z",
"agents": [
{
"agentType": "claude-code",
"displayName": "Claude Code",
"mcps": [
{ "name": "github", "enabled": true, "transport": "stdio" },
{ "name": "postgres", "enabled": true, "transport": "http" }
]
}
]
}

Response: success, deviceId, agentsIn, mcpsIn, and receivedAt.

FieldTypeDescription
namestringMCP server name
enabledbooleanWhether it’s enabled for the agent
transportstringstdio, http, or sse