openapi: 3.1.0
info:
  title: Stashy API
  description: API documentation for Stashy API
  version: 1.0.0
servers:
  - url: https://files.galactica.games
    description: Your Stashy instance
paths:
  /v1/files:
    get:
      summary: ListFiles
      description: |-
        List your files, newest first. To get the next page, pass the last
         file's ID as after. A page shorter than limit is the last one.
      operationId: FileService_ListFiles
      parameters:
        - name: limit
          in: query
          description: Maximum number of files to return. Absent means 50.
          schema:
            type: integer
            title: limit
            maximum: 100
            minimum: 1
            format: int32
        - name: after
          in: query
          description: ID of the last file from the previous page. Absent means the first page.
          schema:
            type: string
            title: after
            pattern: ^[A-Za-z0-9_-]{21}$
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/stashy.v1.File'
                title: files
                description: Newest first.
    post:
      summary: CreateFile
      description: |-
        Upload a new file. The request body is the file's content, and its
         Content-Type is stored with it.
      operationId: FileService_CreateFile
      parameters:
        - name: slug
          in: query
          description: Human-readable end of the file's URL (/{id}/{slug}).
          required: false
          explode: false
          schema:
            type: string
            maxLength: 128
            pattern: ^[A-Za-z0-9._~-]*$
        - name: name
          in: query
          description: Original filename, e.g. "Quarterly report.pdf".
          required: false
          explode: false
          schema:
            type: string
            maxLength: 255
        - name: visibility
          in: query
          description: Who can open the file by its URL. Defaults to internal.
          required: false
          explode: false
          schema:
            type: string
            enum:
              - private
              - internal
              - public
      requestBody:
        content:
          '*/*':
            schema:
              type: string
              format: binary
        required: false
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/stashy.v1.File'
                title: file
  /v1/files/{id}:
    get:
      summary: GetFile
      description: Get a file's metadata.
      operationId: FileService_GetFile
      parameters:
        - name: id
          in: path
          description: The id path parameter.
          required: true
          schema:
            type: string
            title: id
            pattern: ^[A-Za-z0-9_-]{21}$
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/stashy.v1.File'
                title: file
    delete:
      summary: DeleteFile
      description: Permanently delete a file and its content. Its URL stops working.
      operationId: FileService_DeleteFile
      parameters:
        - name: id
          in: path
          description: The id path parameter.
          required: true
          schema:
            type: string
            title: id
            pattern: ^[A-Za-z0-9_-]{21}$
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/stashy.v1.DeleteFileResponse'
    patch:
      summary: UpdateFile
      description: |-
        Update a file. Fields are optional: an absent field is left unchanged,
         an empty value clears it.
      operationId: FileService_UpdateFile
      parameters:
        - name: id
          in: path
          description: The id path parameter.
          required: true
          schema:
            type: string
            title: id
            pattern: ^[A-Za-z0-9_-]{21}$
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                slug:
                  type:
                    - string
                    - "null"
                  title: slug
                  maxLength: 128
                  pattern: ^[A-Za-z0-9._~-]*$
                  description: |-
                    Human-readable slug used in the file's canonical URL (/{id}/{slug}).
                     An empty string clears it.
                name:
                  type:
                    - string
                    - "null"
                  title: name
                  maxLength: 255
                  pattern: ^[^/\x00-\x1F\x7F]*$
                  description: Original filename. An empty string clears it.
                visibility:
                  type:
                    - string
                    - "null"
                  title: visibility
                  enum:
                    - private
                    - internal
                    - public
                  description: Who can open the file by its URL.
              title: UpdateFileRequest
              additionalProperties: false
        required: true
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/stashy.v1.File'
                title: file
  /v1/files/{id}/content:
    get:
      summary: GetFileContent
      description: Get a file's content. Supports Range requests.
      operationId: FileService_GetFileContent
      parameters:
        - name: id
          in: path
          description: The id path parameter.
          required: true
          schema:
            type: string
            title: id
            pattern: ^[A-Za-z0-9_-]{21}$
      responses:
        "200":
          description: ""
          content:
            '*/*':
              schema:
                type: string
                format: binary
    put:
      summary: UpdateFileContent
      description: |-
        Update a file's content, replacing it entirely. Its ID and URL stay the
         same.
      operationId: FileService_UpdateFileContent
      parameters:
        - name: id
          in: path
          description: The id path parameter.
          required: true
          schema:
            type: string
            title: id
            pattern: ^[A-Za-z0-9_-]{21}$
      requestBody:
        content:
          '*/*':
            schema:
              type: string
              format: binary
        required: false
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/stashy.v1.File'
                title: file
