> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getcliq.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Submit an event

> Submits an event; matching notification rules deliver it. Each family needs its fields:
`run.*` / `phase.*` / `hug.*` need `realm_id`, `run_id` and `daemon_id` (and `phase` for
`phase.*`), `team.*` needs `team`, `daemon.*` needs `daemon_id`. Some types are raised by
CliqHub only. The run must be in `realm_id`, and a daemon may only speak for daemons of its
realm. Repeating the same submit is de-duplicated.

Requires a signed-in user token; with `realm_id`, a realm operator (or higher) on that realm; with `org_id`, membership in that organization. One of `realm_id` or `org_id` is required. A daemon's realm token (`cliq_dt_…`) from the same realm may also call it. Run in realm; daemon: own daemons, own org.



## OpenAPI

````yaml /openapi/hub-by-tag/hub-events.yaml post /v1/events/submit
openapi: 3.0.3
info:
  title: 'CliqHub API: Events'
  version: 1.0.0
  description: >-
    The notification event bus. Events have a type from CliqHub's catalog
    (`run.failed`,

    `phase.input_required`, `hug.review_requested`, `daemon.offline`, …) or a
    custom type

    `custom.<name>` registered for a realm. Notification rules match events and
    deliver them to

    channels. Daemons and integrations submit events; CliqHub raises some
    itself. This is not

    the live run timeline (that is Runs).
servers:
  - url: https://{host}
    variables:
      host:
        default: cliqhub.io
        description: CliqHub host
security: []
tags:
  - name: Events
    description: >-
      The notification event bus. Events have a type from CliqHub's catalog
      (`run.failed`,

      `phase.input_required`, `hug.review_requested`, `daemon.offline`, …) or a
      custom type

      `custom.<name>` registered for a realm. Notification rules match events
      and deliver them to

      channels. Daemons and integrations submit events; CliqHub raises some
      itself. This is not

      the live run timeline (that is Runs).
