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

# Spawn an additional subprocess inside a running instance

> Starts a new process inside the VM that already hosts the named
operation.  Distinct from `POST /instances`, which spins up a
VM: this endpoint requires a running operation (EXECUTING or
ASSIGNED) and reuses the existing VM.

The body is an `ExecSpec` — process-execution fields only.
VM-level concerns (`image`, `hostname`, `resources_limits`,
`files`, `timeout`, `disposable`, `preserve_env`) are not
accepted here; they were set when the parent operation was
created.

The required permission follows the parent instance:
`SPAWN_DISPOSABLE` when it was spawned with `disposable=true`,
`SPAWN` otherwise.

On success the worker assigns a fresh `spid` (≥2; `spid=1` is
the main process spawned from `metadata`) and the response
carries it in the body plus a `Location` header pointing at
`GET /operations/{operationId}/subprocesses/{spid}` — the
subprocess result reconstructed from its events.




## OpenAPI

````yaml https://eu-north.nebius.computer/static/api.yaml post /operations/{operationId}/subprocesses
openapi: 3.0.0
info:
  title: Contree API
  description: >
    Contree is a container management system combining virtual machine isolation
    with container operational efficiency. 

    Designed for security-sensitive workloads requiring hardware-enforced
    boundaries while maintaining

    container workflow compatibility.
  version: 1.0.0
servers:
  - url: '{baseUrl}/v1'
    description: |
      Nebius IAM-fronted endpoint (use `IAMBearerAuth` + `IAMProjectHeader`).
      Override `baseUrl` to point at a different deployment.
    variables:
      baseUrl:
        default: https://api.tokenfactory.nebius.com/sandboxes
        description: |
          Base URL of the contree service. Defaults to the public Nebius
          IAM-fronted endpoint; set to your self-hosted contree origin
          (e.g. `https://contree.example.com`) when running elsewhere.
security:
  - IAMBearerAuth: []
    IAMProjectHeader: []
tags:
  - name: images
    description: Operations related to container images
  - name: files
    description: Operations related to file uploads
  - name: instances
    description: Operations related to container instances
  - name: inspect
    description: Operations related to inspecting container images
  - name: operations
    description: Operations related to long-running operations
  - name: auth
    description: Authentication and token introspection
