Forithmus submissions API

The submissions API from Forithmus — 18 operation(s) for submissions.

OpenAPI Specification

forithmus-submissions-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Forithmus Challenge Platform 2fa submissions API
  version: 1.0.0
tags:
- name: submissions
paths:
  /challenges/{slug}/submissions/upload-file:
    post:
      tags:
      - submissions
      summary: Upload File Submission
      description: 'Upload a prediction file (JSON, CSV, NIfTI, etc.) for a file-submission phase.

        Stored in the submissions GCS bucket.


        Uses explicit session management to avoid holding a DB connection during

        slow file I/O (ClamAV scan, GCS upload). The dependency-injected session

        from require_challenge_role is released after validation completes.'
      operationId: upload_file_submission_challenges__slug__submissions_upload_file_post
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/Body_upload_file_submission_challenges__slug__submissions_upload_file_post'
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubmissionOut'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/docker-upload-url:
    post:
      tags:
      - submissions
      summary: Docker Upload Url
      description: Generate POST Policy for direct-to-GCS Docker submission upload.
      operationId: docker_upload_url_challenges__slug__submissions_docker_upload_url_post
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Body
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/docker-upload-complete:
    post:
      tags:
      - submissions
      summary: Docker Upload Complete
      description: 'Finalize direct Docker upload: verify + scan + move to permanent key.

        Returns {gcs_key, file_size} on success — pass gcs_key to /upload-docker.'
      operationId: docker_upload_complete_challenges__slug__submissions_docker_upload_complete_post
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Body
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/docker-upload-abort:
    post:
      tags:
      - submissions
      summary: Docker Upload Abort
      description: Cancel direct Docker upload — delete partial/complete temp blob.
      operationId: docker_upload_abort_challenges__slug__submissions_docker_upload_abort_post
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Body
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/weights-upload-url:
    post:
      tags:
      - submissions
      summary: Weights Upload Url
      description: 'Generate POST Policy for direct-to-GCS model-weights upload.


        Body: {phase_id, size_bytes, filename="weights.zip"}

        Returns a signed POST policy plus a `submission_id_pending` that the eventual

        /upload-docker call must reference (so the weights GCS prefix is stable).'
      operationId: weights_upload_url_challenges__slug__submissions_weights_upload_url_post
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Body
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/weights-upload-complete:
    post:
      tags:
      - submissions
      summary: Weights Upload Complete
      description: 'Finalize a direct weights upload: verify blob, zip-bomb check, kick off

        extraction. Does NOT delete the Redis session — /upload-docker consumes it.'
      operationId: weights_upload_complete_challenges__slug__submissions_weights_upload_complete_post
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              title: Body
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/pre-upload-docker:
    post:
      tags:
      - submissions
      summary: Pre Upload Docker
      description: 'Upload a Docker container .tar.gz to GCS without creating a submission.

        Returns the GCS key for use in the submit step. Validates, scans, and stores.'
      operationId: pre_upload_docker_challenges__slug__submissions_pre_upload_docker_post
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/Body_pre_upload_docker_challenges__slug__submissions_pre_upload_docker_post'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/upload-status/{upload_id}:
    get:
      tags:
      - submissions
      summary: Get Upload Status
      description: Poll the scan status of a pre-uploaded Docker file.
      operationId: get_upload_status_challenges__slug__submissions_upload_status__upload_id__get
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      - name: upload_id
        in: path
        required: true
        schema:
          type: string
          title: Upload Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/upload-docker:
    post:
      tags:
      - submissions
      summary: Upload Docker Submission
      description: "Submit a Docker container for evaluation.\n\nTwo modes:\n  1. Pre-uploaded (recommended): pass gcs_key from pre-upload-docker. Instant.\n  2. Direct upload (legacy): pass file. Blocks during upload.\n\nOptional weights binding (separated-weights feature):\n  - weights_upload_id pairs this submission with a previously-uploaded\n    weights zip. The submission id is fixed to the upload's\n    submission_id_pending so the GCS prefix used during extraction is\n    consistent with the row written here.\n  - reuse_weights_from points at a prior submission of yours whose\n    weights to reuse (no copy: same GCS path, weights_status=\"ready\").\n  The two are mutually exclusive. Neither = legacy fully-baked image, the\n  `weights_*` columns stay NULL.\n\nUses explicit session management to avoid holding a DB connection during\nthe potentially long file stream, ClamAV scan, and GCS upload."
      operationId: upload_docker_submission_challenges__slug__submissions_upload_docker_post
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/Body_upload_docker_submission_challenges__slug__submissions_upload_docker_post'
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubmissionOut'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/{submission_id}/continue:
    post:
      tags:
      - submissions
      summary: Continue Timed Out Submission
      description: 'Continue a timed-out submission from its checkpoint.

        Accepts new tier, time budget, and spot settings for the continuation run.'
      operationId: continue_timed_out_submission_challenges__slug__submissions__submission_id__continue_post
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      - name: submission_id
        in: path
        required: true
        schema:
          type: string
          title: Submission Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ContinueRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubmissionOut'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/{submission_id}/cancel:
    post:
      tags:
      - submissions
      summary: Cancel Submission
      description: Cancel a running or timed-out submission. Refunds unused time credits.
      operationId: cancel_submission_challenges__slug__submissions__submission_id__cancel_post
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      - name: submission_id
        in: path
        required: true
        schema:
          type: string
          title: Submission Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubmissionOut'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/{submission_id}/docker-image:
    get:
      tags:
      - submissions
      summary: Download Docker Image
      description: 'Download a kept Docker image for a scored submission. Admin only.

        Only available when keep_docker_images is enabled and the image exists.

        Returns a streaming tar.gz response in dev, or a signed registry URL in production.'
      operationId: download_docker_image_challenges__slug__submissions__submission_id__docker_image_get
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      - name: submission_id
        in: path
        required: true
        schema:
          type: string
          title: Submission Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/estimate:
    get:
      tags:
      - submissions
      summary: Estimate Cost
      description: Estimate the cost of a submission before committing.
      operationId: estimate_cost_challenges__slug__submissions_estimate_get
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      - name: tier
        in: query
        required: false
        schema:
          type: string
          default: cpu-4
          title: Tier
      - name: time_budget_minutes
        in: query
        required: false
        schema:
          type: integer
          default: 60
          title: Time Budget Minutes
      - name: use_spot
        in: query
        required: false
        schema:
          type: boolean
          default: false
          title: Use Spot
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions:
    get:
      tags:
      - submissions
      summary: List Submissions
      description: List submissions. Participants see own only; admins/reviewers/staff see all.
      operationId: list_submissions_challenges__slug__submissions_get
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      - name: phase_id
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Phase Id
      - name: flagged
        in: query
        required: false
        schema:
          anyOf:
          - type: boolean
          - type: 'null'
          description: 'Filter by leakage flags: true=flagged only, false=clean only'
          title: Flagged
        description: 'Filter by leakage flags: true=flagged only, false=clean only'
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          maximum: 200
          minimum: 1
          default: 50
          title: Limit
      - name: offset
        in: query
        required: false
        schema:
          type: integer
          minimum: 0
          default: 0
          title: Offset
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/{submission_id}:
    get:
      tags:
      - submissions
      summary: Get Submission
      description: Get submission details. Own submissions or admin/reviewer/staff access.
      operationId: get_submission_challenges__slug__submissions__submission_id__get
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      - name: submission_id
        in: path
        required: true
        schema:
          type: string
          title: Submission Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubmissionOut'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/{submission_id}/logs:
    get:
      tags:
      - submissions
      summary: Get Submission Logs
      description: Get container stdout/stderr logs for a submission.
      operationId: get_submission_logs_challenges__slug__submissions__submission_id__logs_get
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      - name: submission_id
        in: path
        required: true
        schema:
          type: string
          title: Submission Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/{submission_id}/outputs:
    get:
      tags:
      - submissions
      summary: Get Submission Outputs
      description: "List output files for a scored submission.\n\nSECURITY: Only challenge admins and platform staff can download output files.\nParticipants cannot download predictions/evaluation outputs because:\n  1. Predictions may contain exfiltrated test data (steganography, encoded data, etc.)\n  2. GCS egress fees would be incurred on every download\nParticipants only see metrics and scores — not raw files."
      operationId: get_submission_outputs_challenges__slug__submissions__submission_id__outputs_get
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      - name: submission_id
        in: path
        required: true
        schema:
          type: string
          title: Submission Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/submissions/{submission_id}/outputs/download:
    get:
      tags:
      - submissions
      summary: Download Output File
      description: 'Download a single output file. Rate-limited: 1 download per file per week per user.

        Only challenge admins and platform staff can download.

        Returns a short-lived signed URL (15 min).'
      operationId: download_output_file_challenges__slug__submissions__submission_id__outputs_download_get
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      - name: submission_id
        in: path
        required: true
        schema:
          type: string
          title: Submission Id
      - name: path
        in: query
        required: true
        schema:
          type: string
          description: GCS path of the file to download
          title: Path
        description: GCS path of the file to download
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    Body_upload_file_submission_challenges__slug__submissions_upload_file_post:
      properties:
        file:
          type: string
          format: binary
          title: File
        phase_id:
          type: string
          title: Phase Id
        description:
          type: string
          title: Description
          default: ''
      type: object
      required:
      - file
      - phase_id
      title: Body_upload_file_submission_challenges__slug__submissions_upload_file_post
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    Body_upload_docker_submission_challenges__slug__submissions_upload_docker_post:
      properties:
        file:
          type: string
          format: binary
          title: File
        gcs_key:
          type: string
          title: Gcs Key
        phase_id:
          type: string
          title: Phase Id
        tier:
          type: string
          title: Tier
          default: cpu-4
        use_spot:
          type: boolean
          title: Use Spot
          default: false
        time_budget_minutes:
          type: integer
          title: Time Budget Minutes
          default: 60
        description:
          type: string
          title: Description
          default: ''
        weights_upload_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Weights Upload Id
        reuse_weights_from:
          anyOf:
          - type: string
          - type: 'null'
          title: Reuse Weights From
      type: object
      required:
      - phase_id
      title: Body_upload_docker_submission_challenges__slug__submissions_upload_docker_post
    SubmissionOut:
      properties:
        id:
          type: string
          format: uuid
          title: Id
        challenge_id:
          type: string
          format: uuid
          title: Challenge Id
        phase_id:
          anyOf:
          - type: string
            format: uuid
          - type: 'null'
          title: Phase Id
        user_id:
          type: string
          format: uuid
          title: User Id
        status:
          type: string
          title: Status
        description:
          type: string
          title: Description
        gcs_key:
          anyOf:
          - type: string
          - type: 'null'
          title: Gcs Key
        submission_file_key:
          anyOf:
          - type: string
          - type: 'null'
          title: Submission File Key
        model_image_uri:
          anyOf:
          - type: string
          - type: 'null'
          title: Model Image Uri
        tier:
          anyOf:
          - type: string
          - type: 'null'
          title: Tier
        use_spot:
          type: boolean
          title: Use Spot
          default: false
        time_budget_minutes:
          anyOf:
          - type: integer
          - type: 'null'
          title: Time Budget Minutes
        cost_charged:
          anyOf:
          - type: number
          - type: 'null'
          title: Cost Charged
        cost_actual:
          anyOf:
          - type: number
          - type: 'null'
          title: Cost Actual
        cost_refunded:
          anyOf:
          - type: number
          - type: 'null'
          title: Cost Refunded
        duration_seconds:
          anyOf:
          - type: number
          - type: 'null'
          title: Duration Seconds
        metrics:
          type: object
          title: Metrics
          default: {}
        score:
          anyOf:
          - type: number
          - type: 'null'
          title: Score
        rank:
          anyOf:
          - type: integer
          - type: 'null'
          title: Rank
        error_message:
          anyOf:
          - type: string
          - type: 'null'
          title: Error Message
        leakage_flags:
          anyOf:
          - items:
              type: string
            type: array
          - type: 'null'
          title: Leakage Flags
        created_at:
          type: string
          format: date-time
          title: Created At
        completed_at:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Completed At
      type: object
      required:
      - id
      - challenge_id
      - phase_id
      - user_id
      - status
      - description
      - gcs_key
      - submission_file_key
      - model_image_uri
      - tier
      - score
      - rank
      - error_message
      - created_at
      - completed_at
      title: SubmissionOut
      description: Full submission details including evaluation results.
    ContinueRequest:
      properties:
        tier:
          anyOf:
          - type: string
          - type: 'null'
          title: Tier
        time_budget_minutes:
          anyOf:
          - type: integer
          - type: 'null'
          title: Time Budget Minutes
        use_spot:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Use Spot
      type: object
      title: ContinueRequest
    Body_pre_upload_docker_challenges__slug__submissions_pre_upload_docker_post:
      properties:
        file:
          type: string
          format: binary
          title: File
        phase_id:
          type: string
          title: Phase Id
      type: object
      required:
      - file
      - phase_id
      title: Body_pre_upload_docker_challenges__slug__submissions_pre_upload_docker_post