Files
inter-hub/contracts/functional/interaction-reporting-v1.md
Bernd Worsch 3cac021213
Some checks failed
Test / test (push) Has been cancelled
feat(WP-0010): IHF Phase 9 — External API Surface and Consumer SDKs
Delivers the full Phase 9 external API layer:

- Versioned REST API (/api/v2/) with OpenAPI 3.1 spec; enum arrays for
  widget_type, event_type, annotation category drawn live from registry tables
- OAuth 2.0 client credentials flow (/api/v2/token); hub:*:write scopes
  gated on active HubCapabilityManifest FK
- API key management: SHA256-hashed tokens, key_prefix for display,
  one-time reveal on creation, revocation support
- TypeScript and Python consumer SDKs generated from registry tables
  (/api/v2/sdk/ihf-client.ts, /api/v2/sdk/ihf-client.py)
- Webhook delivery: HMAC-SHA256 signing, append-only webhook_deliveries,
  fire-and-forget dispatch via forkIO, 3-retry logic
- Admin API dashboard with 24h stats (request count, error rate, last seen)
- Rate limiting (per-minute) and daily quota enforcement via api_request_log
- Schema migration: api_consumers, api_keys, webhook_subscriptions (CHECK
  constraint on 6 framework lifecycle topics), webhook_deliveries
  (append-only trigger), api_request_log
- ARCHITECTURE-LAYERS.md scorecard: 3.34 → 3.41 (approaching Strong)
- contracts/functional/interaction-reporting-v1.md extended with Phase 9
  endpoint catalogue and 422 validation error format

GAAF: no bare TEXT discriminators; webhook event_type uses CHECK constraint
over 6 allowed framework lifecycle topic strings (not widget event types).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 19:52:20 +00:00

4.5 KiB

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)

{
  "id": "<uuid>",
  "widget_id": "<uuid>",
  "event_type": "clicked",
  "occurred_at": "2026-03-31T12:00:00Z"
}

Response — Validation Error (422 Unprocessable Entity)

{
  "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)

{
  "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 supersedes per-hub Bearer tokens with 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)

New endpoints in v2:

  • POST /api/v2/token — OAuth 2.0 client credentials token exchange
  • GET /api/v2/widgets — paginated widget listing
  • 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:

{ "code": "unregistered_event_type", "registry": "/api/v2/event-types" }

v1.0 (/api/v1/) remains supported. New consumers should use v2.