paths:
  /operations/{operationId}/subprocesses:
    post:
      tags:
        - operation
      summary: Spawn an additional subprocess inside a running instance
      description: |
        Starts a new process inside the VM that already hosts the named
        operation.  Distinct from `POST /instances`, which spins up a
        VM: this endpoint requires a running operation (EXECUTING or
        ASSIGNED) and reuses the existing VM.

        The body is an `ExecSpec` — process-execution fields only.
        VM-level concerns (`image`, `hostname`, `resources_limits`,
        `files`, `timeout`, `disposable`, `preserve_env`) are not
        accepted here; they were set when the parent operation was
        created.

        The required permission follows the parent instance:
        `SPAWN_DISPOSABLE` when it was spawned with `disposable=true`,
        `SPAWN` otherwise.

        On success the worker assigns a fresh `spid` (≥2; `spid=1` is
        the main process spawned from `metadata`) and the response
        carries it in the body plus a `Location` header pointing at
        `GET /operations/{operationId}/subprocesses/{spid}` — the
        subprocess result reconstructed from its events.
      operationId: operationSubprocessCreate
      parameters:
        - name: operationId
          in: path
          required: true
          description: The ID of the operation
          schema:
            $ref: '#/components/schemas/UUIDSchema'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExecSpec'
      responses:
        '201':
          description: |
            Created — subprocess started.  `Location` references the
            new subprocess result.
          headers:
            Location:
              schema:
                type: string
              description: URL of the new subprocess result.
              example: /v1/operations/01J.../subprocesses/2
          content:
            application/json:
              schema:
                type: object
                required:
                  - spid
                properties:
                  spid:
                    type: integer
                    minimum: 2
                    description: Spawn id assigned by the worker.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: |
            Conflict — the operation exists but is not an instance, or
            is not currently EXECUTING / ASSIGNED.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '425':
          description: |
            Too Early (RFC 8470) — the VM is not ready to accept the
            exec yet: no worker holds the operation, or the guest
            control channel is still coming up.  Retry after
            `Retry-After`.
          headers:
            Retry-After:
              schema:
                type: integer
        '504':
          description: |
            Gateway Timeout — the guest accepted the connection but the
            spawn call didn't return in time.  The subprocess MAY have
            started anyway; do not blind-retry — inspect
            `GET /events` for a `spawn` event first.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    UUIDSchema:
      type: string
      format: uuid
      description: A UUID string
      example: 12345678-9abc-baba-deda-0123456789ab
    ExecSpec:
      type: object
      description: |
        Process-execution surface shared between `InstanceSpawnRequest`
        (the main process) and
        `POST /operations/{operationId}/subprocesses` (additional
        subprocesses).  VM-level concerns (image, hostname,
        resources_limits, files, timeout, disposable, preserve_env)
        live on `InstanceSpawnRequest` only.
      required:
        - command
      properties:
        command:
          type: string
          description: >
            The command to execute.  Same semantics as in
            `InstanceSpawnRequest.command` — when `shell=true` it is a shell
            expression, otherwise a path to an executable.
          example: /bin/app
        args:
          type: array
          items:
            type: string
          description: Arguments to pass to the command if shell is set to false.
          example:
            - arg1
            - arg2
          default: []
        shell:
          type: boolean
          description: Run command through a shell expression (args must be empty).
          default: false
        env:
          nullable: true
          type: object
          additionalProperties:
            type: string
          description: Environment variables to set in the child process.
        cwd:
          type: string
          pattern: ^((/[^/]*)+/?)?$
          description: Working directory; empty string means image / server default.
          default: ''
        uid:
          type: integer
          minimum: 0
          default: 0
          description: User ID to run the process as.
        gid:
          type: integer
          minimum: 0
          default: 0
          description: Group ID to run the process as.
        stdin:
          allOf:
            - $ref: '#/components/schemas/ClosableStreamRepr'
          description: |
            Bytes fed to the child's stdin — honored for both the main
            process and exec'd subprocesses.  With `close=false` the
            pipe stays open and more data can be written via
            `POST /operations/{operationId}/subprocesses/{spid}/stdin`.
        truncate_output_at:
          type: integer
          description: |
            Maximum number of bytes of stdout / stderr to keep.
            Defaults to 1 MiB; capped at 10 MiB.
          default: 1048576
          example: 65535
    Error:
      type: object
      required:
        - error
      properties:
        error:
          oneOf:
            - type: string
            - type: object
            - type: array
              items:
                type: object
          description: Error message or structured validation errors
          example: Some error occurred, this is an example of error message
        status:
          type: integer
          description: HTTP status code
          example: 500
        traceback:
          type: array
          items:
            type: string
    ClosableStreamRepr:
      type: object
      description: |
        Stdin payload.  Unlike output streams it is never truncated;
        instead it carries a `close` flag controlling the pipe's EOF.
      required:
        - value
      properties:
        value:
          type: string
          description: Content to write to stdin (may be empty for a close-only request)
          example: aGVsbG8K
        encoding:
          type: string
          enum:
            - ascii
            - base64
          description: Encoding of the content
          default: ascii
        close:
          type: boolean
          default: true
          description: |
            `true` (default) closes stdin (EOF) after writing `value` —
            the pre-existing one-shot behavior.  `false` keeps the pipe
            open so more data can be sent later via
            `POST /operations/{operationId}/subprocesses/{spid}/stdin`.
  responses:
    BadRequest:
      description: Bad Request - Invalid request parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: |
        Unauthorized - Invalid or missing authentication credentials.
        Either the `Authorization` bearer token is missing or invalid, or
        the `Project` header is missing.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: Forbidden - Token does not have sufficient permissions
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Not Found - The requested resource does not exist
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    IAMBearerAuth:
      type: http
      scheme: bearer
      bearerFormat: IAM
      description: |
        IAM bearer token issued by the Nebius IAM service. Sent as
        `Authorization: Bearer <iam-token>`. Must be combined with the
        `Project` header (see `IAMProjectHeader`).

        This is the recommended authentication scheme for new clients.
    IAMProjectHeader:
      type: apiKey
      in: header
      name: Project
      description: |
        Nebius project ID associated with the IAM token. Required together
        with `IAMBearerAuth`. Identifies the project context the request is
        scoped to.

````