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

# Execute a workflow by slug or slug@version

> Submit a workflow for execution using its globally unique slug.
Identical to runWorkflow but uses the human-readable slug instead of UUID.
The slug must belong to the specified team's workflows.
Pass `slug@version` (for example, `text-to-image@2`) to run the workflow
JSON and parameter definitions saved for that version snapshot.
Accepts JWT Bearer, `sk-` integration credential, or `dk-` device credential.




## OpenAPI

````yaml /api-reference/core-openapi.yaml post /r/workflows/slug/{workflowSlug}/run
openapi: 3.0.3
info:
  title: Cyberun API
  version: 1.0.0
  description: >
    Multi-tenant GPU orchestration platform for enterprise private deployments.


    ## Authentication


    Two authentication families are supported:


    - **JWT Bearer** (`Authorization: Bearer <jwt>`) — Used by team
    owners/admins/members
      for management endpoints and user sessions. JWT-authenticated requests that operate
      on a team **must** include the `X-Team-ID` header to select which team the request
      applies to (a user can belong to multiple teams).
    - **Credential Bearer** (`Authorization: Bearer <sk-/ak-/dk-...>`) — Unified
    machine
      credential. The credential is always scoped to a single team derived from the
      credential row, and any `X-Team-ID` header is **ignored**. The three kinds differ in
      identity and routing:

      | Kind          | Prefix | Identity                  | Allowed surfaces |
      | ------------- | ------ | ------------------------- | --- |
      | `integration` | `sk-`  | Team only                 | Runtime API (`/r/`) + the Web MCP endpoint. Rejected on every management endpoint because the authorization layer needs a user identity and `sk-` has none. |
      | `agent`       | `ak-`  | Team only                 | the platform's WebSocket handshake **only** — rejected by the REST surface at the middleware layer. |
      | `device`      | `dk-`  | Team + user (per-device)  | Runtime API and scoped management endpoints — behaves like a JWT for the underlying user. Issued by the desktop pairing flow only (`POST /desktop/pair/confirm`). |

      the authorization layer runs against the user identity carried by JWT and `dk-`. `sk-` and `ak-`
      bypass the authorization layer; service-layer checks enforce team scope for them.

    Runtime endpoints under `/r/` accept **JWT (with `X-Team-ID`)**, `sk-`, and
    `dk-`.

    `ak-` is rejected at the middleware (it is only meaningful on the the
    platform's WebSocket

    handshake). Scoped management endpoints accept **JWT (with `X-Team-ID`)** or

    `dk-`; `sk-` is rejected on management because the the authorization layer
    authorize layer

    requires a user identity. The Web MCP endpoint accepts `sk-` only.

    Multipart upload endpoints (`/uploads/multipart/*`) remain JWT-only.

    Credential-bearing callers (`sk-`, `dk-`) should use single-part presign

    (`POST /r/files/presign`) instead — that returns a vanilla S3 PUT URL

    (≤ 5 GB by S3, subject to the server's configured request cap; default

    500 MB). Files beyond the cap currently require the JWT-only multipart

    flow.


    ## Task Lifecycle


    Tasks follow this state machine: `pending → waiting → queued → running →
    completed | failed | cancelled`.

    Submit tasks via workflow run endpoints, poll status via GET
    /r/tasks/{taskId},

    and retrieve results via GET /r/tasks/{taskId}/result.


    ## Pagination


    All list endpoints support pagination via `current_page` (default: 1) and
    `per_page`

    (default: 20, max: 100) query parameters. Responses include a `page_meta`
    object

    with `current_page`, `per_page`, and `total_count`.
servers:
  - url: https://core.cyberun.cloud/api/v1
    description: Cyberun Cloud API
