openlatch-client-schemas 0.1.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,52 @@
1
+ # Dependencies
2
+ *.swp
3
+ *.swo
4
+ *.pyc
5
+ __pycache__/
6
+
7
+ # Environment variables
8
+ .env
9
+ .env.local
10
+ .env.*.local
11
+
12
+ # IDE
13
+ .vscode/
14
+ .idea/
15
+ *.swp
16
+ *.swo
17
+ *~
18
+ Thumbs.db
19
+ .DS_Store
20
+
21
+ # Build outputs
22
+ target/
23
+ dist/
24
+ build/
25
+
26
+ # Schemas package build staging — canonical source lives in schemas/; CI copies
27
+ # into these paths before publishing @openlatch/client-schemas (npm) and
28
+ # openlatch-client-schemas (PyPI). Not committed to avoid duplicate sources.
29
+ npm/client-schemas/schemas/
30
+ pypi/openlatch-client-schemas/src/openlatch_client_schemas/schemas/
31
+ pypi/openlatch-client-schemas/dist/
32
+
33
+ # Docker
34
+ *.pid
35
+ *.sock
36
+
37
+ # Secrets
38
+ *.pem
39
+ *.key
40
+
41
+ # CI CD
42
+ coverage/
43
+ /target-test
44
+
45
+ # AI Agents
46
+ CLAUDE.md
47
+ CLAUDE.local.md
48
+ .claude/
49
+ .planning/
50
+ .brainstorming/
51
+ /.brainstorms
52
+ .worktreeinclude
@@ -0,0 +1,50 @@
1
+ Metadata-Version: 2.4
2
+ Name: openlatch-client-schemas
3
+ Version: 0.1.4
4
+ Summary: OpenLatch client wire-format JSON Schemas — canonical contract for events exchanged between openlatch-client and openlatch-platform
5
+ Project-URL: Homepage, https://openlatch.ai
6
+ Project-URL: Repository, https://github.com/OpenLatch/openlatch-client
7
+ Project-URL: Changelog, https://github.com/OpenLatch/openlatch-client/blob/main/CHANGELOG.md
8
+ Author: OpenLatch
9
+ License: Apache-2.0
10
+ Keywords: contract,json-schema,openlatch,schemas
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+
21
+ # openlatch-client-schemas
22
+
23
+ Canonical JSON Schemas for the openlatch-client wire format. This package is the source of truth for the contract between [openlatch-client](https://github.com/OpenLatch/openlatch-client) (Rust) and [openlatch-platform](https://github.com/OpenLatch/openlatch-platform) (Python + React).
24
+
25
+ ## Usage
26
+
27
+ ```python
28
+ from openlatch_client_schemas import schemas_path, load, load_all
29
+
30
+ schemas_path() # pathlib.Path to the bundled schemas/ directory
31
+ load_all() # {"enums": {...}, "event-envelope": {...}, ...}
32
+ load("event-envelope") # parsed schema for one file
33
+ ```
34
+
35
+ ## Contents
36
+
37
+ | File | Purpose |
38
+ |---|---|
39
+ | `enums.schema.json` | `AgentType`, `HookEventType`, `Verdict` |
40
+ | `event-envelope.schema.json` | `EventEnvelope` wire-format |
41
+ | `verdict-response.schema.json` | `VerdictResponse` returned to agent hooks |
42
+ | `cloud-ingestion-request.schema.json` | `CloudIngestionRequest` sent to platform |
43
+ | `cloud-ingestion-response.schema.json` | `CloudIngestionResponse` from platform |
44
+ | `auth-me-response.schema.json` | `AuthMeResponse` for `/api/v1/users/me` |
45
+
46
+ Version is synchronized with the `openlatch-client` crate — every published version corresponds to the binary release of the same version.
47
+
48
+ ## Breaking Changes
49
+
50
+ Breaking schema changes require a major version bump. Consumers pinning an exact version will not be silently broken. See the [openlatch-client CHANGELOG](https://github.com/OpenLatch/openlatch-client/blob/main/CHANGELOG.md) for what changed.
@@ -0,0 +1,30 @@
1
+ # openlatch-client-schemas
2
+
3
+ Canonical JSON Schemas for the openlatch-client wire format. This package is the source of truth for the contract between [openlatch-client](https://github.com/OpenLatch/openlatch-client) (Rust) and [openlatch-platform](https://github.com/OpenLatch/openlatch-platform) (Python + React).
4
+
5
+ ## Usage
6
+
7
+ ```python
8
+ from openlatch_client_schemas import schemas_path, load, load_all
9
+
10
+ schemas_path() # pathlib.Path to the bundled schemas/ directory
11
+ load_all() # {"enums": {...}, "event-envelope": {...}, ...}
12
+ load("event-envelope") # parsed schema for one file
13
+ ```
14
+
15
+ ## Contents
16
+
17
+ | File | Purpose |
18
+ |---|---|
19
+ | `enums.schema.json` | `AgentType`, `HookEventType`, `Verdict` |
20
+ | `event-envelope.schema.json` | `EventEnvelope` wire-format |
21
+ | `verdict-response.schema.json` | `VerdictResponse` returned to agent hooks |
22
+ | `cloud-ingestion-request.schema.json` | `CloudIngestionRequest` sent to platform |
23
+ | `cloud-ingestion-response.schema.json` | `CloudIngestionResponse` from platform |
24
+ | `auth-me-response.schema.json` | `AuthMeResponse` for `/api/v1/users/me` |
25
+
26
+ Version is synchronized with the `openlatch-client` crate — every published version corresponds to the binary release of the same version.
27
+
28
+ ## Breaking Changes
29
+
30
+ Breaking schema changes require a major version bump. Consumers pinning an exact version will not be silently broken. See the [openlatch-client CHANGELOG](https://github.com/OpenLatch/openlatch-client/blob/main/CHANGELOG.md) for what changed.
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "openlatch-client-schemas"
7
+ version = "0.1.4"
8
+ description = "OpenLatch client wire-format JSON Schemas — canonical contract for events exchanged between openlatch-client and openlatch-platform"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "Apache-2.0" }
12
+ authors = [{ name = "OpenLatch" }]
13
+ keywords = ["openlatch", "json-schema", "contract", "schemas"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "License :: OSI Approved :: Apache Software License",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ ]
23
+
24
+ [project.urls]
25
+ Homepage = "https://openlatch.ai"
26
+ Repository = "https://github.com/OpenLatch/openlatch-client"
27
+ Changelog = "https://github.com/OpenLatch/openlatch-client/blob/main/CHANGELOG.md"
28
+
29
+ [tool.hatch.build.targets.wheel]
30
+ packages = ["src/openlatch_client_schemas"]
31
+
32
+ [tool.hatch.build.targets.sdist]
33
+ include = [
34
+ "src/openlatch_client_schemas/**/*.py",
35
+ "src/openlatch_client_schemas/schemas/*.schema.json",
36
+ "README.md",
37
+ ]
@@ -0,0 +1,35 @@
1
+ """Canonical JSON Schemas for the openlatch-client wire format.
2
+
3
+ This package is the source of truth for the contract between openlatch-client
4
+ (Rust) and openlatch-platform (Python + React). Version is synchronized with
5
+ the openlatch-client crate.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ from importlib.resources import files
12
+ from pathlib import Path
13
+ from typing import Any
14
+
15
+ __all__ = ["schemas_path", "load", "load_all"]
16
+
17
+
18
+ def schemas_path() -> Path:
19
+ """Return the filesystem path to the bundled schemas/ directory."""
20
+ return Path(str(files(__name__).joinpath("schemas")))
21
+
22
+
23
+ def load(name: str) -> dict[str, Any]:
24
+ """Load a single schema by stem name (e.g. 'event-envelope')."""
25
+ resource = files(__name__).joinpath("schemas").joinpath(f"{name}.schema.json")
26
+ return json.loads(resource.read_text(encoding="utf-8"))
27
+
28
+
29
+ def load_all() -> dict[str, dict[str, Any]]:
30
+ """Load every bundled schema, keyed by stem name."""
31
+ out: dict[str, dict[str, Any]] = {}
32
+ root = schemas_path()
33
+ for p in sorted(root.glob("*.schema.json")):
34
+ out[p.name.removesuffix(".schema.json")] = json.loads(p.read_text(encoding="utf-8"))
35
+ return out
@@ -0,0 +1,40 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.openlatch.ai/client/v1/auth-me-response.schema.json",
4
+ "title": "AuthMeResponse",
5
+ "description": "Response from GET /api/v1/users/me for auth status validation (D-19) and PostHog identity stitching (telemetry Phase C). user_db_id, when present, is used as the persistent distinct_id and triggers a one-time $create_alias merging prior agent_id events into the platform person. Mirrors the `id` field on the platform side; both carry the stable better-auth user TEXT primary key.",
6
+ "type": "object",
7
+ "additionalProperties": true,
8
+ "x-postgresql-skip": true,
9
+ "properties": {
10
+ "id": {
11
+ "type": "string",
12
+ "description": "Stable database identifier for the authenticated user (better-auth user.id). Mirror of user_db_id — either field may be read; prefer user_db_id for telemetry alias semantics."
13
+ },
14
+ "user_db_id": {
15
+ "type": "string",
16
+ "description": "Stable database identifier for the authenticated user. Used as the PostHog distinct_id post-auth and as the alias target for $create_alias. Optional in this client schema for backwards compatibility — older platforms may not return it; client falls back to agent_id and skips the alias when absent."
17
+ },
18
+ "email": {
19
+ "type": "string",
20
+ "description": "Email of the authenticated user."
21
+ },
22
+ "organization_id": {
23
+ "type": "string",
24
+ "description": "Organization id for the user's active organization."
25
+ },
26
+ "organization_name": {
27
+ "type": "string",
28
+ "description": "Human-readable display name of the user's active organization. Surfaced by the client on re-runs of `openlatch init` so the user can confirm which org their cached credential belongs to. Optional \u2014 when absent, the client displays `Authenticated` without the parenthetical org suffix."
29
+ }
30
+ },
31
+ "examples": [
32
+ {
33
+ "id": "usr_019d8af1-f8da-73b3-92eb-79a99e59b10b",
34
+ "user_db_id": "usr_019d8af1-f8da-73b3-92eb-79a99e59b10b",
35
+ "email": "alice@example.com",
36
+ "organization_id": "a1b2c3d4-e5f6-4000-a000-000000000001",
37
+ "organization_name": "Acme Corp"
38
+ }
39
+ ]
40
+ }
@@ -0,0 +1,33 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.openlatch.ai/client/v1/cloud-ingestion-request.schema.json",
4
+ "title": "CloudIngestionRequest",
5
+ "description": "HTTP request body for POST /api/v1/events/ingest sent by openlatch-client. CloudEvents v1.0.2 batch mode — a bare JSON array of EventEnvelope objects, sent with Content-Type: application/cloudevents-batch+json. Client-wide metadata (schema_version, agent_id) is carried on each CloudEvent via extension attributes rather than a wrapper object.",
6
+ "type": "array",
7
+ "x-postgresql-skip": true,
8
+ "minItems": 1,
9
+ "maxItems": 100,
10
+ "items": {
11
+ "$ref": "event-envelope.schema.json#/$defs/EventEnvelope"
12
+ },
13
+ "examples": [
14
+ [
15
+ {
16
+ "specversion": "1.0",
17
+ "id": "evt_019d8af1-f8da-73b3-92eb-79a99e59b10b",
18
+ "source": "claude-code",
19
+ "type": "pre_tool_use",
20
+ "time": "2026-04-16T12:00:00Z",
21
+ "datacontenttype": "application/json",
22
+ "subject": "sess_abc123",
23
+ "data": {
24
+ "tool_name": "Bash",
25
+ "tool_input": {"command": "ls -la"}
26
+ },
27
+ "os": "linux",
28
+ "arch": "x86_64",
29
+ "clientversion": "0.2.0"
30
+ }
31
+ ]
32
+ ]
33
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.openlatch.ai/client/v1/cloud-ingestion-response.schema.json",
4
+ "title": "CloudIngestionResponse",
5
+ "description": "HTTP response body for POST /api/v1/events/ingest returned to openlatch-client. The client uses status to determine whether to retry, and event_id to correlate verdicts.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "x-postgresql-skip": true,
9
+ "required": [
10
+ "status"
11
+ ],
12
+ "properties": {
13
+ "status": {
14
+ "type": "string",
15
+ "description": "Ingestion outcome — accepted means persisted (or duplicate), rejected means permanently invalid.",
16
+ "enum": ["accepted", "rejected"]
17
+ },
18
+ "event_id": {
19
+ "type": "string",
20
+ "description": "Server-assigned UUIDv7 event_id for the stored event. Present when status is accepted."
21
+ },
22
+ "error": {
23
+ "type": "string",
24
+ "description": "Human-readable error description. Present when status is rejected."
25
+ }
26
+ },
27
+ "examples": [
28
+ {
29
+ "status": "accepted",
30
+ "event_id": "019d8af1-f8da-73b3-92eb-79a99e59b10b"
31
+ },
32
+ {
33
+ "status": "rejected",
34
+ "error": "Envelope failed schema validation: missing required attribute 'specversion'"
35
+ }
36
+ ]
37
+ }
@@ -0,0 +1,72 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.openlatch.ai/client/v1/enums.schema.json",
4
+ "title": "OpenLatch Client Enums",
5
+ "description": "Shared string types for the openlatch-client wire format. HookEventType and AgentType are OPEN strings — any string is valid. The x-known-values vocabularies are informational hints for tooling and telemetry. Verdict remains a closed enum because it is the cloud→client response surface and the client must branch exhaustively on it.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "properties": {},
9
+ "x-postgresql-skip": true,
10
+ "$defs": {
11
+ "AgentType": {
12
+ "type": "string",
13
+ "description": "CloudEvents 'source' attribute value — the agent platform identifier that emitted the event. Client forwards any string verbatim; the list below is the canonical set of agent platforms recognised by current OpenLatch tooling. Unknown values are preserved and forwarded unchanged (surfaced in Rust as AgentType::Unknown(String) via the tagged-enum lens).",
14
+ "examples": [
15
+ "claude-code",
16
+ "cursor",
17
+ "windsurf",
18
+ "github-copilot",
19
+ "codex-cli",
20
+ "gemini-cli",
21
+ "cline",
22
+ "openclaw"
23
+ ],
24
+ "x-known-values": [
25
+ "claude-code",
26
+ "cursor",
27
+ "windsurf",
28
+ "github-copilot",
29
+ "codex-cli",
30
+ "gemini-cli",
31
+ "cline",
32
+ "openclaw"
33
+ ]
34
+ },
35
+ "HookEventType": {
36
+ "type": "string",
37
+ "description": "CloudEvents 'type' attribute value — the hook event lifecycle name. Client forwards any string verbatim; the list below is the canonical set recognised by current OpenLatch tooling. Unknown values are preserved and forwarded unchanged (surfaced in Rust as HookEventType::Unknown(String) via the tagged-enum lens). The per-agent x-known-values vocabulary records each agent's native event names; every listed value MUST have a matching Rust variant enforced at compile time by build.rs.",
38
+ "examples": [
39
+ "pre_tool_use",
40
+ "post_tool_use",
41
+ "user_prompt_submit",
42
+ "stop",
43
+ "notification",
44
+ "pre_compact",
45
+ "session_start",
46
+ "session_end",
47
+ "subagent_stop"
48
+ ],
49
+ "x-known-values": [
50
+ "pre_tool_use",
51
+ "post_tool_use",
52
+ "user_prompt_submit",
53
+ "notification",
54
+ "stop",
55
+ "subagent_stop",
56
+ "pre_compact",
57
+ "session_start",
58
+ "session_end"
59
+ ]
60
+ },
61
+ "Verdict": {
62
+ "type": "string",
63
+ "description": "Verdict returned to the agent hook. Closed enum — client must handle all three variants exhaustively. allow = proceed normally, approve = user-confirmed allow, deny = blocked.",
64
+ "enum": [
65
+ "allow",
66
+ "approve",
67
+ "deny"
68
+ ]
69
+ }
70
+ },
71
+ "examples": [{}]
72
+ }
@@ -0,0 +1,113 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.openlatch.ai/client/v1/event-envelope.schema.json",
4
+ "title": "EventEnvelope",
5
+ "description": "CloudEvents v1.0.2 structured-mode envelope for agent hook events. Content-Type is application/cloudevents+json (single) or application/cloudevents-batch+json (batch). The 'data' field contains the raw agent payload untouched; all OpenLatch metadata lives in CloudEvents extension attributes. Extension attribute names MUST match ^[a-z0-9]+$ per the CloudEvents spec. verdict and latency_ms are NOT on the wire — they are produced by the daemon after processing and attached to stored events as the olverdict and ollatencyms extension attributes.",
6
+ "type": "object",
7
+ "additionalProperties": true,
8
+ "x-postgresql-skip": true,
9
+ "required": [
10
+ "specversion",
11
+ "id",
12
+ "source",
13
+ "type",
14
+ "time"
15
+ ],
16
+ "properties": {
17
+ "specversion": {
18
+ "type": "string",
19
+ "const": "1.0",
20
+ "description": "CloudEvents spec version. MUST be '1.0' for CloudEvents v1.0.2."
21
+ },
22
+ "id": {
23
+ "type": "string",
24
+ "description": "Unique event identifier — UUIDv7 with 'evt_' prefix. CloudEvents core attribute."
25
+ },
26
+ "source": {
27
+ "$ref": "enums.schema.json#/$defs/AgentType",
28
+ "description": "Agent platform identifier (was 'agent_platform'). CloudEvents core attribute. Bare string per OpenLatch convention; any string is valid. See x-known-values in enums.schema.json#/$defs/AgentType for the canonical set."
29
+ },
30
+ "type": {
31
+ "$ref": "enums.schema.json#/$defs/HookEventType",
32
+ "description": "Hook event lifecycle name (was 'event_type'). CloudEvents core attribute. Any string is valid. See x-known-values in enums.schema.json#/$defs/HookEventType for the canonical set."
33
+ },
34
+ "time": {
35
+ "type": "string",
36
+ "format": "date-time",
37
+ "description": "Event creation timestamp (was 'timestamp'). RFC 3339 UTC with Z suffix. CloudEvents core attribute."
38
+ },
39
+ "datacontenttype": {
40
+ "type": "string",
41
+ "const": "application/json",
42
+ "description": "Media type of the 'data' field. CloudEvents core optional attribute. Fixed to application/json for all OpenLatch events."
43
+ },
44
+ "subject": {
45
+ "type": "string",
46
+ "description": "CloudEvents 'subject' attribute. OpenLatch uses this for the agent session identifier (was 'session_id'). Consumers can group events by subject for per-session analytics."
47
+ },
48
+ "data": {
49
+ "description": "Raw agent payload, forwarded verbatim. Shape is agent-specific (e.g. Claude Code PreToolUse emits { tool_name, tool_input, … }; Cursor beforeShellExecution emits { command, … }). OpenLatch does NOT normalise this field."
50
+ },
51
+ "os": {
52
+ "type": "string",
53
+ "description": "OpenLatch extension. Operating system ('linux', 'macos', 'windows'). CloudEvents extension — lowercase alphanumeric attribute name."
54
+ },
55
+ "arch": {
56
+ "type": "string",
57
+ "description": "OpenLatch extension. CPU architecture ('x86_64', 'aarch64')."
58
+ },
59
+ "localipv4": {
60
+ "type": "string",
61
+ "format": "ipv4",
62
+ "description": "OpenLatch extension (was 'local_ipv4'). Machine's local IPv4 address. Detected once at daemon startup, cached for the process lifetime. Omitted when no non-loopback interface is available."
63
+ },
64
+ "localipv6": {
65
+ "type": "string",
66
+ "format": "ipv6",
67
+ "description": "OpenLatch extension (was 'local_ipv6'). Machine's local IPv6 address."
68
+ },
69
+ "publicipv4": {
70
+ "type": "string",
71
+ "format": "ipv4",
72
+ "description": "OpenLatch extension (was 'public_ipv4'). Machine's public IPv4 address."
73
+ },
74
+ "publicipv6": {
75
+ "type": "string",
76
+ "format": "ipv6",
77
+ "description": "OpenLatch extension (was 'public_ipv6'). Machine's public IPv6 address."
78
+ },
79
+ "clientversion": {
80
+ "type": "string",
81
+ "description": "OpenLatch extension (was 'client_version'). Semver of the openlatch-client that emitted the envelope."
82
+ },
83
+ "agentversion": {
84
+ "type": "string",
85
+ "description": "OpenLatch extension (was 'agent_version'). Agent software version, if reported by the hook."
86
+ },
87
+ "agentid": {
88
+ "type": "string",
89
+ "description": "OpenLatch extension. Stamped by the daemon on outbound events — identifies the AI agent install (one openlatch-client installation) that emitted this event (agt_<uuid>)."
90
+ }
91
+ },
92
+ "examples": [
93
+ {
94
+ "specversion": "1.0",
95
+ "id": "evt_019d8af1-f8da-73b3-92eb-79a99e59b10b",
96
+ "source": "claude-code",
97
+ "type": "pre_tool_use",
98
+ "time": "2026-04-16T12:00:00Z",
99
+ "datacontenttype": "application/json",
100
+ "subject": "sess_abc123",
101
+ "data": {
102
+ "tool_name": "Bash",
103
+ "tool_input": {"command": "ls -la"}
104
+ },
105
+ "os": "linux",
106
+ "arch": "x86_64",
107
+ "localipv4": "192.168.1.42",
108
+ "publicipv4": "203.0.113.7",
109
+ "clientversion": "0.2.0",
110
+ "agentversion": "1.2.0"
111
+ }
112
+ ]
113
+ }
@@ -0,0 +1,73 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.openlatch.ai/client/v1/verdict-response.schema.json",
4
+ "title": "VerdictResponse",
5
+ "description": "Verdict response returned to the agent hook after processing. The client passes this through to the agent hook without interpreting the verdict itself. Mirrors the cloud response schema.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "x-postgresql-skip": true,
9
+ "required": [
10
+ "schema_version",
11
+ "verdict",
12
+ "event_id",
13
+ "latency_ms"
14
+ ],
15
+ "properties": {
16
+ "schema_version": {
17
+ "type": "string",
18
+ "description": "Schema version for forward compatibility. Currently '1.0'."
19
+ },
20
+ "verdict": {
21
+ "$ref": "enums.schema.json#/$defs/Verdict",
22
+ "description": "The verdict: allow = proceed, approve = user-confirmed allow, deny = blocked."
23
+ },
24
+ "event_id": {
25
+ "type": "string",
26
+ "description": "Server-assigned or client-generated ID of the event this verdict responds to."
27
+ },
28
+ "latency_ms": {
29
+ "type": "number",
30
+ "minimum": 0,
31
+ "description": "Total end-to-end processing latency in milliseconds, including cloud round-trip when applicable."
32
+ },
33
+ "reason": {
34
+ "type": "string",
35
+ "description": "Human-readable explanation for the verdict. Omitted for allow verdicts."
36
+ },
37
+ "severity": {
38
+ "type": "string",
39
+ "description": "Threat severity level (e.g., 'critical', 'high', 'medium', 'low'). Omitted when no threat was detected."
40
+ },
41
+ "threat_category": {
42
+ "type": "string",
43
+ "description": "Category of detected threat (e.g., 'credential_exfiltration', 'command_injection'). Omitted when no threat detected."
44
+ },
45
+ "rule_id": {
46
+ "type": "string",
47
+ "description": "Identifier of the detection rule that triggered this verdict. Omitted when no rule matched."
48
+ },
49
+ "details_url": {
50
+ "type": "string",
51
+ "description": "URL to the OpenLatch dashboard with detailed event analysis. Omitted when not available."
52
+ }
53
+ },
54
+ "examples": [
55
+ {
56
+ "schema_version": "1.0",
57
+ "verdict": "allow",
58
+ "event_id": "019d8af1-f8da-73b3-92eb-79a99e59b10b",
59
+ "latency_ms": 42
60
+ },
61
+ {
62
+ "schema_version": "1.0",
63
+ "verdict": "deny",
64
+ "event_id": "019d8af1-f8da-73b3-92eb-000000000002",
65
+ "latency_ms": 88,
66
+ "reason": "Credential detected in tool output",
67
+ "severity": "critical",
68
+ "threat_category": "credential_detection",
69
+ "rule_id": "rule_cred_001",
70
+ "details_url": "https://app.openlatch.ai/events/019d8af1-f8da-73b3-92eb-000000000002"
71
+ }
72
+ ]
73
+ }