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

# Stream Run

> Opens a Server-Sent Events (SSE) stream for real-time execution progress.
This is an alternative to polling `GET /v1/runs/{runId}` -- use
whichever fits your architecture better.

**Connection:** The stream uses standard SSE (`text/event-stream`). Most HTTP
clients and all modern browsers support this natively.

**Event types:**

| Event | When | Data payload |
|-------|------|-------------|
| `progress` | Execution status changes (e.g. `queued` -> `running`) | Full `ExecutionStatus` object |
| `complete` | All outputs are ready | Full `ExecutionStatus` with final values |
| `error` | Execution failed or was cancelled | Full `ExecutionStatus` with error details |
| `timeout` | Stream exceeded 10-minute limit | `{ "message": "Stream timeout after 10 minutes" }` |
| `ping` | Keepalive every ~15 seconds | Unix timestamp |

**Terminal behavior:**
- If the execution is already in a terminal state (`completed`, `failed`, `cancelled`)
  when you connect, the stream sends a single `complete` or `error` event and closes.
- Otherwise, the stream stays open and polls internally every 2 seconds.
- The stream automatically closes after 10 minutes with a `timeout` event.

**Agent usage pattern:**
```
const es = new EventSource('/v1/runs/{id}/stream', {
  headers: { 'x-api-key': 'lma_...' }
});
es.addEventListener('complete', (e) => {
  const result = JSON.parse(e.data);
  // result.outputs contains final values
  es.close();
});
es.addEventListener('error', (e) => {
  const result = JSON.parse(e.data);
  console.error(result.errorMessage);
  es.close();
});
```


Opens a Server-Sent Events (SSE) stream for real-time execution progress.

Use this instead of polling when you need instant updates -- for example, to drive a progress bar, stream partial outputs to a UI, or feed status changes into an agent loop. The connection stays open until the execution reaches `completed` or `failed`.

Each SSE event contains the current execution state, including per-node output status. The final event carries the full completed (or failed) execution payload, after which the server closes the stream.


## OpenAPI

````yaml GET /v1/runs/{runId}/stream
openapi: 3.1.0
info:
  title: Lamina Apps API
  version: 1.0.0
  description: >
    Professional creative content production for AI agents. Create brand-aligned
    images, videos, and designs from natural-language briefs using 30+
    specialized AI pipelines.


    Unlike raw model APIs (DALL-E, Flux, Kling), Lamina automatically applies
    brand guidelines, selects the optimal multi-model pipeline, scores output
    quality, and delivers permanent CDN-hosted URLs with composability metadata
    for chaining.


    ## Authentication

    All endpoints require an API key passed via one of these headers:

    - `x-api-key: lma_your_key` (recommended)

    - `Authorization: Bearer lma_your_key`


    API keys are workspace-scoped. Create them in **Settings -> API Keys**.


    ## Quick Start (One-Call Path)

    `POST /v1/create` with `{ "brief": "product photo of sneakers", "sync": true
    }` — returns completed output inline with CDN URL.


    ## Quick Start (Advanced)

    1. `GET /v1/apps` -- browse 30+ specialized creative apps

    2. `GET /v1/apps/{appId}` -- inspect input parameters

    3. `POST /v1/apps/{appId}/runs?webhook=<url>` -- run with your inputs

    4. Receive results via webhook, poll `GET /v1/runs/{runId}`, or stream via
    `GET /v1/runs/{runId}/stream`


    ## Rate Limits

    All `/v1/*` endpoints are currently limited to 100 requests per minute per
    IP.

    On `429`, read the `RateLimit-*` and `Retry-After` headers before retrying.


    ## How Inputs Work

    When running an app, provide inputs as a JSON object keyed by parameter
    **name** (from the app details response).


    - **text** parameters: send a string value (e.g. a prompt or description)

    - **options** parameters: send the **label** of the option (e.g.
    `"Caucasian"`), not an internal value

    - **url** parameters: send a publicly accessible URL to an image or video


    Every parameter is returned with `required: true`. Parameters with a
    `default` can safely be omitted -- the app will use the default value.


    ## Endpoint Groups

    | Group | Purpose |

    |-------|---------|

    | **Apps** | Discover and inspect available content creation apps |

    | **Runs** | Run workflows, track progress, and retrieve results |

    | **Assets** | Browse generated images, videos, and text from past
    executions |

    | **Intelligence** | Brand context, performance prediction, recommendations,
    and trends |

    | **Publishing** | Publish content to connected social channels |

    | **Content** | One-call agent operations: create, score, brief, batch |

    | **Account** | Credit balance and rate limit visibility |

    | **Templates** | Content creation templates and strategies |

    | **Webhooks** | Webhook signature verification |