components:
  schemas:
    google.api.HttpBody:
      type: object
      properties:
        content_type:
          type: string
          title: content_type
          description: The HTTP Content-Type header value specifying the content type of the body.
        data:
          type: string
          title: data
          format: byte
          description: The HTTP request/response body as raw binary.
        extensions:
          type: array
          items:
            $ref: '#/components/schemas/google.protobuf.Any'
          title: extensions
          description: |-
            Application specific response metadata. Must be set in the first response
             for streaming APIs.
      title: HttpBody
      additionalProperties: false
      description: |-
        Message that represents an arbitrary HTTP body. It should only be used for
         payload formats that can't be represented as JSON, such as raw binary or
         an HTML page.


         This message can be used both in streaming and non-streaming API methods in
         the request as well as the response.

         It can be used as a top-level request field, which is convenient if one
         wants to extract parameters from either the URL or HTTP template into the
         request fields and also want access to the raw HTTP body.

         Example:

             message GetResourceRequest {
               // A unique request id.
               string request_id = 1;

               // The raw HTTP body is bound to this field.
               google.api.HttpBody http_body = 2;

             }

             service ResourceService {
               rpc GetResource(GetResourceRequest)
                 returns (google.api.HttpBody);
               rpc UpdateResource(google.api.HttpBody)
                 returns (google.protobuf.Empty);

             }

         Example with streaming methods:

             service CaldavService {
               rpc GetCalendar(stream google.api.HttpBody)
                 returns (stream google.api.HttpBody);
               rpc UpdateCalendar(stream google.api.HttpBody)
                 returns (stream google.api.HttpBody);

             }

         Use of this type only changes how the request and response bodies are
         handled, all other features will continue to work unchanged.
    google.protobuf.Any:
      type: object
      properties:
        type:
          type: string
        value:
          type: string
          format: binary
      additionalProperties: true
      description: An arbitrary message with a type URL identifying the encoded message type.
    google.protobuf.Timestamp:
      type: string
      examples:
        - "2023-01-15T01:30:15.01Z"
        - "2024-12-25T12:00:00Z"
      format: date-time
      description: A point in time in RFC 3339 format, with up to nanosecond precision. Output uses UTC (`Z`); input may use an offset from UTC.
    stashy.v1.CreateFileRequest:
      type: object
      properties:
        content:
          allOf:
            - $ref: '#/components/schemas/google.api.HttpBody'
          title: content
        slug:
          type:
            - string
            - "null"
          title: slug
          maxLength: 128
          pattern: ^[A-Za-z0-9._~-]*$
          description: |-
            Human-readable end of the file's URL (/{id}/{slug}). Over REST, pass it as
             the slug query parameter.
        name:
          type:
            - string
            - "null"
          title: name
          maxLength: 255
          pattern: ^[^/\x00-\x1F\x7F]*$
          description: |-
            Original filename, e.g. "Quarterly report.pdf". Over REST, pass it as the
             name query parameter.
        visibility:
          type:
            - string
            - "null"
          title: visibility
          enum:
            - private
            - internal
            - public
          description: |-
            Who can open the file by its URL; defaults to "internal". Over REST, pass
             it as the visibility query parameter.
      title: CreateFileRequest
      required:
        - content
      additionalProperties: false
    stashy.v1.CreateFileResponse:
      type: object
      properties:
        file:
          allOf:
            - $ref: '#/components/schemas/stashy.v1.File'
          title: file
      title: CreateFileResponse
      required:
        - file
      additionalProperties: false
    stashy.v1.DeleteFileRequest:
      type: object
      properties:
        id:
          type: string
          title: id
          pattern: ^[A-Za-z0-9_-]{21}$
      title: DeleteFileRequest
      required:
        - id
      additionalProperties: false
    stashy.v1.DeleteFileResponse:
      type: object
      title: DeleteFileResponse
      additionalProperties: false
    stashy.v1.File:
      type: object
      properties:
        id:
          type: string
          title: id
          pattern: ^[A-Za-z0-9_-]{21}$
          description: Unique file ID.
        slug:
          type: string
          title: slug
          maxLength: 128
          pattern: ^[A-Za-z0-9._~-]*$
          description: Human-readable name at the end of the URL. Empty when not set.
        url:
          type: string
          title: url
          format: uri
          description: Canonical URL of the file, including the slug when set.
        name:
          type: string
          title: name
          maxLength: 255
          pattern: ^[^/\x00-\x1F\x7F]*$
          description: Original filename, e.g. "Quarterly report.pdf". Empty when not set.
        content_type:
          type: string
          title: content_type
          description: Media type of the content, from the Content-Type of the upload.
        size:
          type: string
          title: size
          minimum: 0
          format: int64
          description: Size of the content in bytes.
        checksum:
          type: string
          title: checksum
          pattern: ^([A-Za-z0-9+/]{6}==)?$
          description: CRC32C checksum of the content.
        visibility:
          type: string
          title: visibility
          enum:
            - private
            - internal
            - public
          description: |-
            Who can open the file by its URL: "private" (only the owner), "internal"
             (any signed-in user), or "public" (anyone).
        created_at:
          allOf:
            - $ref: '#/components/schemas/google.protobuf.Timestamp'
          title: created_at
        updated_at:
          allOf:
            - $ref: '#/components/schemas/google.protobuf.Timestamp'
          title: updated_at
      title: File
      required:
        - id
        - slug
        - url
        - name
        - content_type
        - size
        - checksum
        - visibility
        - created_at
        - updated_at
      additionalProperties: false
    stashy.v1.GetFileContentRequest:
      type: object
      properties:
        id:
          type: string
          title: id
          pattern: ^[A-Za-z0-9_-]{21}$
      title: GetFileContentRequest
      required:
        - id
      additionalProperties: false
    stashy.v1.GetFileContentResponse:
      type: object
      properties:
        content:
          allOf:
            - $ref: '#/components/schemas/google.api.HttpBody'
          title: content
      title: GetFileContentResponse
      required:
        - content
      additionalProperties: false
    stashy.v1.GetFileRequest:
      type: object
      properties:
        id:
          type: string
          title: id
          pattern: ^[A-Za-z0-9_-]{21}$
      title: GetFileRequest
      required:
        - id
      additionalProperties: false
    stashy.v1.GetFileResponse:
      type: object
      properties:
        file:
          allOf:
            - $ref: '#/components/schemas/stashy.v1.File'
          title: file
      title: GetFileResponse
      required:
        - file
      additionalProperties: false
    stashy.v1.ListFilesRequest:
      type: object
      properties:
        limit:
          type:
            - integer
            - "null"
          title: limit
          maximum: 100
          minimum: 1
          format: int32
          description: Maximum number of files to return. Absent means 50.
        after:
          type:
            - string
            - "null"
          title: after
          pattern: ^[A-Za-z0-9_-]{21}$
          description: ID of the last file from the previous page. Absent means the first page.
      title: ListFilesRequest
      additionalProperties: false
    stashy.v1.ListFilesResponse:
      type: object
      properties:
        files:
          type: array
          items:
            $ref: '#/components/schemas/stashy.v1.File'
          title: files
          description: Newest first.
      title: ListFilesResponse
      additionalProperties: false
    stashy.v1.UpdateFileContentRequest:
      type: object
      properties:
        id:
          type: string
          title: id
          pattern: ^[A-Za-z0-9_-]{21}$
        content:
          allOf:
            - $ref: '#/components/schemas/google.api.HttpBody'
          title: content
      title: UpdateFileContentRequest
      required:
        - id
        - content
      additionalProperties: false
    stashy.v1.UpdateFileContentResponse:
      type: object
      properties:
        file:
          allOf:
            - $ref: '#/components/schemas/stashy.v1.File'
          title: file
      title: UpdateFileContentResponse
      required:
        - file
      additionalProperties: false
    stashy.v1.UpdateFileRequest:
      type: object
      properties:
        id:
          type: string
          title: id
          pattern: ^[A-Za-z0-9_-]{21}$
        slug:
          type:
            - string
            - "null"
          title: slug
          maxLength: 128
          pattern: ^[A-Za-z0-9._~-]*$
          description: |-
            Human-readable slug used in the file's canonical URL (/{id}/{slug}).
             An empty string clears it.
        name:
          type:
            - string
            - "null"
          title: name
          maxLength: 255
          pattern: ^[^/\x00-\x1F\x7F]*$
          description: Original filename. An empty string clears it.
        visibility:
          type:
            - string
            - "null"
          title: visibility
          enum:
            - private
            - internal
            - public
          description: Who can open the file by its URL.
      title: UpdateFileRequest
      required:
        - id
      additionalProperties: false
    stashy.v1.UpdateFileResponse:
      type: object
      properties:
        file:
          allOf:
            - $ref: '#/components/schemas/stashy.v1.File'
          title: file
      title: UpdateFileResponse
      required:
        - file
      additionalProperties: false
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: opaque
security:
  - BearerAuth: []
