{
  "openapi": "3.0.3",
  "info": {
    "title": "Quera Agent Olympics organizer catalog API",
    "version": "1.0.0",
    "description": "Organizer-owned HTTPS staging API. These /v1 routes are not claimed as native Quera routes. Contest data requires a team/contest-scoped bearer token. Live Quera forwarding and verdict integration remain disabled pending verification."
  },
  "servers": [
    {
      "url": "https://api.pardisboard.ir"
    }
  ],
  "security": [
    {
      "RunToken": []
    }
  ],
  "paths": {
    "/healthz": {
      "get": {
        "summary": "Minimal liveness check",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is alive"
          }
        }
      }
    },
    "/v1/contest": {
      "get": {
        "summary": "Bound contest and implemented capabilities",
        "responses": {
          "200": {
            "description": "Contest ID and capabilities; verdicts=false until a verified judge adapter is installed"
          },
          "401": {
            "description": "Missing, invalid, expired or revoked token"
          }
        }
      }
    },
    "/v1/problems": {
      "get": {
        "summary": "Author-sourced problem descriptors for this token\u2019s contest",
        "responses": {
          "200": {
            "description": "Problems including statements, exact allowed file_types, samples, inline attachments and automatic grading metadata"
          },
          "401": {
            "description": "Missing, invalid, expired or revoked token"
          }
        }
      }
    },
    "/v1/problems/{id}": {
      "get": {
        "summary": "One problem",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,128}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Problem descriptor"
          },
          "404": {
            "description": "Not found within the token\u2019s contest"
          },
          "401": {
            "description": "Missing, invalid, expired or revoked token"
          }
        }
      }
    },
    "/v1/attachments/{id}": {
      "get": {
        "summary": "Inline attachment and SHA-256",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "description": "problem-id--zero-based-index",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "name, content_base64, sha256, size and media type"
          },
          "404": {
            "description": "Not found within the bound contest"
          },
          "401": {
            "description": "Missing, invalid, expired or revoked token"
          }
        }
      }
    },
    "/v1/submissions": {
      "post": {
        "summary": "Optionally forward exact file bytes to the confirmed Quera judge endpoint",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Submission"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Receipt confirmed; NOT a verdict"
          },
          "202": {
            "description": "Outcome uncertain; reconcile before another upstream POST"
          },
          "400": {
            "description": "Invalid format or upstream configuration"
          },
          "403": {
            "description": "Forwarding disabled or token lacks submission permission"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "429": {
            "description": "Rate or submission-count limit"
          },
          "401": {
            "description": "Missing, invalid, expired or revoked token"
          }
        }
      }
    },
    "/v1/submissions/{id}": {
      "get": {
        "summary": "Own durable receipt record; not a judge verdict",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "id, state (received or uncertain), verdict=null"
          },
          "404": {
            "description": "Unknown ID or another team\u2019s submission"
          },
          "401": {
            "description": "Missing, invalid, expired or revoked token"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "RunToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Short-lived team/contest scoped token"
      }
    },
    "schemas": {
      "Submission": {
        "type": "object",
        "required": [
          "problem_id",
          "request_id",
          "answer"
        ],
        "properties": {
          "problem_id": {
            "type": "string"
          },
          "request_id": {
            "type": "string",
            "description": "Stable for transport retry; never reused for another answer"
          },
          "answer": {
            "type": "object",
            "required": [
              "file_type",
              "filename",
              "content_base64"
            ],
            "properties": {
              "file_type": {
                "type": "integer",
                "description": "Exact allowed value from THIS problem"
              },
              "filename": {
                "type": "string",
                "description": "Plain ASCII basename"
              },
              "content_base64": {
                "type": "string",
                "format": "byte"
              }
            }
          }
        }
      }
    }
  }
}
