openapi: 3.0.3
info:
  title: OpenStrate reconstruction API
  version: "1.0.0"
  description: |
    Public HTTPS API for **video-to-3D reconstruction**, job polling, and mesh / point-cloud artifacts on **openstrate.com**.

    **No API key** is required for the public upload → poll → download flow documented here. Use this spec with OpenAPI-aware agents, codegen, or validation tools.

    **Human prose (Markdown):** https://openstrate.com/openstrate-reconstruction-api.md  
    **Rendered HTML:** https://openstrate.com/reconstruction-api/  
    **Site index for agents:** https://openstrate.com/llms.txt

    Integrators should **not** call internal pipeline callbacks (`/api/reconstruct/progress/…`, `/complete/…`, `/session/…`); those are for the reconstruction service.
  contact:
    url: https://openstrate.com/reconstruction-api/
  license:
    name: Proprietary
    url: https://openstrate.com/

servers:
  - url: https://openstrate.com
    description: Production

tags:
  - name: ingest
    description: Upload and job creation
  - name: jobs
    description: Reconstruction job status
  - name: artifacts
    description: Files, viewer URLs, previews

paths:
  /api/upload:
    post:
      tags: [ingest]
      summary: Multipart upload (video starts reconstruction)
      description: |
        Single field `file`. Video formats trigger reconstruction in the same response (`job_id` when started).
        Mesh / 3D asset uploads return storage URLs without a reconstruction job.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required: [file]
              properties:
                file:
                  type: string
                  format: binary
                  description: One file (.mp4, .mov, .glb, .ply, etc.; max ~500 MB).
      responses:
        "200":
          description: Stored file metadata; video responses include job fields when reconstruction started.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UploadResponse"
        "400":
          description: Missing or invalid file.
        "500":
          description: Storage or internal error.

  /api/reconstruct:
    post:
      tags: [ingest]
      summary: Start reconstruction from a public video URL
      description: Use when the video is already at an HTTPS URL OpenStrate’s worker can fetch (e.g. prior upload `url`).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ReconstructRequest"
      responses:
        "200":
          description: Job accepted.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReconstructAccepted"
        "400":
          description: Missing or invalid `video_url`.
        "503":
          description: Reconstruction worker unavailable.

  /api/reconstruct/status/{job_id}:
    get:
      tags: [jobs]
      summary: Get job document (poll until complete or failed)
      parameters:
        - name: job_id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Job state and artifact hints (`view_url`, etc. when complete).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JobStatus"
        "404":
          description: Unknown job id.

  /api/files/{fileRef}:
    get:
      tags: [artifacts]
      summary: Download stored asset
      description: |
        `fileRef` is the file id **including extension**, e.g. `{uuid}.glb` or `{uuid}.mp4`.
      parameters:
        - name: fileRef
          in: path
          required: true
          schema:
            type: string
            example: a1b2c3d4-e5f6-7890-abcd-ef1234567890.glb
      responses:
        "200":
          description: Binary file (format depends on extension).
        "404":
          description: Unknown file.

  /api/preview/{fileRef}:
    get:
      tags: [artifacts]
      summary: Preview image for link unfurls
      parameters:
        - name: fileRef
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Image (e.g. PNG).
        "404":
          description: Unknown preview.

  /view/{fileRef}:
    get:
      tags: [artifacts]
      summary: Browser WebGL viewer page for an asset
      description: HTML page (not JSON). For headless automation, prefer `GET /api/files/{fileRef}` or `view_url` from job status.
      parameters:
        - name: fileRef
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: HTML viewer.
        "404":
          description: Unknown asset.

components:
  schemas:
    ReconstructRequest:
      type: object
      required: [video_url]
      properties:
        video_url:
          type: string
          format: uri
          description: HTTPS URL the worker can download.
        filename:
          type: string
          description: Optional label for logs / metadata.

    ReconstructAccepted:
      type: object
      properties:
        job_id:
          type: string
        status:
          type: string
          example: processing

    UploadResponse:
      type: object
      description: Shape varies slightly for mesh vs video; common fields below.
      properties:
        id:
          type: string
          format: uuid
        filename:
          type: string
        url:
          type: string
          format: uri
        view:
          type: string
          format: uri
        size:
          type: integer
        job_id:
          type: string
          description: Present for video uploads when reconstruction started.
        reconstruction_started:
          type: boolean
        reconstruction_error:
          type: string
          description: Present if pipeline could not be reached.

    JobStatus:
      type: object
      description: Persisted job document; fields vary by pipeline version.
      properties:
        status:
          type: string
          enum: [pending, processing, complete, failed]
        current_frame:
          type: integer
        total_frames:
          type: integer
        view_url:
          type: string
          format: uri
        mesh_viewer_url:
          type: string
          format: uri
        glb_asset_url:
          type: string
          format: uri
        mission_id:
          type: string
          description: Progressive / live viewer flows.
        relay_base:
          type: string
          format: uri
        error:
          type: string