servers:
  - url: https://app.uselamina.ai
    description: Production
security:
  - apiKey: []
tags:
  - name: Create
    description: Create content from briefs, run specific apps, and use templates
  - name: Discover
    description: Find and inspect available apps and their input schemas
  - name: Track
    description: Monitor execution progress, retrieve results, and browse generated assets
  - name: Intelligence
    description: >-
      Brand context, performance prediction, content recommendations, and trend
      signals
  - name: Distribute
    description: Publish content to social channels and transfer assets to CDN
  - name: Score
    description: Evaluate content quality, brand alignment, and engagement potential
  - name: Account
    description: Credit balance, rate limits, and health checks
  - name: Webhooks
    description: Webhook signature verification for secure callback handling
paths:
  /v1/runs/{runId}/stream:
    get:
      tags:
        - Track
      summary: Stream Run (SSE)
      description: >
        Opens a Server-Sent Events (SSE) stream for real-time execution
        progress.

        This is an alternative to polling `GET /v1/runs/{runId}` -- use

        whichever fits your architecture better.


        **Connection:** The stream uses standard SSE (`text/event-stream`). Most
        HTTP

        clients and all modern browsers support this natively.


        **Event types:**


        | Event | When | Data payload |

        |-------|------|-------------|

        | `progress` | Execution status changes (e.g. `queued` -> `running`) |
        Full `ExecutionStatus` object |

        | `complete` | All outputs are ready | Full `ExecutionStatus` with final
        values |

        | `error` | Execution failed or was cancelled | Full `ExecutionStatus`
        with error details |

        | `timeout` | Stream exceeded 10-minute limit | `{ "message": "Stream
        timeout after 10 minutes" }` |

        | `ping` | Keepalive every ~15 seconds | Unix timestamp |


        **Terminal behavior:**

        - If the execution is already in a terminal state (`completed`,
        `failed`, `cancelled`)
          when you connect, the stream sends a single `complete` or `error` event and closes.
        - Otherwise, the stream stays open and polls internally every 2 seconds.

        - The stream automatically closes after 10 minutes with a `timeout`
        event.


        **Agent usage pattern:**

        ```

        const es = new EventSource('/v1/runs/{id}/stream', {
          headers: { 'x-api-key': 'lma_...' }
        });

        es.addEventListener('complete', (e) => {
          const result = JSON.parse(e.data);
          // result.outputs contains final values
          es.close();
        });

        es.addEventListener('error', (e) => {
          const result = JSON.parse(e.data);
          console.error(result.errorMessage);
          es.close();
        });

        ```
      operationId: streamRun
      parameters:
        - $ref: '#/components/parameters/runId'
      responses:
        '200':
          description: >-
            SSE event stream. Each event is a `data:` line followed by two
            newlines.
          content:
            text/event-stream:
              schema:
                type: string
              example: >
                event: progress

                data:
                {"runId":"fc32ae7d-...","status":"running","outputs":[...]}


                event: ping

                data: 1713456789000


                event: complete

                data:
                {"runId":"fc32ae7d-...","status":"completed","outputs":[{"id":"...","type":"image","value":"https://...","status":"completed"}]}
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
components:
  parameters:
    runId:
      name: runId
      in: path
      required: true
      schema:
        type: string
        format: uuid
      description: The run ID returned from the Run App or Content Create endpoint
  responses:
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
          example:
            error: Invalid API key
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
          example:
            error: App not found
    TooManyRequests:
      description: >-
        Rate limit exceeded. All `/v1/*` endpoints are currently limited to 100
        requests per minute per IP.
      headers:
        RateLimit-Policy:
          description: Active rate limit policy.
          schema:
            type: string
            example: 100;w=60
        RateLimit-Limit:
          description: Max requests allowed in the current window.
          schema:
            type: integer
            example: 100
        RateLimit-Remaining:
          description: Requests remaining in the current window.
          schema:
            type: integer
            example: 0
        RateLimit-Reset:
          description: Seconds until the current window resets.
          schema:
            type: integer
            example: 60
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
            example: 60
      content:
        text/plain:
          schema:
            type: string
          example: Too many requests from this IP, please try again in a minute
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: 'Workspace API key. Prefix: `lma_`. Example: `lma_abc123...`'

````