openapi: 3.1.0
info: {}
paths:
  /v1/files:
    post:
      tags:
        - alconost.hitl.v1alpha1.FileService
      summary: CreateFile
      description: Upload a file to storage.
      operationId: FileService_CreateFile
      requestBody:
        content:
          application/json:
            schema:
              title: file
              $ref: '#/components/schemas/google.api.HttpBody'
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/alconost.hitl.v1alpha1.CreateFileResponse'
  /v1/files/{id}:
    delete:
      tags:
        - alconost.hitl.v1alpha1.FileService
      summary: DeleteFile
      description: Delete a file. Only the owner can delete.
      operationId: FileService_DeleteFile
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            title: id
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/alconost.hitl.v1alpha1.DeleteFileResponse'
  /v1alpha1/approvals:
    get:
      tags:
        - alconost.hitl.v1alpha1.ApprovalService
      summary: ListApprovals
      description: List requests, newest first. Defaults to "pending".
      operationId: ApprovalService_ListApprovals
      parameters:
        - name: statuses
          in: query
          description: Empty = "pending" only.
          schema:
            type: array
            items:
              type: string
              enum:
                - pending
                - approved
                - rejected
                - canceled
                - expired
            title: statuses
            description: Empty = "pending" only.
        - name: limit
          in: query
          description: Max rows. Unset = 100.
          schema:
            type: integer
            title: limit
            maximum: 250
            minimum: 1
            format: int32
            description: Max rows. Unset = 100.
        - name: after
          in: query
          description: 'Keyset cursor: id of the last row from the previous page.'
          schema:
            type: string
            title: after
            format: uuid
            description: 'Keyset cursor: id of the last row from the previous page.'
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/alconost.hitl.v1alpha1.Approval'
                title: approvals
    post:
      tags:
        - alconost.hitl.v1alpha1.ApprovalService
      summary: CreateApproval
      description: Create a request for a human decision.
      operationId: ApprovalService_CreateApproval
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/alconost.hitl.v1alpha1.CreateApprovalRequest'
        required: true
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                title: approval
                $ref: '#/components/schemas/alconost.hitl.v1alpha1.Approval'
  /v1alpha1/approvals/{id}:
    get:
      tags:
        - alconost.hitl.v1alpha1.ApprovalService
      summary: GetApproval
      description: Fetch one request by id; poll until status != "pending".
      operationId: ApprovalService_GetApproval
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            title: id
            format: uuid
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                title: approval
                $ref: '#/components/schemas/alconost.hitl.v1alpha1.Approval'
  /v1alpha1/approvals/{id}/cancel:
    post:
      tags:
        - alconost.hitl.v1alpha1.ApprovalService
      summary: CancelApproval
      description: Withdraw a request. No-op if already terminal.
      operationId: ApprovalService_CancelApproval
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            title: id
            format: uuid
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/alconost.hitl.v1alpha1.CancelApprovalResponse'
  /v1alpha1/approvals/{id}/resolve:
    post:
      tags:
        - alconost.hitl.v1alpha1.ApprovalService
      summary: ResolveApproval
      description: Approve or reject. Fails if already terminal.
      operationId: ApprovalService_ResolveApproval
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            title: id
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                approved:
                  type: boolean
                  title: approved
                  description: true = approve, false = reject.
                resolved_by:
                  type:
                    - string
                    - "null"
                  title: resolved_by
                  maxLength: 200
                reason:
                  type:
                    - string
                    - "null"
                  title: reason
                  maxLength: 8000
                  description: Free-form Markdown (e.g. timestamped review notes).
              title: ResolveApprovalRequest
              additionalProperties: false
        required: true
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/alconost.hitl.v1alpha1.ResolveApprovalResponse'
components:
  schemas:
    alconost.hitl.v1alpha1.Approval:
      type: object
      properties:
        id:
          type: string
          title: id
          format: uuid
          description: Server-assigned, opaque. Used for polling. UUIDv7 (creation-ordered).
        status:
          type: string
          title: status
          enum:
            - pending
            - approved
            - rejected
            - canceled
            - expired
        title:
          type: string
          title: title
          maxLength: 200
          minLength: 1
          description: One-line ask. Required. e.g. "English to Spanish translation".
        detail:
          type: string
          title: detail
          maxLength: 4000
          description: Optional longer detail for the human.
        context:
          type: object
          title: context
          maxProperties: 32
          additionalProperties:
            type: string
            title: value
            maxLength: 1024
          description: Optional key/values for display and caller correlation.
        attachments:
          type: array
          items:
            $ref: '#/components/schemas/alconost.hitl.v1alpha1.Attachment'
          title: attachments
          description: Content for the reviewer to inspect (e.g. source + translated videos).
        resolved_by:
          type:
            - string
            - "null"
          title: resolved_by
          maxLength: 200
          description: |-
            Set on resolve. resolved_by is opaque human identity (email, user id).
             reason is free-form Markdown (e.g. timestamped review notes).
        reason:
          type:
            - string
            - "null"
          title: reason
          maxLength: 8000
        created_at:
          title: created_at
          $ref: '#/components/schemas/google.protobuf.Timestamp'
        approved_at:
          title: approved_at
          description: Exactly one set on transition, matching status. "expired" via server TTL.
          $ref: '#/components/schemas/google.protobuf.Timestamp'
        rejected_at:
          title: rejected_at
          $ref: '#/components/schemas/google.protobuf.Timestamp'
        canceled_at:
          title: canceled_at
          $ref: '#/components/schemas/google.protobuf.Timestamp'
        expired_at:
          title: expired_at
          $ref: '#/components/schemas/google.protobuf.Timestamp'
      title: Approval
      additionalProperties: false
      description: One human decision.
    alconost.hitl.v1alpha1.Approval.ContextEntry:
      type: object
      properties:
        key:
          type: string
          title: key
        value:
          type: string
          title: value
      title: ContextEntry
      additionalProperties: false
    alconost.hitl.v1alpha1.Attachment:
      type: object
      properties:
        file_id:
          type: string
          title: file_id
          maxLength: 64
          minLength: 1
        label:
          type: string
          title: label
          maxLength: 200
          description: Human label, e.g. "source (en)" or "target (ja)".
      title: Attachment
      additionalProperties: false
      description: |-
        Attachment references a file uploaded via FileService. The server resolves
         its content type; the dashboard renders a player/preview accordingly.
    alconost.hitl.v1alpha1.CancelApprovalRequest:
      type: object
      properties:
        id:
          type: string
          title: id
          format: uuid
      title: CancelApprovalRequest
      additionalProperties: false
    alconost.hitl.v1alpha1.CancelApprovalResponse:
      type: object
      title: CancelApprovalResponse
      additionalProperties: false
      description: 'Empty: re-fetch with GetApproval if the canceled state is needed.'
    alconost.hitl.v1alpha1.CreateApprovalRequest:
      type: object
      properties:
        title:
          type: string
          title: title
          maxLength: 200
          minLength: 1
        detail:
          type: string
          title: detail
          maxLength: 4000
        context:
          type: object
          title: context
          maxProperties: 32
          additionalProperties:
            type: string
            title: value
            maxLength: 1024
        attachments:
          type: array
          items:
            $ref: '#/components/schemas/alconost.hitl.v1alpha1.Attachment'
          title: attachments
          maxItems: 16
      title: CreateApprovalRequest
      additionalProperties: false
    alconost.hitl.v1alpha1.CreateApprovalRequest.ContextEntry:
      type: object
      properties:
        key:
          type: string
          title: key
        value:
          type: string
          title: value
      title: ContextEntry
      additionalProperties: false
    alconost.hitl.v1alpha1.CreateApprovalResponse:
      type: object
      properties:
        approval:
          title: approval
          $ref: '#/components/schemas/alconost.hitl.v1alpha1.Approval'
      title: CreateApprovalResponse
      additionalProperties: false
    alconost.hitl.v1alpha1.CreateFileRequest:
      type: object
      properties:
        file:
          title: file
          $ref: '#/components/schemas/google.api.HttpBody'
      title: CreateFileRequest
      required:
        - file
      additionalProperties: false
    alconost.hitl.v1alpha1.CreateFileResponse:
      type: object
      properties:
        id:
          type: string
          title: id
        url:
          type: string
          title: url
          format: uri
      title: CreateFileResponse
      required:
        - id
        - url
      additionalProperties: false
    alconost.hitl.v1alpha1.DeleteFileRequest:
      type: object
      properties:
        id:
          type: string
          title: id
      title: DeleteFileRequest
      required:
        - id
      additionalProperties: false
    alconost.hitl.v1alpha1.DeleteFileResponse:
      type: object
      title: DeleteFileResponse
      additionalProperties: false
    alconost.hitl.v1alpha1.GetApprovalRequest:
      type: object
      properties:
        id:
          type: string
          title: id
          format: uuid
      title: GetApprovalRequest
      additionalProperties: false
    alconost.hitl.v1alpha1.GetApprovalResponse:
      type: object
      properties:
        approval:
          title: approval
          $ref: '#/components/schemas/alconost.hitl.v1alpha1.Approval'
      title: GetApprovalResponse
      additionalProperties: false
    alconost.hitl.v1alpha1.ListApprovalsRequest:
      type: object
      properties:
        statuses:
          type: array
          items:
            type: string
            enum:
              - pending
              - approved
              - rejected
              - canceled
              - expired
          title: statuses
          description: Empty = "pending" only.
        limit:
          type:
            - integer
            - "null"
          title: limit
          maximum: 250
          minimum: 1
          format: int32
          description: Max rows. Unset = 100.
        after:
          type:
            - string
            - "null"
          title: after
          format: uuid
          description: 'Keyset cursor: id of the last row from the previous page.'
      title: ListApprovalsRequest
      additionalProperties: false
    alconost.hitl.v1alpha1.ListApprovalsResponse:
      type: object
      properties:
        approvals:
          type: array
          items:
            $ref: '#/components/schemas/alconost.hitl.v1alpha1.Approval'
          title: approvals
      title: ListApprovalsResponse
      additionalProperties: false
    alconost.hitl.v1alpha1.ResolveApprovalRequest:
      type: object
      properties:
        id:
          type: string
          title: id
          format: uuid
        approved:
          type: boolean
          title: approved
          description: true = approve, false = reject.
        resolved_by:
          type:
            - string
            - "null"
          title: resolved_by
          maxLength: 200
        reason:
          type:
            - string
            - "null"
          title: reason
          maxLength: 8000
          description: Free-form Markdown (e.g. timestamped review notes).
      title: ResolveApprovalRequest
      additionalProperties: false
    alconost.hitl.v1alpha1.ResolveApprovalResponse:
      type: object
      title: ResolveApprovalResponse
      additionalProperties: false
      description: 'Empty: re-fetch with GetApproval if the resolved state is needed.'
    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: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message.
    google.protobuf.Timestamp:
      type: string
      examples:
        - "2023-01-15T01:30:15.01Z"
        - "2024-12-25T12:00:00Z"
      format: date-time
      description: |-
        A Timestamp represents a point in time independent of any time zone or local
         calendar, encoded as a count of seconds and fractions of seconds at
         nanosecond resolution. The count is relative to an epoch at UTC midnight on
         January 1, 1970, in the proleptic Gregorian calendar which extends the
         Gregorian calendar backwards to year one.

         All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
         second table is needed for interpretation, using a [24-hour linear
         smear](https://developers.google.com/time/smear).

         The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
         restricting to that range, we ensure that we can convert to and from [RFC
         3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.

         # Examples

         Example 1: Compute Timestamp from POSIX `time()`.

             Timestamp timestamp;
             timestamp.set_seconds(time(NULL));
             timestamp.set_nanos(0);

         Example 2: Compute Timestamp from POSIX `gettimeofday()`.

             struct timeval tv;
             gettimeofday(&tv, NULL);

             Timestamp timestamp;
             timestamp.set_seconds(tv.tv_sec);
             timestamp.set_nanos(tv.tv_usec * 1000);

         Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.

             FILETIME ft;
             GetSystemTimeAsFileTime(&ft);
             UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;

             // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
             // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
             Timestamp timestamp;
             timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
             timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));

         Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.

             long millis = System.currentTimeMillis();

             Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
                 .setNanos((int) ((millis % 1000) * 1000000)).build();

         Example 5: Compute Timestamp from Java `Instant.now()`.

             Instant now = Instant.now();

             Timestamp timestamp =
                 Timestamp.newBuilder().setSeconds(now.getEpochSecond())
                     .setNanos(now.getNano()).build();

         Example 6: Compute Timestamp from current time in Python.

             timestamp = Timestamp()
             timestamp.GetCurrentTime()

         # JSON Mapping

         In JSON format, the Timestamp type is encoded as a string in the
         [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
         format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
         where {year} is always expressed using four digits while {month}, {day},
         {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
         seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
         are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
         is required. A proto3 JSON serializer should always use UTC (as indicated by
         "Z") when printing the Timestamp type and a proto3 JSON parser should be
         able to accept both UTC and other timezones (as indicated by an offset).

         For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
         01:30 UTC on January 15, 2017.

         In JavaScript, one can convert a Date object to this format using the
         standard
         [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
         method. In Python, a standard `datetime.datetime` object can be converted
         to this format using
         [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
         the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
         the Joda Time's [`ISODateTimeFormat.dateTime()`](
         http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime()
         ) to obtain a formatter capable of generating timestamps in this format.
security: []
tags:
  - name: alconost.hitl.v1alpha1.ApprovalService
    description: |-
      Pause an automated workflow to ask a human to approve or reject.
       Create an approval, then poll until status leaves "pending".
       Terminal states: "approved", "rejected", "canceled", "expired".
  - name: alconost.hitl.v1alpha1.FileService
    description: |-
      FileService is a thin, stashy-compatible file API. Requests are forwarded to
       the stashy StorageService by the server's proxy; only upload and delete are
       exposed for now. Message shapes and field numbers match stashy so generated
       clients are wire-compatible through the proxy.