security: []
tags:
  - name: Auth
    description: >
      Authentication and account lifecycle: register, login, logout, token
      refresh,

      password reset, and email verification.
  - name: User
    description: |
      Current user profile management: view and update profile, change password.
  - name: Team
    description: >
      Team management: create, update, delete teams, leave, and transfer
      ownership.

      Each user gets a personal team on registration.
  - name: Member
    description: |
      Team member management: list members, update roles, and remove members.
  - name: Invitation
    description: >
      Team invitation management: invite users by email, accept/decline
      invitations,

      list pending invitations, and cancel invitations.
  - name: Credential
    description: |
      Unified credential management: integration keys (`sk-`) for programmatic
      API access, agent keys (`ak-`) for headless workers, and device keys
      (`dk-`) for paired desktop installs. All three share storage and
      revocation flow; the `kind` field selects behaviour.
  - name: DevicePair
    description: >
      Desktop device pairing flow. Three endpoints — start (anonymous),

      confirm (JWT, called from the Cyberun dashboard), poll (anonymous, called
      from

      desktop) — exchange a short user-visible code for a `dk-` credential

      without the user ever typing the secret.
  - name: Workflow
    description: >
      ComfyUI workflow template management: create, update, delete, and list
      workflow templates

      with configurable parameters, labels, timeout, and retry settings.
  - name: Task
    description: |
      Task execution and monitoring: submit workflow runs, poll task status,
      retrieve results, and cancel tasks. Tasks follow the lifecycle:
      `pending → waiting → queued → running → completed | failed | cancelled`.
  - name: Webhook
    description: >
      Webhook management: register HTTPS endpoints to receive event
      notifications

      (task.completed, task.failed) with HMAC-SHA256 signed payloads.
  - name: Container
    description: >
      Container service orchestration: deploy arbitrary Docker containers (vLLM,
      Ollama,

      custom services) to agents, manage lifecycle, and proxy HTTP requests
      through

      the gateway with load balancing.
  - name: CloudProvider
    description: >
      Cloud compute provider management: configure third-party cloud GPU
      provider

      API keys (e.g. ComfyUI Cloud) for teams without local GPU agents, and

      manage automatic cloud fallback settings.
  - name: Notifications
    description: |
      In-app notification center: list, read, and manage notifications
      for status changes and system alerts.
  - name: Agent
    description: >
      Agent monitoring: view connected agents for a team, including their
      status,

      labels, and current task. Data is read from the the platform's runtime
      state.
  - name: Node
    description: |
      Custom node management: upload, register, update, and delete ComfyUI
      custom node packages (zip archives) for team-scoped agents.
  - name: Model
    description: |
      Model management: upload, register, update, and delete AI model files
      (checkpoints, LoRAs, etc.) for team-scoped agents.
  - name: File
    description: >
      File upload for workflow inputs: request presigned upload URLs to stage
      files

      (images, videos, audio) in S3, then reference them as `type: file`
      parameters

      when running workflows.
  - name: Upload
    description: >
      Multipart upload support for large files: initiate, presign parts,
      complete,

      and abort multipart uploads. Used alongside domain-specific presign
      endpoints

      for files exceeding ~100 MB.
  - name: Server
    description: |
      Public server information: registration status and other configuration
      visible to unauthenticated clients.
paths:
  /r/workflows/slug/{workflowSlug}/run:
    parameters:
      - $ref: '#/components/parameters/TeamIdHeaderOptional'
      - $ref: '#/components/parameters/WorkflowSlug'
    post:
      tags:
        - Task
      summary: Execute a workflow by slug or slug@version
      description: >
        Submit a workflow for execution using its globally unique slug.

        Identical to runWorkflow but uses the human-readable slug instead of
        UUID.

        The slug must belong to the specified team's workflows.

        Pass `slug@version` (for example, `text-to-image@2`) to run the workflow

        JSON and parameter definitions saved for that version snapshot.

        Accepts JWT Bearer, `sk-` integration credential, or `dk-` device
        credential.
      operationId: runWorkflowBySlug
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RunWorkflowRequest'
      responses:
        '202':
          description: Task submitted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RunWorkflowResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - bearerAuth: []
        - DeviceAuth: []
        - ApiKeyAuth: []
