openapi: 3.1.0
info:
  title: PlatPhorm Data Studio API
  version: 1.0.0
  description: Public-safe platform metadata, read-only MCP capability discovery, and explicit protected publishing of a selected generated export for the local-first PlatPhorm Data Studio.
  contact:
    url: https://platphormnews.com
servers:
  - url: https://data.platphormnews.com
    description: Canonical production
tags:
  - name: Health
  - name: Discovery
  - name: Compliance
  - name: MCP
  - name: Publishing
paths:
  /api/health:
    get:
      tags: [Health]
      operationId: getHealth
      summary: Read the public-safe service health summary
      responses:
        "200":
          description: Health summary
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Success"
  /api/v1/health:
    get:
      tags: [Health]
      operationId: getVersionedHealth
      summary: Read the versioned public-safe service health summary
      responses:
        "200":
          description: Health summary
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Success"
  /api/docs:
    get:
      tags: [Discovery]
      operationId: getApiDocs
      summary: Read API, local-processing, format, and trust documentation
      responses:
        "200":
          description: Documentation
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Success"
  /api/v1/compliance:
    get:
      tags: [Compliance]
      operationId: getDeclaredCompliance
      summary: Read the declared standard-route implementation status
      responses:
        "200":
          description: Declared compliance
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Success"
    post:
      tags: [Compliance]
      operationId: runLiveCompliance
      summary: Trigger a fresh live check of the canonical standard routes
      security:
        - PlatPhormBearer: []
        - PlatPhormHeader: []
      responses:
        "200":
          description: Live route-check results
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Success"
        "401":
          description: Missing or invalid PLATPHORM_API_KEY
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: PLATPHORM_API_KEY is not configured
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/publish:
    post:
      tags: [Publishing]
      operationId: publishGeneratedExport
      summary: Publish one explicitly selected generated export to a compatible PlatPhorm service
      description: Source files and source rows are never accepted. Generated exports use a fixed allowlisted PlatPhorm destination and must produce a durable receipt. Sheets, Docs, and OpenContent use the 4 MiB relay. Larger Files exports use a short-lived direct object-store ticket up to 2 GiB and are indexed only after S3 SHA-256 and byte-count verification. Local imports and downloads have no application size cap.
      security:
        - PlatPhormBearer: []
        - PlatPhormHeader: []
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required: [destination, format, title, fileName, file]
              properties:
                destination:
                  type: string
                  enum: [sheets, docs, opencontent, files]
                format:
                  type: string
                  enum: [csv, tsv, json, ndjson, parquet, arrow, sqlite, markdown, html, sql, vcard, google-contacts-csv]
                title:
                  type: string
                  minLength: 1
                  maxLength: 200
                fileName:
                  type: string
                  minLength: 1
                  maxLength: 220
                file:
                  type: string
                  format: binary
                  maxLength: 4194304
          application/json:
            schema:
              oneOf:
                - type: object
                  required: [action, destination, format, title, fileName, contentType, size, checksumSHA256]
                  properties:
                    action:
                      type: string
                      const: create_direct_files_upload
                    destination:
                      type: string
                      const: files
                    format:
                      type: string
                      enum: [csv, tsv, json, ndjson, parquet, arrow, sqlite, markdown, html, sql, vcard, google-contacts-csv]
                    title:
                      type: string
                      minLength: 1
                      maxLength: 200
                    fileName:
                      type: string
                      minLength: 1
                      maxLength: 220
                    contentType:
                      type: string
                    size:
                      type: integer
                      minimum: 1
                      maximum: 2147483648
                    checksumSHA256:
                      type: string
                      description: Base64-encoded SHA-256 digest
                - type: object
                  required: [action, destination, format, title, fileName, contentType, size, checksumSHA256, path]
                  properties:
                    action:
                      type: string
                      const: complete_direct_files_upload
                    destination:
                      type: string
                      const: files
                    format:
                      type: string
                    title:
                      type: string
                    fileName:
                      type: string
                    contentType:
                      type: string
                    size:
                      type: integer
                      minimum: 1
                      maximum: 2147483648
                    checksumSHA256:
                      type: string
                    path:
                      type: string
                      pattern: "^data-studio/"
      responses:
        "201":
          description: The destination returned durable publication evidence
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Success"
        "400":
          description: Invalid metadata, unsupported format/destination pair, or invalid text encoding
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "401":
          description: Missing or invalid PLATPHORM_API_KEY
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "413":
          description: Generated export exceeds the 4 MiB document relay; Files direct publishing supports larger exports up to 2 GiB
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "429":
          description: Protected publish rate limit exceeded
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "502":
          description: Destination rejected the transfer, was unavailable, or did not return a durable receipt
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "503":
          description: PLATPHORM_API_KEY is not configured
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/mcp:
    get:
      tags: [MCP]
      operationId: getMcpMetadata
      summary: Read MCP endpoint metadata and usage
      responses:
        "200":
          description: MCP metadata
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Success"
    post:
      tags: [MCP]
      operationId: callMcp
      summary: Call the public read-only JSON-RPC 2.0 MCP endpoint
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/JsonRpcRequest"
                - type: array
                  minItems: 1
                  items:
                    $ref: "#/components/schemas/JsonRpcRequest"
      responses:
        "200":
          description: JSON-RPC response or batch
          content:
            application/json:
              schema: {}
        "204":
          description: Notification accepted without a response body
        "400":
          description: Parse error or invalid request
          content:
            application/json:
              schema: {}
components:
  securitySchemes:
    PlatPhormBearer:
      type: http
      scheme: bearer
      bearerFormat: PLATPHORM_API_KEY
      description: "Authorization: Bearer $PLATPHORM_API_KEY"
    PlatPhormHeader:
      type: apiKey
      in: header
      name: X-PlatPhorm-API-Key
      description: "X-PlatPhorm-API-Key: $PLATPHORM_API_KEY"
  schemas:
    Success:
      type: object
      required: [ok, data]
      properties:
        ok:
          const: true
        data: {}
    Error:
      type: object
      required: [ok, error]
      properties:
        ok:
          const: false
        error:
          type: object
          required: [code, message, details]
          properties:
            code:
              type: string
            message:
              type: string
            details:
              type: object
    JsonRpcRequest:
      type: object
      required: [jsonrpc, method]
      properties:
        jsonrpc:
          const: "2.0"
        id:
          oneOf:
            - type: string
            - type: number
            - type: "null"
        method:
          type: string
        params:
          type: object