paths:
  /v1/events/submit:
    post:
      tags:
        - Events
      summary: Submit an event
      description: >-
        Submits an event; matching notification rules deliver it. Each family
        needs its fields:

        `run.*` / `phase.*` / `hug.*` need `realm_id`, `run_id` and `daemon_id`
        (and `phase` for

        `phase.*`), `team.*` needs `team`, `daemon.*` needs `daemon_id`. Some
        types are raised by

        CliqHub only. The run must be in `realm_id`, and a daemon may only speak
        for daemons of its

        realm. Repeating the same submit is de-duplicated.


        Requires a signed-in user token; with `realm_id`, a realm operator (or
        higher) on that realm; with `org_id`, membership in that organization.
        One of `realm_id` or `org_id` is required. A daemon's realm token
        (`cliq_dt_…`) from the same realm may also call it. Run in realm;
        daemon: own daemons, own org.
      operationId: POST_v1_events_submit
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - run.started
                    - run.resumed
                    - run.resume_requested
                    - run.completed
                    - run.failed
                    - run.crashed
                    - run.cancelled
                    - phase.started
                    - phase.completed
                    - phase.failed
                    - phase.skipped
                    - phase.escalated
                    - phase.input_required
                    - phase.inputs_supplied
                    - phase.timed_out
                    - phase.idle
                    - hug.review_requested
                    - hug.review_reminded
                    - hug.review_responded
                    - hug.routing_requested
                    - hug.review_resolved
                    - hug.review_expired
                    - team.published
                    - team.visibility_changed
                    - daemon.enrolled
                    - daemon.removed
                    - daemon.online
                    - daemon.offline
                    - "s local hub_outbox dead_count. `dead` events carry\n\t// a compact cause summary so operators can triage without opening\n\t// the SPA. Emitted best-effort via the outbox itself; loss on a\n\t// completely-broken daemon is acceptable because `daemon.offline`\n\t// covers the total-loss case.\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t// Org-scoped identity events, raised only by CliqHub itself\n\t// (notifications/org_events.ts); `events/submit` refuses them.\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                    - ",\n\t"
                  description: >-
                    Hub catalog type (run.* / phase.* / hug.* / …) or
                    custom.<name>
                occurred_at:
                  type: string
                  description: ISO-8601 timestamp; Hub defaults to now when omitted
                realm_id:
                  type: string
                  description: Required for most families (see family rules)
                org_id:
                  type: string
                  description: Optional org scope
                team:
                  type: string
                  description: Team slug; required for team.*
                run_id:
                  type: string
                  description: Required for run.* / phase.* / hug.*
                phase:
                  type: string
                  description: Required for phase.*
                daemon_id:
                  type: string
                  description: Required for run.* / phase.* / hug.* / daemon.*
                title:
                  type: string
                  description: Short notification title
                message:
                  type: string
                  description: Longer notification body
                severity:
                  type: string
                  enum:
                    - info
                    - warn
                    - error
                    - critical
                  description: Overrides catalog default severity when set
                payload:
                  type: object
                  properties:
                    notify:
                      type: object
                      properties:
                        channels:
                          oneOf:
                            - type: boolean
                              enum:
                                - false
                            - type: array
                              items:
                                type: string
                          description: >-
                            false = mute; string[] = channel refs; omit =
                            default routing
                      description: Fan-out intent for Hub notification channels
                      additionalProperties: true
                    run_name:
                      type: string
                      description: Display name for the run
                    daemon_name:
                      type: string
                      description: Display name for the daemon
                    error:
                      type: string
                      description: Failure / crash message
                    reason:
                      type: string
                      description: Human-readable reason (cancel, escalate, …)
                    review_id:
                      type: string
                      description: HUG review id when applicable
                    stream_event:
                      type: string
                      description: Underlying stream/lifecycle verb
                    dead_count:
                      type: number
                      description: daemon.outbox.dead — dead outbox row count
                    cause_summary:
                      type: string
                      description: Compact outbox dead-cause summary
                  additionalProperties: true
                  description: Type-specific extras (notify routing, names, error, …)
              required:
                - type
            example:
              type: run.failed
              realm_id: 00000000-0000-4000-8000-000000000001
              run_id: 00000000-0000-4000-8000-000000000002
              daemon_id: 00000000-0000-4000-8000-000000000003
              severity: error
              title: Run failed
              message: phase coder exited non-zero
              payload:
                run_name: fix-api
                error: npm test failed
                notify:
                  channels:
                    - slack:ops
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                    enum:
                      - true
                    description: Always `true` on success.
                  event:
                    $ref: '#/components/schemas/HubEvent'
                required:
                  - ok
              example:
                ok: true
                event:
                  id: 2d3e4f5a-6b7c-4d8e-9f0a-1b2c3d4e5f6a
                  type: run.failed
                  occurred_at: '2026-10-07T10:25:00Z'
                  realm_id: 5b0c3a7e-2f4d-4b8e-9a51-7c1d2e3f4a5b
                  org_id: null
                  team: code-review
                  run_id: 0c8d7e6f-5a4b-4c3d-9e2f-1a0b9c8d7e6f
                  phase: fix
                  daemon_id: 7d1c2b3a-4e5f-4a6b-8c7d-9e0f1a2b3c4d
                  title: Run failed
                  message: npm test failed
                  severity: error
                  payload: {}
                  actor_id: null
                  created_at: '2026-10-07T10:25:01Z'
                  notifications: deferred
        '400':
          description: '`bad_request`: Neither `realm_id` nor `org_id` was sent.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HubErr'
              examples:
                bad_request:
                  summary: bad_request
                  value:
                    ok: false
                    error:
                      code: bad_request
                      message: realm_id or org_id is required
        '401':
          description: >-
            `unauthorized`: No `Authorization` header, or the token is
            malformed, expired or revoked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HubErr'
              examples:
                unauthorized:
                  summary: unauthorized
                  value:
                    ok: false
                    error:
                      code: unauthorized
                      message: Authentication required
        '403':
          description: >-
            `forbidden`: You can see the realm or organization but your role
            lacks the required permission.


            `forbidden`: A daemon token named a daemon outside its realm, or an
            organization other than its realm's.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HubErr'
              examples:
                forbidden:
                  summary: forbidden
                  value:
                    ok: false
                    error:
                      code: forbidden
                      message: You do not have access to do this
                forbidden (endpoint):
                  summary: forbidden (endpoint)
                  value:
                    ok: false
                    error: Daemon token has no realm
                    code: forbidden
        '404':
          description: >-
            `not_found`: The realm or organization you named does not exist or
            you cannot see it.


            `not_found`: The run does not exist, or is not in `realm_id`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HubErr'
              examples:
                not_found:
                  summary: not_found
                  value:
                    ok: false
                    error:
                      code: not_found
                      message: Not found
                not_found (endpoint):
                  summary: not_found (endpoint)
                  value:
                    ok: false
                    error: Run not found in this realm
                    code: not_found
        '422':
          description: >-
            `invalid_params`: The body fails the request schema: a field is
            missing or has the wrong type. `details.issues` lists each problem.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HubErr'
              examples:
                invalid_params:
                  summary: invalid_params
                  value:
                    ok: false
                    error: Required
                    code: invalid_params
                    details:
                      issues:
                        - field: type
                          message: Required
        '500':
          description: >-
            `internal_error`: An unexpected server fault. Retry later; if it
            persists, report it with the time of the request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HubErr'
              examples:
                internal_error:
                  summary: internal_error
                  value:
                    ok: false
                    error: Internal server error
                    code: internal_error
      security:
        - BearerAuth: []
components:
  schemas:
    HubEvent:
      type: object
      properties:
        id:
          type: string
        type:
          type: string
          example: run.failed
        occurred_at:
          type: string
        realm_id:
          type: string
          nullable: true
        org_id:
          type: string
          nullable: true
        team:
          type: string
          nullable: true
        run_id:
          type: string
          nullable: true
        phase:
          type: string
          nullable: true
        daemon_id:
          type: string
          nullable: true
        title:
          type: string
          nullable: true
        message:
          type: string
          nullable: true
        severity:
          type: string
          enum:
            - info
            - warn
            - error
            - critical
        payload:
          type: object
          additionalProperties: true
        actor_id:
          type: string
          nullable: true
        created_at:
          type: string
        notifications:
          type: string
          description: >-
            Whether notifications were sent now or later (for example
            `deferred`).
    HubErr:
      type: object
      required:
        - ok
        - error
      description: >-
        Every failure. Route-policy denials (401/403/404, and 400 when neither
        realm_id nor org_id was sent) answer `error` as `{ code, message }`;
        errors raised by the endpoint answer `error` as the message with the
        code beside it in `code`. Every error has a code. See
        [Errors](/hub-api/errors).
      properties:
        ok:
          type: boolean
          description: Always false on error
        error:
          description: The message, or `{ code, message }` for an access denial.
          oneOf:
            - type: string
            - type: object
              required:
                - code
                - message
              properties:
                code:
                  type: string
                message:
                  type: string
        code:
          type: string
          description: Stable error code of an endpoint error.
        details:
          type: object
          additionalProperties: true
          description: Structured detail, when there is some.
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: cliq_tok_* | cliq_dt_*
      description: >-
        User PAT (`cliq_tok_…`, including session-scoped) or realm token
        (`cliq_dt_…`).

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.