{
  "openapi": "3.1.0",
  "info": {
    "title": "UZFOX Developer API",
    "version": "1.1.0",
    "description": "OpenBudget project metadata, user-controlled official voting handoff, developer wallet and audited usage API."
  },
  "servers": [
    {
      "url": "https://api.uzfox.uz"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/health": {
      "get": {
        "summary": "Service health",
        "security": [],
        "responses": {
          "200": {
            "description": "Operational"
          }
        }
      }
    },
    "/v1/projects/resolve": {
      "get": {
        "summary": "Resolve an official OpenBudget project URL",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Resolved project"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/v1/wallet": {
      "get": {
        "summary": "Read developer wallet",
        "responses": {
          "200": {
            "description": "Wallet state"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "summary": "List API usage",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 30
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Usage list"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/wallet/topups": {
      "post": {
        "summary": "Create an idempotent wallet top-up checkout",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "amount",
                  "provider"
                ],
                "properties": {
                  "amount": {
                    "type": "integer",
                    "minimum": 50000,
                    "maximum": 100000000,
                    "multipleOf": 5000
                  },
                  "provider": {
                    "type": "string",
                    "enum": [
                      "click",
                      "payme"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Checkout created or reused"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/v1/vote-sessions": {
      "post": {
        "summary": "Create a user-controlled official voting handoff",
        "description": "Resolves the project and returns an official OpenBudget URL that must be opened by the user. This method does not accept phone numbers, CAPTCHA data or confirmation codes, does not cast a vote automatically and does not charge the wallet.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "project_url"
                ],
                "properties": {
                  "project_url": {
                    "type": "string",
                    "format": "uri",
                    "pattern": "^https://([a-z0-9-]+\\\\.)*openbudget\\\\.uz/"
                  },
                  "locale": {
                    "type": "string",
                    "enum": [
                      "uz",
                      "ru"
                    ],
                    "default": "uz"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "User action handoff created"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "503": {
            "description": "Project resolver is temporarily unavailable"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "UZFOX API key"
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "API key is missing, invalid or inactive"
      },
      "ValidationError": {
        "description": "Request validation failed"
      }
    }
  }
}