components:
  parameters:
    TeamIdHeaderOptional:
      name: X-Team-ID
      in: header
      required: false
      description: |
        UUID of the team to scope the request to. Used by dual-auth endpoints
        (runtime + scoped management):
        - **JWT callers** MUST send it — a user may belong to multiple teams and
          the runtime cannot otherwise know which one to operate on. Missing
          header → 400.
        - **Credential callers** (`sk-`, `dk-`) can omit it because the team is
          derived from the credential row itself. Any value sent is ignored.
      schema:
        type: string
        format: uuid
        example: 019abc12-4567-7890-abcd-ef1234567891
    WorkflowSlug:
      name: workflowSlug
      in: path
      required: true
      description: >
        Workflow slug for runtime lookup. Use `slug` for the latest version or

        `slug@version` to reference an immutable workflow snapshot, e.g.
        `text-to-image@2`.
      schema:
        type: string
        pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*(?:@[1-9][0-9]*)?$
        maxLength: 128
        example: text-to-image@2
  schemas:
    RunWorkflowRequest:
      type: object
      description: >
        Request body to execute a workflow with optional parameter overrides.


        ## Workflow run usage


        ### Step 1 — Discover available parameters


        Call `GET /r/workflows/{workflowId}` or

        `GET /r/workflows/slug/{workflowSlug}` to retrieve the workflow

        detail. To target a previous workflow version, use `slug@version`

        (for example, `text-to-image@2`). The `parameters` array contains
        `ParameterDef` entries that describe

        every user-configurable input. Each entry has:


        | Field       |
        Purpose                                                     |

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

        | `key`       | The key you use in the request body
        below                   |

        | `type`      | `string` / `number` / `boolean` / `select` /
        `file`        |

        | `label`     | Human-readable label for UI
        rendering                       |

        | `description` | Optional description of what this parameter
        does          |

        | `required`  | If `true`, you **must** provide a
        value                     |

        | `default`   | Value used when the key is omitted (optional params
        only)   |

        | `min` / `max` | Numeric bounds (only for `type:
        number`)                  |

        | `options`   | Allowed values list (only for `type:
        select`)               |

        | `accept`    | Allowed MIME patterns (only for `type: file`, e.g.
        `image/*`) |


        Example `parameters` from a workflow detail response:

        ```json

        [
          {"key": "prompt", "node_id": "6", "field": "text", "type": "string",
           "label": "Positive Prompt", "required": true},
          {"key": "width",  "node_id": "5", "field": "width", "type": "number",
           "label": "Width", "min": 64, "max": 2048, "default": 512},
          {"key": "sampler", "node_id": "3", "field": "sampler_name", "type": "select",
           "label": "Sampler", "options": ["euler", "euler_ancestral", "dpmpp_2m"],
           "default": "euler"},
          {"key": "input_image", "node_id": "10", "field": "image", "type": "file",
           "label": "Input Image", "required": true, "accept": ["image/*"]}
        ]

        ```


        ### Step 2 — Build the run request


        Use the `key` values from the parameter definitions as keys in the

        `parameters` object:


        ```json

        POST /r/workflows/{workflowId}/run

        {
          "parameters": {
            "prompt": "sunset over ocean",
            "width": 1024,
            "sampler": "dpmpp_2m"
          }
        }

        ```


        **For `type: file` parameters**, upload the file first, then pass the
        `file_key`:


        1. `POST /r/files/presign` with `{"file_name": "photo.png", "file_size":
        1048576, "content_type": "image/png"}`

        2. Upload the file to the returned `upload_url` via HTTP PUT.

        3. Pass the `file_key` as the parameter value:

        ```json

        {
          "parameters": {
            "input_image": "inputs/{team}/{uuid}/photo.png",
            "prompt": "enhance this photo"
          }
        }

        ```


        ### Step 3 — Validation rules


        - **Unknown keys** → `400 Bad Request` (only keys from ParameterDef are
        accepted).

        - **Missing required keys** → `400 Bad Request`.

        - **Type mismatch** → `400 Bad Request` (e.g. string for a number
        parameter).

        - **Out of range** → `400 Bad Request` (number outside min/max bounds).

        - **Invalid select value** → `400 Bad Request` (value not in the options
        list).

        - **File not uploaded** → `400 Bad Request` (file_key not found in S3).

        - **File wrong team** → `400 Bad Request` (file_key must belong to the
        team).

        - **File type rejected** → `400 Bad Request` (file MIME doesn't match
        `accept` pattern).

        - **Omitted optional keys** → the workflow's `default` value is used
        automatically.

        - **Empty body `{}`** → valid if no parameters are required (all have
        defaults).

        - **Workflow with no parameters** → send `{}` or omit `parameters`
        entirely.


        ### Step 4 — Poll for results


        The response contains a `task_id`. Poll status:

        ```

        GET /r/tasks/{taskId}

        ```

        When `task_status` is `completed`, fetch the output:

        ```

        GET /r/tasks/{taskId}/result

        ```
      properties:
        parameters:
          type: object
          additionalProperties: true
          maxProperties: 100
          description: >
            Key-value map of parameter overrides. Keys must match the `key`
            field

            of a `ParameterDef` entry defined in the workflow's `parameters`
            array.


            For `type: file` parameters, the value must be a `file_key` string

            obtained from `POST /r/files/presign`. Upload the file first, then
            pass

            the key here.


            Retrieve available keys by calling `GET /r/workflows/{workflowId}`

            or `GET /r/workflows/slug/{workflowSlug}` and inspecting

            the `parameters` array in the response. Use `workflowSlug@version`
            to

            discover parameters for a previous workflow version.


            Maximum 100 parameter keys per request.
          example:
            prompt: sunset over ocean
            width: 1024
            input_image: inputs/019abc12-3456/550e8400-e29b/photo.png
        dispatch_target:
          type: string
          enum:
            - agent
            - comfy_cloud
          description: >
            Where to execute this task:

            - `agent` (default): Execute on a local BYOC agent.

            - `comfy_cloud`: Execute on ComfyUI Cloud (requires configured API
            key).


            If omitted, the workflow's `default_dispatch_target` is used,
            falling

            back to `agent`.
          example: agent
        target_pool:
          type: string
          enum:
            - team
            - community
          description: |
            Dispatch pool for this task. Only meaningful when
            `dispatch_target=agent`.
            - `team` (default): route to an agent in the same team — the
              P2.1 behaviour.
            - `community`: route to any opted-in agent across teams via the
              Cyberun community pool. Submitting team does not need to
              opt in to consume; the serving agent does.

            If omitted, defaults to `team`.
          example: team
        submitter_region:
          type: string
          maxLength: 64
          description: |
            Submitter's declared geographic / network locality, used by
            the P3.1 scoring engine to favour region-matching agents
            when multiple candidates are eligible. Opaque user-supplied
            string (e.g. `us-east`, `eu-central`, `ap-southeast`); normalised
            server-side to lowercase + trimmed. Empty / omitted →
            scorer treats as unknown (neutral 0.5 region factor; no
            agent is disqualified). Has no effect on
            `dispatch_target=comfy_cloud`.
          example: us-east
        tool_type:
          $ref: '#/components/schemas/ToolType'
    RunWorkflowResponse:
      type: object
      required:
        - task_id
      properties:
        task_id:
          type: string
          format: uuid
          description: ID of the created task. Use this to poll task status and results.
          example: 019abc12-9012-7890-abcd-ef1234567896
    ToolType:
      type: string
      enum:
        - comfyui
        - nerfstudio
      description: |
        Tool runtime used by this workflow:
        - `comfyui`: ComfyUI API workflow JSON (default, backward compatible).
        - `nerfstudio`: Nerfstudio 3DGS pipeline spec.
      example: comfyui
    ErrorResponse:
      type: object
      required:
        - error_message
      properties:
        error_message:
          type: string
          description: Human-readable error message describing what went wrong.
          example: resource not found
  responses:
    BadRequest:
      description: >-
        Invalid request: missing required fields, validation failure, or
        malformed input.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: 'Authentication failed: missing, expired, or invalid JWT/API key.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: >-
        Insufficient permissions: the authenticated user does not have the
        required role or the authorization layer policy.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: 'Resource not found: the specified ID or slug does not exist.'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        User session JWT (Bearer <jwt>). Must be paired with the `X-Team-ID`
        request header on team-scoped endpoints so the server knows which
        team's resources to operate on.
    DeviceAuth:
      type: http
      scheme: bearer
      description: >
        Device credential (Bearer dk-...) issued by the client device-pair

        flow (`POST /desktop/pair/confirm`). Carries the confirming user's

        identity, so it behaves like the user's JWT on team-scoped endpoints

        — the authorization layer runs against the user. Accepted on runtime +
        management

        endpoints. Never accepted on the platform's WebSocket. Team scope is
        bound at pair

        time; `X-Team-ID` is ignored.
    ApiKeyAuth:
      type: http
      scheme: bearer
      description: >
        Integration credential (Bearer sk-...). Team-scoped, no user identity,

        bypasses the authorization layer. Full runtime access on `/r/*`
        (including container

        invoke and proxy) and the Web MCP endpoint. **Not accepted on

        management endpoints** — those need a user-bearing credential (JWT or

        `DeviceAuth`). Team scope is taken from the credential; `X-Team-ID`

        is ignored.

````