{
  "openapi": "3.0.0",
  "info": {
    "title": "Gokapi",
    "description": "[https://github.com/Forceu/Gokapi](https://github.com/Forceu/Gokapi)\n",
    "version": "1.0"
  },
  "servers": [
    {
      "url": "/api/",
      "description": "Target Server"
    }
  ],
  "security": [
    {
      "apikey": ["VIEW","UPLOAD","DELETE", "API_MANAGE"]
    },
    {
      "session": []
    }
  ],
  "tags": [
    {
      "name": "files"
    },
    {
      "name": "auth"
    }
  ],
  "paths": {
    "/files/list": {
      "get": {
        "tags": [
          "files"
        ],
        "summary": "Lists all files",
        "description": "This API call lists all files that are not expired. Returns null, if no files are stored. Requires permission VIEW",
        "operationId": "list",
        "security": [
          {
            "apikey": ["VIEW"]
          },
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "Operation successful",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "nullable": true,
                  "items": {
                    "$ref": "#/components/schemas/File"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid API key provided or not logged in as admin"
          }
        }
      }
    },
    "/chunk/add": {
      "post": {
        "tags": [
          "chunk"
        ],
        "summary": "Uploads a new chunk",
        "description": "Uploads a file in chunks, in case a reverse proxy does not support upload of larger files. Parallel uploading is supported. Must call /chunk/complete after all chunks have been uploaded. WARNING: Does not support end-to-end encryption! If server is setup to utilise end-to-end encryption, file will be stored in plain-text! Requires permission UPLOAD",
        "operationId": "chunkadd",
        "security": [
          {
            "apikey": ["UPLOAD"]
          },
          {
            "session": []
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/chunking"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Operation successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/chunkUploadResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid API key provided or not logged in as admin"
          }
        }
      }
    },
    "/chunk/complete": {
      "post": {
        "tags": [
          "chunk"
        ],
        "summary": "Finalises uploaded chunks",
        "description": "Needs to be called after all chunks have been uploaded. Adds the uploaded file to Gokapi. Requires permission UPLOAD",
        "operationId": "chunkcomplete",
        "security": [
          {
            "apikey": ["UPLOAD"]
          },
          {
            "session": []
          }
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/chunkingcomplete"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Operation successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid API key provided or not logged in as admin"
          }
        }
      }
    },
    "/files/add": {
      "post": {
        "tags": [
          "files"
        ],
        "summary": "Adds a new file without chunking",
        "description": "Uploads the submitted file to Gokapi. Please note: This method does not use chunking, therefore if you are behind a reverse proxy or have a provider that limits upload filesizes, this might not work for bigger files (e.g. Cloudflare). WARNING: Does not support end-to-end encryption! If server is setup to utilise end-to-end encryption, file will be stored in plain-text! Requires permission UPLOAD",
        "operationId": "add",
        "security": [
          {
            "apikey": ["UPLOAD"]
          },
          {
            "session": []
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/body"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Operation successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid API key provided or not logged in as admin"
          }
        }
      }
    },
    "/files/duplicate": {
      "post": {
        "tags": [
          "files"
        ],
        "summary": "Duplicates an existing file",
        "description": "This API call duplicates an existing file with new parameters. Requires permission UPLOAD",
        "operationId": "duplicate",
        "security": [
          {
            "apikey": ["VIEW","UPLOAD"]
          },
          {
            "session": []
          }
        ],
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/duplicate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Operation successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/File"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid API key provided or not logged in as admin"
          }
        }
      }
    },
    "/files/modify": {
      "put": {
        "tags": [
          "files"
        ],
        "summary": "Changes parameters of an uploaded file",
        "description": "This API call changes parameters of an uploaded file.  Requires permission EDIT",
        "operationId": "modifyfile",
        "security": [
          {
            "apikey": ["API_EDIT"]
          },
          {
            "session": []
          }
        ],
            "parameters": [
      {
        "name": "id",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "ID of file to be edited"
      },
      {
        "name": "allowedDownloads",
        "in": "header",
        "required": false,
        "schema": {
          "type": "integer"
        },
        "description": "How many remaining downloads are allowed. Unlimited if 0 is passed."
      },
      {
        "name": "expiryTimestamp",
        "in": "header",
        "required": false,
        "schema": {
          "type": "integer"
        },
        "description": "Unix timestamp of the file expiration date. Unlimited if 0 is passed."
      },
      {
        "name": "password",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string"
        },
        "description": "Password for this file to be set. No password will be used if empty."
      },
      {
        "name": "originalPassword",
        "in": "header",
        "required": false,
        "schema": {
          "type": "boolean"
        },
        "description": "Set to true to use the original password. Field \"password\" will be ignored if set."
      }
    ],
        "responses": {
          "200": {
            "description": "Operation successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/File"
                }
              }
            }
          },
          "400": {
            "description": "Invalid ID supplied or incorrect data type sent"
          },
          "401": {
            "description": "Invalid API key provided or not logged in as admin"
          }
        }
      }
    },
    "/files/delete": {
      "delete": {
        "tags": [
          "files"
        ],
        "summary": "Deletes the selected file",
        "description": "This API call deletes the selected file and runs the clean-up procedure which purges all expired files from the data directory immediately. Requires permission DELETE",
        "operationId": "delete",
        "security": [
          {
            "apikey": ["DELETE"]
          },
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "header",
            "description": "The ID of the file to be deleted",
            "required": true,
            "style": "simple",
            "explode": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operation successful"
          },
          "400": {
            "description": "Invalid ID supplied"
          },
          "401": {
            "description": "Invalid API key provided or not logged in as admin"
          }
        }
      }
    },
    "/auth/create": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Creates a new API key",
        "description": "This API call returns a new API key. The new key does not have any permissions. Requires permission API_MOD",
        "operationId": "create",
        "security": [
          {
            "apikey": ["API_MANAGE"]
          },
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "friendlyName",
            "in": "header",
            "description": "The friendly name of the key",
            "required": false,
            "style": "simple",
            "explode": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operation successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NewApiKey"
                }
              }
            }
          },
          "401": {
            "description": "Invalid API key provided or not logged in as admin"
          }
        }
      }
    },
    "/auth/friendlyname": {
      "put": {
        "tags": [
          "auth"
        ],
        "summary": "Changes the name of the API key",
        "description": "This API call changes the name of the API key that is shown in the API overview. Requires permission API_MOD",
        "operationId": "friendlyname",
        "security": [
          {
            "apikey": ["API_MANAGE"]
          },
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "apiKeyToModify",
            "in": "header",
            "description": "The API key to change the name of",
            "required": true,
            "style": "simple",
            "explode": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "friendlyName",
            "in": "header",
            "description": "The new name of a API key",
            "required": true,
            "style": "simple",
            "explode": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operation successful"
          },
          "400": {
            "description": "Invalid ID supplied"
          },
          "401": {
            "description": "Invalid API key provided or not logged in as admin"
          }
        }
      }
    },
    "/auth/modify": {
      "put": {
        "tags": [
          "auth"
        ],
        "summary": "Changes the permissions of the API key",
        "description": "This API call changes the permissions for the given API key. Requires permission API_MOD",
        "operationId": "modifypermission",
        "security": [
          {
            "apikey": ["API_MANAGE"]
          },
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "apiKeyToModify",
            "in": "header",
            "description": "The API key to change the permission of",
            "required": true,
            "style": "simple",
            "explode": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "permission",
            "in": "header",
            "description": "The name of the permission",
            "required": true,
            "style": "simple",
            "explode": false,
            "schema": {
              "type": "string",
              "enum": ["PERM_VIEW", "PERM_UPLOAD", "PERM_EDIT", "PERM_DELETE", "PERM_API_MOD"]
            }
          },
          {
            "name": "permissionModifier",
            "in": "header",
            "description": "If the permission shall be granted or revoked",
            "required": true,
            "style": "simple",
            "explode": false,
            "schema": {
              "type": "string",
              "enum": ["GRANT", "REVOKE"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Operation successful"
          },
          "400": {
            "description": "Invalid ID supplied"
          },
          "401": {
            "description": "Invalid API key provided or not logged in as admin"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "File": {
        "type": "object",
        "properties": {
          "Id": {
            "type": "string",
            "description": "The internal ID of the file",
            "example": "oNleRD3pUZgaDKn"
          },
          "Name": {
            "type": "string",
            "description": "The filename. Will be 'Encrypted file' for end-to-end encrypted files",
            "example": "Test File.jpg"
          },
          "Size": {
            "type": "string",
            "description": "Filesize in a human readable format",
            "example": "395.4 kB"
          },
          "HotlinkId": {
            "type": "string",
            "description": "If file is a picture file and can be hotlinked, this is the ID for the hotlink",
            "example": "tDMs0U8MvRFwK69PfjagI7F87C13UVeQuOGDvtCG.jpg"
          },
          "ContentType": {
            "description": "The MIME type for the file",
            "type": "string",
            "example": "image/jpeg"
          },
          "ExpireAtString": {
            "type": "string",
            "description": "Time expiry in a human readable format in local time",
            "example": "2024-02-17 14:08"
          },
          "UrlDownload": {
            "type": "string",
            "description": "The public download URL for the file",
            "example": "https://gokapi.server/d?id=oNleRD3pUZgaDKn"
          },
          "UrlHotlink": {
            "type": "string",
            "description": "The public hotlink URL for the file",
            "example": "https://gokapi.server/hotlink/tDMs0U8MvRFwK69PfjagI7F87C13UVeQuOGDvtCG.jpg"
          },
          "ExpireAt": {
            "type": "integer",
            "description": "UTC timestamp of file expiry",
            "format": "int64",
            "example": "1708175321"
          },
          "SizeBytes": {
            "type": "integer",
            "format": "int64",
            "description": "Filesize in bytes",
            "example": "404843"
          },
          "DownloadsRemaining": {
            "type": "integer",
            "description": "The remaining downloads for this file",
            "format": "int64",
            "example": "4"
          },
          "DownloadCount": {
            "type": "integer",
            "description": "The amount of times the file has been downloaded",
            "format": "int64",
            "example": "1"
          },
          "UnlimitedDownloads": {
            "type": "boolean",
            "description": "True if the uploader did not limit the downloads",
            "example": "false"
          },
          "UnlimitedTime": {
            "type": "boolean",
            "description": "True if the uploader did not limit the time",
            "example": "false"
          },
          "RequiresClientSideDecryption": {
            "type": "boolean",
            "description": "True if the file has to be decrypted client-side",
            "example": "false"
          },
          "IsEncrypted": {
            "description": "True if the file is encrypted",
            "type": "boolean",
            "example": "false"
          },
          "IsPasswordProtected": {
            "type": "boolean",
            "description": "True if a password has to be entered before downloading the file",
            "example": "false"
          },
          "IsSavedOnLocalStorage": {
            "description": "True if the file does not use cloud storage",
            "type": "boolean",
            "example": "true"
          }
        },
        "description": "File is a struct used for saving information about an uploaded file",
        "x-go-package": "Gokapi/internal/models"
      },
      "chunkUploadResult": {
        "type": "object",
        "properties": {
          "Result": {
            "type": "string",
            "example": "OK"
            }
        },
        "description": "Result after uploading a chunk",
        "x-go-package": "Gokapi/internal/models"
      },
      "UploadResult": {
        "type": "object",
        "properties": {
          "Result": {
            "type": "string",
            "example": "OK"
          },
          "FileInfo": {
            "$ref": "#/components/schemas/File"
          },
          "IncludeFilename": {
            "type": "boolean",
            "description": "If true, the download URLs include the filename",
            "example": "true"
          }
        },
        "description": "UploadResult is the struct used for the result after an upload",
        "x-go-package": "Gokapi/internal/models"
      },
      "NewApiKey": {
        "type": "object",
        "properties": {
          "Result": {
            "type": "string",
            "example": "OK"
          },
          "Id": {
            "type": "string",
            "example": "ar3iecahghiethiemeeR"
          }
        },
        "description": "NewApiKey is the struct used for the result after creating a new API key",
        "x-go-package": "Gokapi/internal/models"
      },
      "body": {
        "required": [
          "file"
        ],
        "type": "object",
        "properties": {
          "file": {
            "type": "string",
            "description": "The file to be uploaded",
            "format": "binary"
          },
          "allowedDownloads": {
            "type": "integer",
            "description": "How many downloads are allowed. Last used value from web interface will be used if empty. Unlimited if 0 is passed."
          },
          "expiryDays": {
            "type": "integer",
            "description": "How many days the file will be stored. Last used value from web interface will be used if empty. Unlimited if 0 is passed."
          },
          "password": {
            "type": "string",
            "description": "Password for this file to be set. No password will be used if empty"
          }
        }
      },"duplicate": {
        "required": [
          "id"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID of file to be duplicated"
          },
          "allowedDownloads": {
            "type": "integer",
            "description": "How many downloads are allowed. Original value from web interface will be used if empty. Unlimited if 0 is passed."
          },
          "expiryDays": {
            "type": "integer",
            "description": "How many days the file will be stored. Original value from web interface will be used if empty. Unlimited if 0 is passed."
          },
          "password": {
            "type": "string",
            "description": "Password for this file to be set. No password will be used if empty."
          },
          "originalPassword": {
            "type": "boolean",
            "description": "Set to true to use original password. Field \"password\" will be ignored if set."
          },
          "filename": {
            "type": "string",
            "description": "Sets a new filename. Filename will be unchanged if empty."
          }
        }
    },"chunking": {
        "required": [
          "file","uuid","filesize","offset"
        ],
        "type": "object",
        "properties": {
          "file": {
            "type": "string",
            "description": "The file to be uploaded",
            "format": "binary"
          },
          "uuid": {
            "type": "string",
            "description": "A unique ID that has to be the same for all chunks of a single file. Needs to be at least 10 characters long."
          },
          "filesize": {
            "type": "integer",
            "description": "The total filesize of the final file in bytes"
          },
          "offset": {
            "type": "integer",
            "description": "The chunk's offset starting at the beginning of the file"
          }
        }
    },"chunkingcomplete": {
        "required": [
          "uuid","filename","filesize"
        ],
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "description": "The unique ID that was used for the uploaded chunks"
          },
          "filename": {
            "type": "string",
            "description": "The filename of the uploaded file"
          },
          "filesize": {
            "type": "integer",
            "description": "The total filesize of the uploaded file in bytes"
          },
          "contenttype": {
            "type": "string",
            "description": "The MIME content type. If empty, application/octet-stream will be used."
          },
          "allowedDownloads": {
            "type": "integer",
            "description": "How many downloads are allowed. Last used value from web interface will be used if empty. Unlimited if 0 is passed."
          },
          "expiryDays": {
            "type": "integer",
            "description": "How many days the file will be stored. Last used value from web interface will be used if empty. Unlimited if 0 is passed."
          },
          "password": {
            "type": "string",
            "description": "Password for this file to be set. No password will be used if empty"
          }
        }
    }
    },
    "securitySchemes": {
      "apikey": {
        "type": "apiKey",
        "name": "apikey",
        "in": "header"
      },
      "session": {
        "type": "apiKey",
        "name": "session_token",
        "in": "cookie"
      }
    }
  }
}
