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

# Subscribe to trigger events

> A text/event-stream response carrying the same event shape
 GET /v1/triggers/{triggerId}/events returns, one per data: {json} line, for events
 dispatched from the moment of connection onward. Near-real-time rather than a true push: events
 are picked up on a roughly one-second interval.

 Filters combine with AND: triggerId (must be yours - a foreign or unknown id is a 404
 before the stream opens), triggerSlug (an unrecognised slug simply matches nothing) and
 applicationSlug. since=te_... replays every event after that one and then continues
 live; omit it to start from now. A heartbeat comment is sent every 20 seconds on an otherwise idle
 stream - if two intervals pass with nothing at all, treat the connection as dead and reconnect with
 since set to the last event id you received.

 A connection is not open-ended: expect to reconnect. Always resume with since rather
 than assuming one stream will run forever, and be ready for an intermediary to close a long-lived
 connection earlier than the server would.

 Capped at 10 concurrent streams per account - one more than that gets a 429 with
 Retry-After.

 An opaque eng_ API key is re-checked periodically while the stream is open, so a key
 revoked mid-stream ends it. Every controlled end - a revoked key, an unreplayable since
 cursor, or the server shutting down - is signalled by a named terminal event rather than a dropped
 socket, so a client can tell a deliberate end from a network blip.



## OpenAPI

````yaml /api-reference/openapi.json get /v1/triggers/subscribe
openapi: 3.0.0
info:
  title: Engini DeveloperAPI
  version: v1
  description: 'Merged public developer API spec: Identity + WorkflowApi.'
servers:
  - url: https://api.engini.io
security:
  - Bearer: []
  - ApiKey: []
tags:
  - name: Auth
    description: Identify the caller a Developer API request is authenticated as.
  - name: Applications
    description: >-
      Discover the applications (toolkits) available in Engini and their
      connection requirements.
  - name: Tools
    description: Browse and execute the tools exposed by Engini applications.
  - name: Toolsets
    description: Manage toolsets - named groupings of connections and tools.
  - name: McpServers
    description: >-
      Inspect and maintain MCP servers - the account-wide endpoints that expose
      Engini tools and workflows over the Model Context Protocol. Distinct from
      the MCPClient connection kind, which is Engini consuming a third-party MCP
      server.
  - name: Connections
    description: >-
      Manage connections to applications, including OAuth sign-in and
      default-connection selection.
  - name: Triggers
    description: >-
      Create triggers that fire when something changes in a connected app, and
      manage the destinations their events are delivered to.
paths:
  /v1/triggers/subscribe:
    get:
      tags:
        - Triggers
      summary: Subscribe to trigger events
      description: |-
        A text/event-stream response carrying the same event shape
         GET /v1/triggers/{triggerId}/events returns, one per data: {json} line, for events
         dispatched from the moment of connection onward. Near-real-time rather than a true push: events
         are picked up on a roughly one-second interval.

         Filters combine with AND: triggerId (must be yours - a foreign or unknown id is a 404
         before the stream opens), triggerSlug (an unrecognised slug simply matches nothing) and
         applicationSlug. since=te_... replays every event after that one and then continues
         live; omit it to start from now. A heartbeat comment is sent every 20 seconds on an otherwise idle
         stream - if two intervals pass with nothing at all, treat the connection as dead and reconnect with
         since set to the last event id you received.

         A connection is not open-ended: expect to reconnect. Always resume with since rather
         than assuming one stream will run forever, and be ready for an intermediary to close a long-lived
         connection earlier than the server would.

         Capped at 10 concurrent streams per account - one more than that gets a 429 with
         Retry-After.

         An opaque eng_ API key is re-checked periodically while the stream is open, so a key
         revoked mid-stream ends it. Every controlled end - a revoked key, an unreplayable since
         cursor, or the server shutting down - is signalled by a named terminal event rather than a dropped
         socket, so a client can tell a deliberate end from a network blip.
      operationId: Triggers_SubscribeTriggerEvents
      parameters:
        - name: triggerId
          in: query
          description: >-
            Optional ti_ filter. A foreign or unknown id 404s before the stream
            opens.
          schema:
            type: string
            nullable: true
          x-position: 1
        - name: triggerSlug
          in: query
          description: Optional trigger-type slug filter.
          schema:
            type: string
            nullable: true
          x-position: 2
        - name: applicationSlug
          in: query
          description: Optional filter to one application's triggers.
          schema:
            type: string
            nullable: true
          x-position: 3
        - name: since
          in: query
          description: >-
            Optional te_ catch-up cursor - replay everything after this event,
            then continue live.
          schema:
            type: string
            nullable: true
          x-position: 4
      responses:
        '200':
          description: >-
            A live text/event-stream of the caller's trigger events. Never
            actually documented with a body schema - SSE is not a single JSON
            document.
        '400':
          description: Bad request - malformed body or invalid parameters.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized - missing or invalid bearer token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Forbidden - the caller lacks access to the resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: >-
            The triggerId filter names a trigger instance that does not exist or
            is not this account's.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '410':
          description: >-
            The since cursor is unknown or has been pruned by retention
            (SINCE_PRUNED) - the gap cannot be replayed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: >-
            The account already holds the maximum concurrent trigger streams.
            Retry-After names how long to wait.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error - an unexpected error occurred.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - Bearer: []
        - ApiKey: []
components:
  schemas:
    ErrorResponse:
      type: object
      description: >-
        Unified error envelope for every non-200 response from
        /api/DeveloperAPI/v1/*.

        See applications-tools-spec.md §"Error envelope".
      additionalProperties: false
      required:
        - errorCode
        - message
        - requestId
        - timestamp
        - path
      properties:
        errorCode:
          type: string
          description: Machine-readable error code identifying the failure.
        message:
          type: string
          description: Human-readable error message.
        requestId:
          type: string
          description: Identifier of the request, for support/correlation.
        timestamp:
          type: string
          description: Timestamp when the error occurred (ISO 8601).
        path:
          type: string
          description: Request path that produced the error.
        details:
          type: array
          description: Per-field validation details, when applicable.
          nullable: true
          items:
            $ref: '#/components/schemas/ErrorDetail'
    ErrorDetail:
      type: object
      description: A single field-level error detail within an ErrorResponse.
      additionalProperties: false
      required:
        - field
        - issue
      properties:
        field:
          type: string
          description: Name of the field the issue relates to.
        issue:
          type: string
          description: Description of the issue with the field.
  securitySchemes:
    Bearer:
      type: http
      description: Enter your JWT token
      scheme: bearer
      bearerFormat: JWT
    ApiKey:
      type: apiKey
      description: >-
        Opaque Developer API key (prefix `eng_`). Authenticates as the key's
        owner and resolves the account automatically.
      name: x-api-key
      in: header

````