Journey Docs
HXP Threads & Actions

HXP Threads and Listening for Changes

Operator-only thread reads, event polling, pagination, message writes, and channel ingress

All HTTP examples on this page require an authenticated HXP operator session and authorized workspace. They are not public integration endpoints. MCP has a separate, limited tool contract.

For third-party server access, use the separate organization API-key contract. Its read projections and allowed commands are narrower than the operator API documented below. Do not substitute its bearer key into these operator URLs.

Read endpoints

Base path: /api/v1/orgs/{orgId}/messaging?scope={scopeId}. Successful responses have a { "data": ... } envelope and Cache-Control: private, no-store.

QueryResponse dataPagination
view=thread&guest={guestId}guestName, timeZone, stays, references, messages, actions, runs, legacy, actorId, canWrite, nextCursorPass nextCursor as before for older messages
view=inbox (default)Personal items, team queues, actorId, nextCursor, queueNextCursorbefore for attention; queueBefore for the team queue; snoozed=1 selects snoozed attention
view=actionsitems, nextCursorbefore
view=recentitems containing guest ID, name, update time, and follow stateBounded recent list, not a complete thread directory
view=configurationAccessible teams and people, routing, readiness indicatorsNot paginated
view=events&after={sequence}events, cursorNumeric event cursor; see below

Thread messages include id, guestId, nullable stayId and parentId, audience, actorId, body, version, mentions, optional guest/room references, reactions, and timestamps. audience is either { "type": "staff" } or { "type": "team", "teamId": "team-example" }; it is not a guest-delivery channel. Stay IDs are validated against the guest's canonical reservations.

Message, Action, and Inbox pages scan up to 100 records before visibility filtering. A short or empty page can still have a next cursor. Follow the returned cursor rather than inferring completion from array length. Thread pagination covers messages; associated Actions, runs, and legacy context are bounded projections, not a complete export.

Event polling

The implemented listener is a JSON polling endpoint, not a long-lived connection:

GET /api/v1/orgs/hotel-example/messaging?scope=venue-example&view=events&after=0

Illustrative response (identifiers are fictional):

{
  "data": {
    "events": [
      {
        "id": "receipt-example",
        "type": "finish",
        "resourceId": "hxp-action:example",
        "actorId": "user-example",
        "createdAt": "2026-09-19T17:00:00.000Z",
        "sequence": 42
      }
    ],
    "cursor": 42
  }
}

after must be a nonnegative safe integer. The service scans at most 100 events per request and filters by current resource, actor, team audience, and guest access. Event types are internal command/runtime names, such as comment, edit, claim, finish, and handoff; they are not a separately versioned public event taxonomy.

For an HXP-owned client:

  1. Keep a cursor for each actor, organization, and scope. Start with after=0 when no checkpoint exists.
  2. Process visible events and refresh the relevant authorized thread, Inbox, or Action snapshot. Events contain identifiers and metadata, not message bodies or a complete after-image.
  3. Persist the returned cursor after processing. Use it even when events is empty: the cursor advances across records the actor cannot see.
  4. Deduplicate by event id. Drain advancing pages with a bounded request budget, then wait before polling again. Retry transient failures with backoff; stop and clear protected cached data when access is denied.
  5. Periodically reconcile the current authorized snapshots. The feed has no published retention, replay SLA, or external delivery guarantee and is not a substitute for an export or audit archive.

HXP's current UI usually refreshes snapshots every 15 seconds, or every 2 seconds while an AI run is working, and pauses background refetching. These are UI choices, not an external polling SLA.

Following is not an external subscription

POST /api/v1/orgs/{orgId}/collaboration?scope={scopeId} accepts this internal command with an Idempotency-Key:

{
  "type": "subscribe",
  "guestId": "guest-example",
  "audience": { "type": "staff" },
  "active": true
}

This records the operator's followed thread for HXP attention. It does not register a callback URL. The matching read is GET .../collaboration?scope={scopeId}&view=subscription&guest={guestId} (add team={teamId} for a team audience).

There is currently no public webhook-registration API, SSE stream, WebSocket endpoint, MCP push subscription, or public event replay service. The internal collaboration worker poll route is a scheduler endpoint, not an integration listener.

Writing a comment

The internal operator client posts commands to the same /messaging?scope=... path with JSON and a stable Idempotency-Key:

{
  "type": "comment",
  "guestId": "guest-example",
  "stayId": null,
  "audience": { "type": "team", "teamId": "team-example" },
  "parentId": null,
  "body": "Please prepare the quiet room before arrival.",
  "sensitive": false,
  "mentions": [{ "type": "person", "id": "user-example" }]
}

The body is 1–6,000 characters; mentions are structured person/team IDs (maximum 20), not inferred authorization from @ text. Guest/room references also use validated structured IDs. A successful write returns { "result": { "id": "...", "kind": "message", "receiptId": "..." } }.

Slack and SMS are specific integrations

/api/collaboration/slack/{installationId} accepts signed Slack callbacks for a configured installation. The current handler responds to explicit app mentions, performs identity-link proof, and can start a bounded consultation for a verified linked operator. It does not import every channel message or expose general thread history. Replies direct the user to authenticated HXP; guest results remain behind HXP access.

/api/collaboration/twilio/{installationId} receives signed SMS delivery callbacks. Guest sending requires a ready connection, recorded consent, and approval bound to the exact effect. This callback is not an inbound guest-chat API. Other channel adapters and arbitrary third-party webhook destinations are not implied by these two implementations.

On this page