Files
inter-hub/contracts/functional/interaction-reporting-v1.md
tegwick 5c13de1b8f
All checks were successful
Build and Deploy / build-push-deploy (push) Successful in 3m6s
Make hub discovery public
2026-06-14 22:48:53 +02:00

175 lines
5.4 KiB
Markdown

# Interaction Reporting API Contract
**Name:** interaction-reporting
**Version:** 1.0
**Date:** 2026-03-31
**Status:** Active
**Layer:** Functional
**Maturity:** Stable
---
## Purpose
Defines the REST API surface for external systems (non-IHP adapters, domain
hubs, third-party tools) to submit interaction events and annotations to the
IHF without coupling to the IHP server-side implementation.
---
## Canonical Source of Truth
The authoritative runtime contract is the active row in the
`interaction_reporting_contracts` table. This file is the discoverable
human-readable declaration. In case of conflict, the database row governs.
---
## Endpoint
```
POST /api/v1/interaction-events
```
Authentication: `Authorization: Bearer <hub-api-key>`
The `hub-api-key` must match the `api_key` column of a registered hub.
---
## Required Request Fields
| Field | Type | Description |
|---|---|---|
| `widget_id` | UUID | The governed widget's stable ID |
| `event_type` | TEXT | Must exist in `event_type_registry` with `status = 'active'` |
| `occurred_at` | ISO 8601 timestamp | When the event occurred on the client |
---
## Optional Request Fields
| Field | Type | Description |
|---|---|---|
| `actor_id` | UUID | The acting user's ID |
| `actor_type` | TEXT | `user`, `agent`, `automation`, `external_adapter` |
| `view_context_ref` | TEXT | View path where event occurred |
| `metadata` | JSON object | Arbitrary additional context |
---
## Response — Success (201 Created)
```json
{
"id": "<uuid>",
"widget_id": "<uuid>",
"event_type": "clicked",
"occurred_at": "2026-03-31T12:00:00Z"
}
```
---
## Response — Validation Error (422 Unprocessable Entity)
```json
{
"error": "event_type 'pipeline_started' not registered",
"help": "Register this event type via the Type Registry admin UI or hub capability manifest before submitting."
}
```
---
## Response — Auth Error (401 Unauthorized)
```json
{
"error": "Authorization: Bearer <hub-api-key> required"
}
```
---
## Accepted Event Types
Accepted event types are all entries in `event_type_registry` with
`status = 'active'`. The framework-level seed vocabulary:
`viewed`, `focused`, `clicked`, `submitted`, `abandoned`, `retried`,
`failed`, `commented`, `flagged_confusing`, `flagged_helpful`,
`blocked_by_policy`, `escalated`, `accepted_recommendation`,
`rejected_recommendation`
Domain hubs may register additional event types via `HubCapabilityManifest`.
---
## Versioning Policy
- v1.0: current version. Stable.
- Adding new optional request fields: minor version (v1.1), no breaking change.
- Changing required fields, response shape, or auth scheme: major version (v2.0).
- Phase 9 will introduce `/api/v2/` with OAuth 2.0 replacing per-hub Bearer tokens.
v1.0 will remain supported during the migration window.
---
## Implementation Reference
- Controller: `Web/Controller/ApiInteractionEvents.hs`
- Route: `Web/Routes.hs` (`CanRoute ApiInteractionEventsController`)
- DB record: `interaction_reporting_contracts` (contract_version = '1.0')
---
## Phase 9 Extension: `/api/v2/` (IHUB-WP-0010)
The v2 API supports authenticated Bearer access with static API keys and, where
configured, OAuth 2.0 client credentials.
**OpenAPI spec:** `/api/v2/openapi.json` (live-generated; `widget_type`,
`event_type`, and `category` fields carry `enum` arrays from the type registries)
`GET /api/v2/hubs` and the vocabulary registry list endpoints are public
discovery surfaces. Mutating bootstrap operations still require Bearer access.
**New endpoints in v2:**
- `POST /api/v2/token` — OAuth 2.0 client credentials token exchange
- `GET /api/v2/hubs` / `POST /api/v2/hubs` — list or create hubs, including
first-class VSM hub metadata
- `GET /api/v2/hub-capability-manifests` / `POST /api/v2/hub-capability-manifests`
— list or create hub capability manifests
- `PATCH /api/v2/hub-capability-manifests/{id}` — update draft manifest
vocabulary and metadata
- `POST /api/v2/hub-capability-manifests/{id}/activate` — activate a draft
manifest and register its declared vocabulary
- `GET /api/v2/api-consumers` / `POST /api/v2/api-consumers` — list or create
API consumers
- `POST /api/v2/api-consumers/{id}/api-keys` — create a static API key; the
raw `fullKey` is returned exactly once
- `GET /api/v2/widgets` — paginated widget listing
- `POST /api/v2/widgets` — create a widget
- `GET /api/v2/interaction-events` — paginated event listing
- `POST /api/v2/interaction-events` — submit event (registry-validated)
- `GET /api/v2/annotations` — paginated annotation listing
- `POST /api/v2/annotations` — submit annotation (registry-validated)
- `GET /api/v2/requirement-candidates` — paginated candidates
- `GET /api/v2/decision-records` — paginated decisions
- `GET /api/v2/deployment-records` — paginated deployments
- `GET /api/v2/outcome-signals` — paginated outcome signals
- `GET /api/v2/event-types` — public registry enumeration
- `GET /api/v2/widget-types` — public registry enumeration
- `GET /api/v2/annotation-categories` — public registry enumeration
- `GET /api/v2/sdk/ihf-client.ts` — TypeScript SDK
- `GET /api/v2/sdk/ihf-client.py` — Python SDK
- `GET /api/v2/docs` — Swagger UI
**Validation:** Unregistered `event_type` returns HTTP 422 with:
```json
{ "code": "unregistered_event_type", "registry": "/api/v2/event-types" }
```
v1.0 (`/api/v1/`) remains supported. New consumers should use v2.