Sageox Runs API

The runs API from Sageox — 7 operation(s) for runs.

Operations 7

POST /api/v1/runs/prepare Prepare a new terraform run #
POST /api/v1/runs/{run_id}/events Stream terraform apply events #
POST /api/v1/runs/{run_id}/complete Complete a terraform run #
GET /api/v1/runs/{run_id} Get run status and resources #
POST /api/v1/env/{env_id}/run/init Initialize new run (deprecated) #
POST /api/v1/env/{env_id}/run/{run_id} Update run with step data (deprecated) #
POST /api/v1/env/{env_id}/run/{run_id}/status Complete or fail run (deprecated) #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/sageox-runs-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

sageox-runs-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: SageOx Runs API
  version: 1.0.0
  description: '# API Reference


    ## Overview


    SageOx is a platform that captures team knowledge from discussions, decisions, and work context into a Ledger (per-repo historical record) and Team Context (team-wide shared knowledge).'
  contact:
    name: SageOx Team
  license:
    name: MIT
servers:
- url: http://localhost:3000
  description: Devcontainer
- url: https://test.sageox.ai
  description: Test
- url: https://sageox.ai
  description: Production
security:
- bearerAuth: []
tags:
- name: Runs
paths:
  /api/v1/runs/prepare:
    post:
      operationId: prepareRun
      summary: Prepare a new terraform run
      description: 'Initialize a run before streaming terraform apply events.


        This endpoint creates a pending run that is ready to receive JSONL events from a terraform apply.

        Once created, the CLI streams terraform output to `/api/v1/runs/{run_id}/events` and calls

        `/api/v1/runs/{run_id}/complete` when terraform finishes.


        **Required sequence:**

        1. Call `/runs/prepare` to create run

        2. Stream events via `/runs/{run_id}/events`

        3. Call `/runs/{run_id}/complete` with exit code


        See ADR-012 for architecture details.'
      tags:
      - Runs
      security:
      - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - workspace_id
              - git_commit
              - terraform_version
              - plan_path
              properties:
                workspace_id:
                  type: string
                  description: Workspace ID (ws_ prefix)
                  example: ws_abc123def456
                git_commit:
                  type: string
                  description: Git commit SHA for this run
                  example: abc123deadbeef1234567890abcdef123456789
                terraform_version:
                  type: string
                  description: Terraform version (e.g., "1.9.5")
                  example: 1.9.5
                plan_path:
                  type: string
                  description: Path to plan.json in repository (relative to workspace)
                  example: workspaces/acme-corp/prod/plan.json
      responses:
        '201':
          description: Run created successfully
          content:
            application/json:
              schema:
                type: object
                required:
                - run_id
                properties:
                  run_id:
                    type: string
                    format: uuid
                    description: UUIDv7 identifier for the created run
                    example: 018c5e72-1b3a-7def-8abc-123456789012
        '400':
          description: Invalid request (missing required fields, invalid workspace_id format)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: 'Missing required field: workspace_id'
        '401':
          description: Unauthorized (invalid or missing authentication token)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Workspace not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Run already in progress for this workspace (conflict)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/runs/{run_id}/events:
    post:
      operationId: streamRunEvents
      summary: Stream terraform apply events
      description: 'Stream terraform apply JSONL events. Connection stays open until terraform completes or disconnects.


        **Event Format:**

        Send terraform output as newline-delimited JSON (NDJSON). Each line is a single Terraform event.


        Example events:

        ```

        {"@level":"info","type":"apply_start","@timestamp":"2025-01-01T00:00:00Z"}

        {"@level":"info","type":"apply_progress","hook":{"resource":{"addr":"aws_s3_bucket.main"},"action":"create"}}

        {"@level":"info","type":"apply_complete","changes":{"add":3,"change":0,"remove":0}}

        ```


        **Connection Lifecycle:**

        - Backend validates run exists and is in `pending` or `running` status

        - First connection signals Temporal workflow `run_started`

        - Each event line updates `last_event_at` timestamp

        - Important events (progress, complete) update DB directly

        - Connection drop without calling `/complete` signals `connection_lost` to workflow

        - Reconnection within 2 minutes cancels the connection_lost timeout


        **Storage:**

        - Backend does NOT store raw events (would be high write volume)

        - CLI must locally write events to `apply.jsonl` file

        - CLI commits `apply.jsonl` to git after terraform exits

        - Backend queries important events from database, not stored JSONL


        See ADR-012 for full event specifications.'
      tags:
      - Runs
      security:
      - bearerAuth: []
      parameters:
      - name: run_id
        in: path
        required: true
        description: UUIDv7 run identifier from `/runs/prepare`
        schema:
          type: string
          format: uuid
          example: 018c5e72-1b3a-7def-8abc-123456789012
      requestBody:
        required: true
        description: Newline-delimited JSON stream of terraform events
        content:
          application/x-ndjson:
            schema:
              type: string
              description: 'Terraform JSON output streamed as NDJSON (one JSON object per line).

                See Terraform documentation for event schema.

                '
              example: '{"@level":"info","type":"apply_start","@timestamp":"2025-01-01T00:00:00Z"}

                {"@level":"info","type":"apply_progress","hook":{"resource":{"addr":"aws_s3_bucket.main"},"action":"create"}}

                '
      responses:
        '202':
          description: 'Accepted - connection established and will remain open.

            Backend processes events as they arrive. Connection closes when:

            - Terraform process exits and CLI calls `/complete`

            - Network connection drops (triggers grace timer)

            - 30-minute inactivity timeout (no events received)

            - 4-hour absolute TTL exceeded

            '
        '400':
          description: Invalid JSONL format or malformed JSON in stream
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized (invalid or missing authentication token)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Run not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Run already completed or failed (cannot accept new events)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/runs/{run_id}/complete:
    post:
      operationId: completeRun
      summary: Complete a terraform run
      description: 'Signal terraform apply has finished (success or failure).


        **CLI Sequence (before calling this endpoint):**

        1. Terraform apply exits (with exit code 0 or non-zero)

        2. CLI writes all events to local `apply.jsonl` file (via streaming from terraform)

        3. CLI commits `apply.jsonl` to git repository

        4. CLI pushes commit to remote

        5. CLI calls this endpoint with exit code and commit SHA


        **Important:** CLI MUST commit and push `apply.jsonl` even on failure.

        Failed runs need logs for debugging and analysis.


        **Backend Behavior:**

        - Stores `apply_commit` in run metadata for audit trail

        - Sets `apply_path` to `workspaces/{team}/{workspace}/apply.jsonl`

        - If exit_code=0: Sets status=`succeeded`, signals Temporal `run_completed`

        - If exit_code!=0: Sets status=`failed`, stores error message, signals Temporal `run_failed`


        See ADR-012 for workflow details.'
      tags:
      - Runs
      security:
      - bearerAuth: []
      parameters:
      - name: run_id
        in: path
        required: true
        description: UUIDv7 run identifier
        schema:
          type: string
          format: uuid
          example: 018c5e72-1b3a-7def-8abc-123456789012
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - exit_code
              - apply_commit
              properties:
                exit_code:
                  type: integer
                  description: Terraform exit code (0=success, non-zero=failure)
                  example: 0
                apply_commit:
                  type: string
                  description: Git commit SHA containing `apply.jsonl`
                  example: abc123def456789abc123def456789abc123def4
                error_message:
                  type: string
                  description: Error details if exit_code is non-zero (optional)
                  example: 'Error: creating S3 bucket: AccessDenied'
      responses:
        '204':
          description: Run completed successfully (no content in response)
        '400':
          description: Invalid request (missing exit_code or apply_commit)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: 'Missing required field: exit_code'
        '401':
          description: Unauthorized (invalid or missing authentication token)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Run not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Run already completed (conflict - cannot complete twice)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/runs/{run_id}:
    get:
      operationId: getRun
      summary: Get run status and resources
      description: 'Retrieve run status and resource states. Frontend polls this endpoint to display progress.


        **Response includes:**

        - Run metadata (workspace, status, timestamps)

        - `metadata` object with resource counts, git commit, and timing info

        - `resources` array with per-resource status and duration


        **Frontend polling (from ADR-012):**

        ```typescript

        // Poll every 2 seconds while running

        const { data: run } = useQuery({

        queryKey: [''run'', runId],

        queryFn: () => fetchRun(runId),

        refetchInterval: (query) => {

        const status = query.state.data?.status;

        return status === ''running'' || status === ''pending'' ? 2000 : false;

        },

        });

        ```


        **Supported status values:**

        - `pending` - Run created, waiting for first event

        - `running` - Receiving events from CLI

        - `succeeded` - Terraform apply exit code 0

        - `failed` - Terraform apply exit code != 0

        - `timeout` - No events within 30 min, or total TTL (4 hours) exceeded

        - `disconnected` - CLI connection lost, didn''t reconnect within 2-min grace period


        **Resource status values:**

        - `pending` - Waiting to execute

        - `running` - Currently executing

        - `succeeded` - Completed successfully

        - `failed` - Execution failed


        See ADR-012 for full schema.'
      tags:
      - Runs
      security:
      - bearerAuth: []
      parameters:
      - name: run_id
        in: path
        required: true
        description: UUIDv7 run identifier
        schema:
          type: string
          format: uuid
          example: 018c5e72-1b3a-7def-8abc-123456789012
      responses:
        '200':
          description: Run details retrieved successfully
          content:
            application/json:
              schema:
                type: object
                required:
                - id
                - workspace_id
                - status
                - plan_path
                - created_at
                - metadata
                - resources
                properties:
                  id:
                    type: string
                    format: uuid
                    description: Run identifier
                    example: 018c5e72-1b3a-7def-8abc-123456789012
                  workspace_id:
                    type: string
                    description: Workspace identifier
                    example: ws_abc123def456
                  status:
                    type: string
                    enum:
                    - pending
                    - running
                    - succeeded
                    - failed
                    - timeout
                    - disconnected
                    description: Current run status
                    example: running
                  plan_path:
                    type: string
                    description: Path to plan.json in repository
                    example: workspaces/acme-corp/prod/plan.json
                  created_at:
                    type: string
                    format: date-time
                    description: When the run was created
                    example: '2025-01-01T00:00:00Z'
                  completed_at:
                    type: string
                    format: date-time
                    nullable: true
                    description: When the run completed (null if still running)
                    example: '2025-01-01T00:05:32Z'
                  metadata:
                    type: object
                    required:
                    - git_commit
                    - resource_count
                    - resources_completed
                    description: Run metadata stored in JSONB
                    properties:
                      git_commit:
                        type: string
                        description: Git commit SHA at run start
                        example: abc123deadbeef1234567890abcdef123456789
                      terraform_version:
                        type: string
                        description: Terraform version used
                        example: 1.9.5
                      resource_count:
                        type: integer
                        description: Total resources in the plan
                        example: 12
                      resources_completed:
                        type: integer
                        description: Number of resources that have completed
                        example: 5
                      last_event_at:
                        type: string
                        format: date-time
                        nullable: true
                        description: Timestamp of last event received
                        example: '2025-01-01T00:04:50Z'
                      error_message:
                        type: string
                        nullable: true
                        description: Error message if run failed
                        example: null
                      apply_commit:
                        type: string
                        nullable: true
                        description: Git commit SHA containing apply.jsonl
                        example: def456abc123def456abc123def456abc123def4
                  resources:
                    type: array
                    description: Per-resource status and timing information
                    items:
                      type: object
                      required:
                      - address
                      - resource_type
                      - status
                      properties:
                        address:
                          type: string
                          description: Terraform resource address
                          example: aws_s3_bucket.main
                        resource_type:
                          type: string
                          description: Resource type for timing aggregation
                          example: aws_s3_bucket
                        status:
                          type: string
                          enum:
                          - pending
                          - running
                          - succeeded
                          - failed
                          description: Resource execution status
                          example: succeeded
                        started_at:
                          type: string
                          format: date-time
                          nullable: true
                          description: When resource execution started
                          example: '2025-01-01T00:00:05Z'
                        completed_at:
                          type: string
                          format: date-time
                          nullable: true
                          description: When resource execution completed
                          example: '2025-01-01T00:00:10Z'
                        duration_ms:
                          type: integer
                          nullable: true
                          description: Execution duration in milliseconds
                          example: 2340
                        metadata:
                          type: object
                          description: Resource metadata
                          properties:
                            name:
                              type: string
                              description: Resource name
                              example: main
                            provider:
                              type: string
                              description: Cloud provider
                              example: aws
                            category:
                              type: string
                              enum:
                              - network
                              - compute
                              - storage
                              - security
                              - iam
                              - gpu
                              - dns
                              - cdn
                              - monitoring
                              description: Resource category for UI grouping
                              example: storage
                            lifecycle:
                              type: string
                              enum:
                              - create
                              - update
                              - delete
                              - replace
                              - no-op
                              description: Terraform lifecycle action
                              example: create
                            run_index:
                              type: integer
                              description: Execution order
                              example: 0
                            dependencies:
                              type: array
                              items:
                                type: string
                              description: Resource addresses this depends on
                              example:
                              - aws_vpc.main
                            error_message:
                              type: string
                              nullable: true
                              description: Error details if resource failed
                              example: null
              example:
                id: 018c5e72-1b3a-7def-8abc-123456789012
                workspace_id: ws_abc123def456
                status: running
                plan_path: workspaces/acme-corp/prod/plan.json
                created_at: '2025-01-01T00:00:00Z'
                completed_at: null
                metadata:
                  git_commit: abc123deadbeef1234567890abcdef123456789
                  terraform_version: 1.9.5
                  resource_count: 12
                  resources_completed: 5
                  last_event_at: '2025-01-01T00:04:50Z'
                  error_message: null
                  apply_commit: null
                resources:
                - address: aws_s3_bucket.main
                  resource_type: aws_s3_bucket
                  status: succeeded
                  started_at: '2025-01-01T00:00:05Z'
                  completed_at: '2025-01-01T00:00:10Z'
                  duration_ms: 2340
                  metadata:
                    name: main
                    provider: aws
                    category: storage
                    lifecycle: create
                    run_index: 0
                    dependencies: []
                    error_message: null
                - address: aws_vpc.main
                  resource_type: aws_vpc
                  status: running
                  started_at: '2025-01-01T00:00:12Z'
                  completed_at: null
                  duration_ms: null
                  metadata:
                    name: main
                    provider: aws
                    category: network
                    lifecycle: create
                    run_index: 1
                    dependencies: []
                    error_message: null
        '401':
          description: Unauthorized (invalid or missing authentication token)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Run not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/env/{env_id}/run/init:
    post:
      operationId: initRun
      summary: Initialize new run (deprecated)
      description: 'DEPRECATED: Use `POST /api/v1/runs/prepare` instead.


        Creates a new run for the specified environment with infrastructure files.

        This endpoint is maintained for backwards compatibility only.'
      tags:
      - Runs
      security:
      - bearerAuth: []
      deprecated: true
      parameters:
      - name: env_id
        in: path
        required: true
        description: Environment identifier
        schema:
          type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - description
              - infrastructure_files
              properties:
                description:
                  type: string
                  description: Description of the run
                infrastructure_files:
                  type: object
                  additionalProperties:
                    type: string
                  description: Map of infrastructure file names to their contents
      responses:
        '201':
          description: Run initialized successfully
          content:
            application/json:
              schema:
                type: object
                required:
                - id
                properties:
                  id:
                    type: string
                    format: uuid
                    description: UUIDv7 identifier for the newly created run
        '400':
          description: Invalid request body
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Environment not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/env/{env_id}/run/{run_id}:
    post:
      operationId: updateRun
      summary: Update run with step data (deprecated)
      description: 'DEPRECATED: Use `POST /api/v1/runs/{run_id}/events` for streaming instead.


        Updates an existing run with data from a specific step.

        This endpoint is maintained for backwards compatibility only.'
      tags:
      - Runs
      security:
      - bearerAuth: []
      deprecated: true
      parameters:
      - name: env_id
        in: path
        required: true
        description: Environment identifier
        schema:
          type: string
      - name: run_id
        in: path
        required: true
        description: Run identifier
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - step
              - data
              properties:
                step:
                  type: string
                  description: Name or identifier of the step
                data:
                  type: object
                  description: Step-specific data
      responses:
        '204':
          description: Run updated successfully (no content)
        '400':
          description: Invalid request body
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Environment or run not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /api/v1/env/{env_id}/run/{run_id}/status:
    post:
      operationId: completeRunLegacy
      summary: Complete or fail run (deprecated)
      description: 'DEPRECATED: Use `POST /api/v1/runs/{run_id}/complete` instead.


        Marks a run as completed or failed with an optional message.

        This endpoint is maintained for backwards compatibility only.'
      tags:
      - Runs
      security:
      - bearerAuth: []
      deprecated: true
      parameters:
      - name: env_id
        in: path
        required: true
        description: Environment identifier
        schema:
          type: string
      - name: run_id
        in: path
        required: true
        description: Run identifier
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - status
              properties:
                status:
                  type: string
                  enum:
                  - completed
                  - failed
                  description: Final status of the run
                message:
                  type: string
                  description: Optional message providing additional context
      responses:
        '204':
          description: Run status updated successfully (no content)
        '400':
          description: Invalid request body
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Environment or run not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    ErrorResponse:
      type: object
      description: Standard error response returned by all endpoints on failure.
      required:
      - success
      - error
      properties:
        success:
          type: boolean
          description: Always `false` for error responses.
          enum:
          - false
        error:
          type: string
          description: Human-readable error message describing what went wrong. Do not parse this programmatically — use HTTP status codes for control flow.
          example: Invalid request parameters
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'JWT token obtained from the auth service (/api/auth/token).

        Token is validated using JWKS from the auth service.

        Required claims: sub (user_id), email, name, tier.

        '