Forithmus challenges API

The challenges API from Forithmus — 7 operation(s) for challenges.

OpenAPI Specification

forithmus-challenges-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Forithmus Challenge Platform 2fa challenges API
  version: 1.0.0
tags:
- name: challenges
paths:
  /challenges/meta/categories:
    get:
      tags:
      - challenges
      summary: List Categories
      description: 'List all distinct challenge categories currently in use, sorted alphabetically.

        Used by frontend for dynamic category dropdowns and browse filters.'
      operationId: list_categories_challenges_meta_categories_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
  /challenges:
    get:
      tags:
      - challenges
      summary: List Challenges
      description: 'List public challenges with pagination.

        If mine=true (requires auth), returns all challenges the user is an active member of.

        Returns: { items: [...], total: int, limit: int, offset: int }'
      operationId: list_challenges_challenges_get
      parameters:
      - name: status
        in: query
        required: false
        schema:
          type: string
          default: open
          title: Status
      - name: category
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Category
      - name: mine
        in: query
        required: false
        schema:
          type: boolean
          default: false
          title: Mine
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          maximum: 100
          minimum: 1
          default: 20
          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'
    post:
      tags:
      - challenges
      summary: Create Challenge
      description: 'Create a new challenge in ''draft'' status. Requires email verification.

        The creator is automatically added as a ChallengeMember with role=''admin''.

        After creation, the admin must upload test data and evaluation container,

        then transition status to ''open'' via PUT.'
      operationId: create_challenge_challenges_post
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChallengeCreate'
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChallengeOut'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/registry-usage:
    get:
      tags:
      - challenges
      summary: Get Registry Usage Endpoint
      description: Get Docker registry storage usage for this challenge. Admin only.
      operationId: get_registry_usage_endpoint_challenges__slug__registry_usage_get
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/registry-purge:
    post:
      tags:
      - challenges
      summary: Purge Registry
      description: Delete all kept Docker images for this challenge. Admin only.
      operationId: purge_registry_challenges__slug__registry_purge_post
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}/stats:
    get:
      tags:
      - challenges
      summary: Get Challenge Stats
      description: 'Stats for a challenge: participants by country/institution, submission stats.

        Private challenges require membership. Public challenges are open to all.

        Cached in Redis for 5 minutes to avoid expensive aggregation queries on every load.'
      operationId: get_challenge_stats_challenges__slug__stats_get
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/by-id/{challenge_id}:
    get:
      tags:
      - challenges
      summary: Get Challenge By Id
      description: Look up a challenge slug by its UUID. Used by notifications.
      operationId: get_challenge_by_id_challenges_by_id__challenge_id__get
      parameters:
      - name: challenge_id
        in: path
        required: true
        schema:
          type: string
          title: Challenge Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /challenges/{slug}:
    get:
      tags:
      - challenges
      summary: Get Challenge
      description: 'Get challenge details. Private challenges require active membership.

        Platform superadmin/staff can always view.'
      operationId: get_challenge_challenges__slug__get
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChallengeOut'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
    put:
      tags:
      - challenges
      summary: Update Challenge
      description: 'Update challenge settings. Only challenge admins can update.

        Platform superadmin/staff also have access (handled by require_challenge_role).

        Status changes are validated against ALLOWED_STATUS_TRANSITIONS

        (e.g. draft->open, open->closed). All other fields are freely editable.'
      operationId: update_challenge_challenges__slug__put
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChallengeUpdate'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChallengeOut'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
    delete:
      tags:
      - challenges
      summary: Delete Challenge
      description: 'Delete a challenge and all related data (members, phases, pages, forum, submissions).

        Only challenge admins or platform superadmin/staff can delete.

        Cascade delete is handled by the database (ondelete=CASCADE on foreign keys).'
      operationId: delete_challenge_challenges__slug__delete
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          title: Slug
      responses:
        '204':
          description: Successful Response
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    ChallengeCreate:
      properties:
        title:
          type: string
          maxLength: 200
          minLength: 1
          title: Title
        acronym:
          type: string
          maxLength: 20
          minLength: 1
          title: Acronym
        description:
          type: string
          title: Description
          default: ''
        category:
          type: string
          title: Category
          default: Segmentation
        visibility:
          type: string
          title: Visibility
          default: public
        tier:
          type: string
          title: Tier
          default: gpu-t4
        timeout_minutes:
          type: integer
          maximum: 360.0
          minimum: 5.0
          title: Timeout Minutes
          default: 60
        max_submissions_per_user:
          type: integer
          maximum: 100.0
          minimum: 1.0
          title: Max Submissions Per User
          default: 10
        score_json_path:
          type: string
          title: Score Json Path
          default: $.metrics.dice
        sort_direction:
          type: string
          title: Sort Direction
          default: desc
        deadline:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Deadline
      type: object
      required:
      - title
      - acronym
      title: ChallengeCreate
      description: 'Request body for POST /challenges: creates a new challenge in ''draft'' status.'
    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
    ChallengeUpdate:
      properties:
        title:
          anyOf:
          - type: string
            maxLength: 200
          - type: 'null'
          title: Title
        acronym:
          anyOf:
          - type: string
            maxLength: 20
          - type: 'null'
          title: Acronym
        description:
          anyOf:
          - type: string
          - type: 'null'
          title: Description
        category:
          anyOf:
          - type: string
          - type: 'null'
          title: Category
        visibility:
          anyOf:
          - type: string
          - type: 'null'
          title: Visibility
        status:
          anyOf:
          - type: string
          - type: 'null'
          title: Status
        tier:
          anyOf:
          - type: string
          - type: 'null'
          title: Tier
        timeout_minutes:
          anyOf:
          - type: integer
            maximum: 360.0
            minimum: 5.0
          - type: 'null'
          title: Timeout Minutes
        max_submissions_per_user:
          anyOf:
          - type: integer
            maximum: 100.0
            minimum: 1.0
          - type: 'null'
          title: Max Submissions Per User
        score_json_path:
          anyOf:
          - type: string
          - type: 'null'
          title: Score Json Path
        sort_direction:
          anyOf:
          - type: string
          - type: 'null'
          title: Sort Direction
        deadline:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Deadline
        forum_enabled:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Forum Enabled
        timeline_enabled:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Timeline Enabled
        groups_enabled:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Groups Enabled
        require_approval:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Require Approval
        current_edition:
          anyOf:
          - type: string
          - type: 'null'
          title: Current Edition
        editions:
          anyOf:
          - items:
              type: string
            type: array
          - type: 'null'
          title: Editions
        resource_overrides:
          anyOf:
          - items:
              type: object
            type: array
          - type: 'null'
          title: Resource Overrides
        eval_cost_limit:
          anyOf:
          - type: number
            maximum: 1000.0
            minimum: 1.0
          - type: 'null'
          title: Eval Cost Limit
        participant_pays_compute:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Participant Pays Compute
        spot_enabled:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Spot Enabled
        keep_docker_images:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Keep Docker Images
        keep_submission_outputs:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Keep Submission Outputs
        hide_submission_logs:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Hide Submission Logs
        storage_price_per_tb:
          anyOf:
          - type: number
          - type: 'null'
          title: Storage Price Per Tb
        storage_free_tier_gb:
          anyOf:
          - type: number
          - type: 'null'
          title: Storage Free Tier Gb
        registry_limit_gb:
          anyOf:
          - type: number
          - type: 'null'
          title: Registry Limit Gb
        registry_price_per_gb:
          anyOf:
          - type: number
          - type: 'null'
          title: Registry Price Per Gb
        output_limit_gb:
          anyOf:
          - type: number
          - type: 'null'
          title: Output Limit Gb
        eval_excess_enabled:
          anyOf:
          - type: boolean
          - type: 'null'
          title: Eval Excess Enabled
        cover_image_url:
          anyOf:
          - type: string
          - type: 'null'
          title: Cover Image Url
        card_image_url:
          anyOf:
          - type: string
          - type: 'null'
          title: Card Image Url
        cover_image_original_url:
          anyOf:
          - type: string
          - type: 'null'
          title: Cover Image Original Url
        card_image_original_url:
          anyOf:
          - type: string
          - type: 'null'
          title: Card Image Original Url
      type: object
      title: ChallengeUpdate
      description: 'Request body for PUT /challenges/{slug}: all fields optional (partial update).

        Note: visibility is intentionally excluded: it is set at creation and cannot be changed.'
    ChallengeOut:
      properties:
        id:
          type: string
          format: uuid
          title: Id
        slug:
          type: string
          title: Slug
        collection_id:
          anyOf:
          - type: string
            format: uuid
          - type: 'null'
          title: Collection Id
        title:
          type: string
          title: Title
        acronym:
          type: string
          title: Acronym
          default: ''
        collection_acronym:
          anyOf:
          - type: string
          - type: 'null'
          title: Collection Acronym
        description:
          type: string
          title: Description
        category:
          type: string
          title: Category
        visibility:
          type: string
          title: Visibility
        status:
          type: string
          title: Status
        tier:
          type: string
          title: Tier
        timeout_minutes:
          type: integer
          title: Timeout Minutes
        max_submissions_per_user:
          type: integer
          title: Max Submissions Per User
        score_json_path:
          type: string
          title: Score Json Path
        sort_direction:
          type: string
          title: Sort Direction
        submission_count:
          type: integer
          title: Submission Count
        participant_count:
          type: integer
          title: Participant Count
          default: 0
        forum_enabled:
          type: boolean
          title: Forum Enabled
        timeline_enabled:
          type: boolean
          title: Timeline Enabled
          default: true
        groups_enabled:
          type: boolean
          title: Groups Enabled
          default: false
        require_approval:
          type: boolean
          title: Require Approval
          default: false
        current_edition:
          anyOf:
          - type: string
          - type: 'null'
          title: Current Edition
        editions:
          items:
            type: string
          type: array
          title: Editions
          default: []
        has_sponsor_pool:
          type: boolean
          title: Has Sponsor Pool
          default: false
        resource_overrides:
          items:
            type: object
          type: array
          title: Resource Overrides
          default: []
        eval_cost_limit:
          type: number
          title: Eval Cost Limit
          default: 20.0
        participant_pays_compute:
          type: boolean
          title: Participant Pays Compute
          default: false
        spot_enabled:
          type: boolean
          title: Spot Enabled
          default: false
        keep_docker_images:
          type: boolean
          title: Keep Docker Images
          default: false
        keep_submission_outputs:
          type: boolean
          title: Keep Submission Outputs
          default: false
        registry_purge_after:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Registry Purge After
        data_retention_until:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Data Retention Until
        hide_submission_logs:
          type: boolean
          title: Hide Submission Logs
          default: false
        storage_price_per_tb:
          anyOf:
          - type: number
          - type: 'null'
          title: Storage Price Per Tb
        storage_free_tier_gb:
          anyOf:
          - type: number
          - type: 'null'
          title: Storage Free Tier Gb
        registry_limit_gb:
          anyOf:
          - type: number
          - type: 'null'
          title: Registry Limit Gb
        output_limit_gb:
          anyOf:
          - type: number
          - type: 'null'
          title: Output Limit Gb
        eval_excess_enabled:
          type: boolean
          title: Eval Excess Enabled
          default: false
        subscription_status:
          anyOf:
          - type: string
          - type: 'null'
          title: Subscription Status
        host_user_id:
          type: string
          format: uuid
          title: Host User Id
        deadline:
          anyOf:
          - type: string
            format: date-time
          - type: 'null'
          title: Deadline
        cover_image_url:
          anyOf:
          - type: string
          - type: 'null'
          title: Cover Image Url
        card_image_url:
          anyOf:
          - type: string
          - type: 'null'
          title: Card Image Url
        cover_image_original_url:
          anyOf:
          - type: string
          - type: 'null'
          title: Cover Image Original Url
        card_image_original_url:
          anyOf:
          - type: string
          - type: 'null'
          title: Card Image Original Url
        created_at:
          type: string
          format: date-time
          title: Created At
        updated_at:
          type: string
          format: date-time
          title: Updated At
      type: object
      required:
      - id
      - slug
      - title
      - description
      - category
      - visibility
      - status
      - tier
      - timeout_minutes
      - max_submissions_per_user
      - score_json_path
      - sort_direction
      - submission_count
      - forum_enabled
      - host_user_id
      - deadline
      - created_at
      - updated_at
      title: ChallengeOut
      description: Full challenge representation returned by detail endpoints.