aafe7d5b5f
Implement and test the batch status feature * working
5299 lines
156 KiB
YAML
5299 lines
156 KiB
YAML
---
|
|
openapi: 3.0.3
|
|
info:
|
|
title: Query Orchestration API
|
|
description: API documentation for the Query Orchestration services.
|
|
version: 0.0.1
|
|
contact:
|
|
email: piragavarapu@aarete.com
|
|
name: Aarete Inc.
|
|
url: https://aarete.com
|
|
license:
|
|
name: Aarete Inc.internal use
|
|
url: https://aarete.com
|
|
servers:
|
|
- url: https://doczy.com/v1
|
|
description: Production server
|
|
tags:
|
|
- name: ClientService
|
|
description: Operations related to clients
|
|
- name: CollectorService
|
|
description: Operations related to collectors
|
|
- name: DocumentsService
|
|
description: Operations related to documents
|
|
- name: FolderService
|
|
description: Operations related to document folders and organization
|
|
- name: LabelService
|
|
description: Operations related to document labels and workflow tracking
|
|
- name: FieldExtractionService
|
|
description: Operations related to document field extractions
|
|
- name: ExportService
|
|
description: Operations related to exports
|
|
- name: AuthService
|
|
description: Operations related to authentication
|
|
- name: AdminService
|
|
description: Operations related to user management and administration
|
|
- name: EulaService
|
|
description: Operations related to End User License Agreement management and tracking
|
|
- name: UISettingsService
|
|
description: Generic UI key-value settings (e.g. demo-dashboard:{userId}, feature-flags:global, saved-filters:{clientId})
|
|
|
|
paths:
|
|
|
|
/client:
|
|
post:
|
|
operationId: createClient
|
|
tags:
|
|
- ClientService
|
|
summary: Create a new client
|
|
description: Creates a new client with the provided details.
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: The details required to create a client
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ClientCreate"
|
|
responses:
|
|
"201":
|
|
description: Client created successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ClientIDBody"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/clients:
|
|
get:
|
|
operationId: listClients
|
|
tags:
|
|
- ClientService
|
|
summary: List all clients
|
|
description: Returns a list of all clients in the system.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: List of clients retrieved successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ClientListResponse"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/client/{id}:
|
|
parameters:
|
|
- $ref: "#/components/parameters/ClientID"
|
|
get:
|
|
operationId: getClient
|
|
tags:
|
|
- ClientService
|
|
summary: Get a client by ID
|
|
description: Retrieves a specific client by its ID.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: Client details.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DocClient"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
patch:
|
|
operationId: updateClient
|
|
tags:
|
|
- ClientService
|
|
summary: Update a client
|
|
description: Updates an existing client with new details.
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: The details to update
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ClientUpdate"
|
|
responses:
|
|
"200":
|
|
description: Client updated successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
delete:
|
|
operationId: deleteClient
|
|
tags:
|
|
- ClientService
|
|
summary: Hard-delete a client and all its data
|
|
description: >-
|
|
Permanently deletes a client and all associated data including documents,
|
|
folders, collectors, batch uploads, and sync records. Source documents in
|
|
S3 are NOT deleted but their paths are logged. This operation is
|
|
irreversible. Requires confirm=true query parameter.
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: confirm
|
|
in: query
|
|
description: Must be set to true to confirm deletion
|
|
required: true
|
|
schema:
|
|
type: boolean
|
|
- name: verbose
|
|
in: query
|
|
required: false
|
|
description: When true, returns S3 paths of orphaned source documents in the response body
|
|
schema:
|
|
type: boolean
|
|
default: false
|
|
responses:
|
|
"200":
|
|
description: Client deleted successfully (verbose mode).
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DeleteResponse"
|
|
"204":
|
|
description: Client deleted successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
# Query paths have been removed - see remove_query_plan.md
|
|
|
|
/client/{id}/status:
|
|
parameters:
|
|
- $ref: "#/components/parameters/ClientID"
|
|
get:
|
|
operationId: getStatusByClientId
|
|
tags:
|
|
- ClientService
|
|
summary: Get client sync status
|
|
description: Retrieves the sync status by its client ID.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: Client status details.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ClientStatusBody"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/client/{id}/collector:
|
|
parameters:
|
|
- $ref: "#/components/parameters/ClientID"
|
|
get:
|
|
operationId: getCollectorByClientId
|
|
tags:
|
|
- CollectorService
|
|
summary: Get a collector by client ID
|
|
description: Retrieves a specific collector by its client ID.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: Collector details.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Collector"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
patch:
|
|
operationId: setCollectorByClientId
|
|
tags:
|
|
- CollectorService
|
|
summary: Set a collector
|
|
description: Set client collector with new details.
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: The details to be set for the collector.
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/CollectorSet"
|
|
responses:
|
|
"204":
|
|
description: Collector set successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/client/{id}/folders:
|
|
parameters:
|
|
- $ref: "#/components/parameters/ClientID"
|
|
get:
|
|
operationId: listClientFolders
|
|
tags:
|
|
- FolderService
|
|
summary: List folders for a client
|
|
description: |
|
|
Returns all folders belonging to a client. The response includes each folder's
|
|
ID, path, and parent folder ID, allowing clients to reconstruct the folder hierarchy.
|
|
Root-level folders will have a null parentId.
|
|
|
|
When metrics=true is specified, each folder will include processing metrics
|
|
(document counts and label breakdown). This adds overhead so should only be
|
|
used when metrics are needed.
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: metrics
|
|
in: query
|
|
required: false
|
|
description: |
|
|
When true, include processing metrics for each folder (document counts by label).
|
|
Defaults to false for performance reasons.
|
|
schema:
|
|
type: boolean
|
|
default: false
|
|
responses:
|
|
"200":
|
|
description: List of folders for the client.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/FolderList"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/client/{id}/document:
|
|
parameters:
|
|
- $ref: "#/components/parameters/ClientID"
|
|
get:
|
|
operationId: listDocumentsByClientId
|
|
tags:
|
|
- DocumentsService
|
|
summary: List the documents for a client
|
|
description: Retrieves the list of documents by the client ID.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: Client documents list.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ListDocuments"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
post:
|
|
operationId: uploadDocument
|
|
tags:
|
|
- DocumentsService
|
|
summary: Upload a file
|
|
description: Upload a single file to the server with optional metadata
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
required: true
|
|
description: upload file body
|
|
content:
|
|
multipart/form-data:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- file
|
|
properties:
|
|
file:
|
|
type: string
|
|
format: binary
|
|
maxLength: 107374182400
|
|
description: The file to upload
|
|
filename:
|
|
type: string
|
|
pattern: ".+"
|
|
maxLength: 4096
|
|
description: Optional custom filename
|
|
example: "document.pdf"
|
|
encoding:
|
|
file:
|
|
contentType: application/pdf
|
|
style: form
|
|
explode: false
|
|
responses:
|
|
"200":
|
|
description: Document uploaded.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/client/{id}/document/batch:
|
|
parameters:
|
|
- $ref: "#/components/parameters/ClientID"
|
|
post:
|
|
operationId: uploadDocumentBatch
|
|
tags:
|
|
- DocumentsService
|
|
summary: Upload multiple PDF documents as ZIP archive
|
|
description: Upload a ZIP archive containing multiple PDF documents for async batch processing
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
required: true
|
|
description: ZIP archive containing PDF documents
|
|
content:
|
|
multipart/form-data:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- archive
|
|
properties:
|
|
archive:
|
|
type: string
|
|
format: binary
|
|
maxLength: 1073741824 # 1GB limit for ZIP files
|
|
description: The file to be uploaded as a ZIP archive
|
|
encoding:
|
|
archive:
|
|
contentType: application/zip
|
|
style: form
|
|
explode: false
|
|
responses:
|
|
"202":
|
|
description: Batch upload accepted for processing
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/BatchUploadResponse"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
get:
|
|
operationId: listDocumentBatches
|
|
tags:
|
|
- DocumentsService
|
|
summary: List batch uploads for a client
|
|
description: Retrieves a list of batch uploads for the specified client
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- in: query
|
|
name: limit
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 100
|
|
default: 20
|
|
description: Maximum number of items to return
|
|
- in: query
|
|
name: offset
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
default: 0
|
|
description: Number of items to skip
|
|
responses:
|
|
"200":
|
|
description: List of batch uploads
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/BatchUploadList"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/client/{id}/document/batch/{batch_id}:
|
|
parameters:
|
|
- $ref: "#/components/parameters/ClientID"
|
|
- $ref: "#/components/parameters/BatchID"
|
|
get:
|
|
operationId: getDocumentBatch
|
|
tags:
|
|
- DocumentsService
|
|
summary: Get batch upload status
|
|
description: Retrieves detailed status information for a specific batch upload
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: Batch upload details
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/BatchUploadDetails"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/document/{id}:
|
|
parameters:
|
|
- $ref: "#/components/parameters/DocumentID"
|
|
get:
|
|
operationId: getDocument
|
|
tags:
|
|
- DocumentsService
|
|
summary: Get document details by its id
|
|
description: |
|
|
Retrieves the details of a document by its id, including metadata such as
|
|
folder, filename, labels, and optionally the full text extraction record.
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: textRecord
|
|
in: query
|
|
required: false
|
|
description: When true, includes the full text extraction record in the response
|
|
schema:
|
|
type: boolean
|
|
default: false
|
|
responses:
|
|
"200":
|
|
description: Document details.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DocumentEnriched"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
delete:
|
|
operationId: deleteDocument
|
|
tags:
|
|
- DocumentsService
|
|
summary: Hard-delete a document
|
|
description: >-
|
|
Permanently deletes a document and all dependent data including entries,
|
|
cleans, text extractions, field extractions, labels, and results. Source
|
|
documents in S3 are NOT deleted but their paths are logged.
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: verbose
|
|
in: query
|
|
required: false
|
|
description: When true, returns S3 paths of orphaned source documents in the response body
|
|
schema:
|
|
type: boolean
|
|
default: false
|
|
responses:
|
|
"200":
|
|
description: Document deleted successfully (verbose mode).
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DeleteResponse"
|
|
"204":
|
|
description: Document deleted successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/folders:
|
|
post:
|
|
operationId: createFolder
|
|
tags:
|
|
- FolderService
|
|
summary: Create a new folder
|
|
description: Creates a new folder for organizing documents.
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: The details required to create a folder
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/FolderCreate"
|
|
responses:
|
|
"201":
|
|
description: Folder created successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Folder"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/folders/{folderId}:
|
|
parameters:
|
|
- name: folderId
|
|
in: path
|
|
required: true
|
|
description: The folder ID
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
patch:
|
|
operationId: renameFolder
|
|
tags:
|
|
- FolderService
|
|
summary: Rename a folder
|
|
description: Updates the folder path/name.
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: The new folder path
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/FolderRename"
|
|
responses:
|
|
"200":
|
|
description: Folder renamed successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Folder"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
delete:
|
|
operationId: deleteFolder
|
|
tags:
|
|
- FolderService
|
|
summary: Hard-delete a folder tree
|
|
description: >-
|
|
Permanently deletes a folder and all its child folders recursively. The
|
|
root folder (path '/') cannot be deleted. If the folder tree contains
|
|
documents, include_documents=true is required or a 409 Conflict is
|
|
returned. When include_documents=true, all documents in the tree are
|
|
also permanently deleted. Source documents in S3 are NOT deleted but
|
|
their paths are logged.
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: include_documents
|
|
in: query
|
|
required: false
|
|
description: When true, also deletes all documents in the folder tree
|
|
schema:
|
|
type: boolean
|
|
default: false
|
|
- name: verbose
|
|
in: query
|
|
required: false
|
|
description: When true, returns S3 paths of orphaned source documents in the response body
|
|
schema:
|
|
type: boolean
|
|
default: false
|
|
responses:
|
|
"200":
|
|
description: Folder tree deleted successfully (verbose mode).
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/DeleteResponse"
|
|
"204":
|
|
description: Folder tree deleted successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Conflict"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/folders/{folderId}/documents:
|
|
parameters:
|
|
- name: folderId
|
|
in: path
|
|
required: true
|
|
description: The folder ID
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
get:
|
|
operationId: getFolderDocuments
|
|
tags:
|
|
- FolderService
|
|
summary: Get documents in a folder
|
|
description: |
|
|
Retrieves all documents within a specific folder, including filename and labels.
|
|
Optionally includes the full text extraction record for each document.
|
|
Returns a lighter-weight format than GET /document/{id} (excludes client_id and computed fields).
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: textRecord
|
|
in: query
|
|
required: false
|
|
description: When true, includes the full text extraction record for each document
|
|
schema:
|
|
type: boolean
|
|
default: false
|
|
responses:
|
|
"200":
|
|
description: List of documents in folder.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
documents:
|
|
type: array
|
|
maxItems: 10000
|
|
items:
|
|
$ref: "#/components/schemas/DocumentInFolder"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/folders/{folderId}/metrics:
|
|
parameters:
|
|
- name: folderId
|
|
in: path
|
|
required: true
|
|
description: The folder ID
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
get:
|
|
operationId: getFolderMetrics
|
|
tags:
|
|
- FolderService
|
|
summary: Get folder processing metrics
|
|
description: Retrieves processing progress metrics for documents in a folder.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: Folder metrics.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/FolderMetrics"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/documents/{documentId}/labels:
|
|
parameters:
|
|
- name: documentId
|
|
in: path
|
|
required: true
|
|
description: The document ID
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
post:
|
|
operationId: applyLabel
|
|
tags:
|
|
- LabelService
|
|
summary: Apply a label to a document
|
|
description: Applies a workflow label to a document for tracking processing state.
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: The label to apply
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/LabelApplication"
|
|
responses:
|
|
"201":
|
|
description: Label applied successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/LabelRecord"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
get:
|
|
operationId: getDocumentLabels
|
|
tags:
|
|
- LabelService
|
|
summary: Get all labels for a document
|
|
description: Retrieves all labels that have been applied to a document, ordered by most recent first.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: List of labels.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
labels:
|
|
type: array
|
|
maxItems: 1000
|
|
items:
|
|
$ref: "#/components/schemas/LabelRecord"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/labels/{labelName}/documents:
|
|
parameters:
|
|
- name: labelName
|
|
in: path
|
|
required: true
|
|
description: The label name
|
|
schema:
|
|
type: string
|
|
maxLength: 100
|
|
pattern: "^[A-Za-z0-9_]+$"
|
|
- name: clientId
|
|
in: query
|
|
required: true
|
|
description: The client ID to filter documents
|
|
schema:
|
|
$ref: "#/components/schemas/ClientID"
|
|
get:
|
|
operationId: getDocumentsByLabel
|
|
tags:
|
|
- LabelService
|
|
summary: Get all documents with a specific label
|
|
description: Retrieves all documents that have been tagged with a specific label.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: List of documents with this label.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
documents:
|
|
type: array
|
|
maxItems: 10000
|
|
items:
|
|
$ref: "#/components/schemas/DocumentSummary"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/client/{id}/export:
|
|
parameters:
|
|
- $ref: "#/components/parameters/ClientID"
|
|
post:
|
|
operationId: triggerExport
|
|
tags:
|
|
- ExportService
|
|
summary: Trigger an export
|
|
description: Initiates the export process.
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: The export requirements.
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ExportTrigger"
|
|
responses:
|
|
"201":
|
|
description: Export triggered successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/IdMessage"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/export/{id}:
|
|
parameters:
|
|
- $ref: "#/components/parameters/ExportID"
|
|
get:
|
|
operationId: exportState
|
|
tags:
|
|
- ExportService
|
|
summary: Check export state.
|
|
description: Checks the current state of an export.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: Export has been completed.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ExportDetails"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/field-extractions:
|
|
post:
|
|
operationId: createFieldExtraction
|
|
tags:
|
|
- FieldExtractionService
|
|
summary: Create a new field extraction
|
|
description: Creates a new field extraction with single-value and array fields for a document.
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: The field extraction data
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/FieldExtractionRequest"
|
|
responses:
|
|
"201":
|
|
description: Field extraction created successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/FieldExtractionResponse"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
get:
|
|
operationId: getCurrentFieldExtraction
|
|
tags:
|
|
- FieldExtractionService
|
|
summary: Get current field extraction
|
|
description: Retrieves the most recent field extraction for a document.
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: documentId
|
|
in: query
|
|
required: true
|
|
description: The document ID
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
responses:
|
|
"200":
|
|
description: Current field extraction.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/FieldExtractionResponse"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/field-extractions/version:
|
|
get:
|
|
operationId: getFieldExtractionByVersion
|
|
tags:
|
|
- FieldExtractionService
|
|
summary: Get field extraction by version
|
|
description: Retrieves a specific version of field extraction for a document.
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: documentId
|
|
in: query
|
|
required: true
|
|
description: The document ID
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
- name: version
|
|
in: query
|
|
required: true
|
|
description: The version number to retrieve
|
|
schema:
|
|
type: integer
|
|
format: int64
|
|
minimum: 1
|
|
maximum: 9223372036854775807
|
|
responses:
|
|
"200":
|
|
description: Field extraction for the specified version.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/FieldExtractionResponse"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/field-extractions/history:
|
|
get:
|
|
operationId: getFieldExtractionHistory
|
|
tags:
|
|
- FieldExtractionService
|
|
summary: Get field extraction version history
|
|
description: Retrieves all versions of field extractions for a document, ordered by most recent first.
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: documentId
|
|
in: query
|
|
required: true
|
|
description: The document ID
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
responses:
|
|
"200":
|
|
description: Field extraction history.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
properties:
|
|
versions:
|
|
type: array
|
|
maxItems: 1000
|
|
items:
|
|
$ref: "#/components/schemas/FieldExtractionVersion"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/login:
|
|
get:
|
|
operationId: login
|
|
tags:
|
|
- AuthService
|
|
summary: Login to the application
|
|
description: >-
|
|
Initiates the login flow by redirecting to Cognito IDP login page.
|
|
security:
|
|
- {}
|
|
- cognitoAuth: [openid, email, profile]
|
|
responses:
|
|
"302":
|
|
description: Redirect to Cognito login page
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
format: uri
|
|
maxLength: 2048
|
|
pattern: "^https://.*"
|
|
description: URL to the Cognito login page
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/login-callback:
|
|
get:
|
|
operationId: loginCallback
|
|
tags:
|
|
- AuthService
|
|
summary: OAuth2 callback endpoint
|
|
description: >-
|
|
Handles the OAuth2 callback during the login process. Receives the
|
|
authorization code from Cognito IDP and exchanges it for tokens.
|
|
security:
|
|
- {}
|
|
parameters:
|
|
- name: code
|
|
in: query
|
|
description: Authorization code from Cognito
|
|
required: true
|
|
schema:
|
|
type: string
|
|
maxLength: 2048
|
|
pattern: "^[A-Za-z0-9\\-_]+$"
|
|
- name: state
|
|
in: query
|
|
description: State parameter for CSRF protection
|
|
required: true
|
|
schema:
|
|
type: string
|
|
maxLength: 1024
|
|
pattern: "^[A-Za-z0-9\\-_]+$"
|
|
responses:
|
|
"302":
|
|
description: Redirect to application after successful login
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
format: uri
|
|
maxLength: 2048
|
|
pattern: "^https?://.*"
|
|
description: URL to redirect after successful login
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/logout:
|
|
get:
|
|
operationId: logout
|
|
tags:
|
|
- AuthService
|
|
summary: Logout from the application
|
|
description: >-
|
|
Logs the user out by invalidating the session and redirecting to
|
|
Cognito logout endpoint.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"302":
|
|
description: Redirect to Cognito logout page or application home page
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
format: uri
|
|
maxLength: 2048
|
|
pattern: "^https?://.*"
|
|
description: URL to redirect after logout
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/ui-settings:
|
|
post:
|
|
operationId: createUISetting
|
|
tags:
|
|
- UISettingsService
|
|
summary: Create a UI setting
|
|
description: >
|
|
Creates a new UI setting (namespace, key, value).
|
|
Use namespace to scope data (e.g. demo-dashboard:{userId}, feature-flags:global).
|
|
Returns 201 with the created resource.
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: UI setting payload.
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UISettingCreate"
|
|
responses:
|
|
"201":
|
|
description: Setting created successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UISetting"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
get:
|
|
operationId: listUISettings
|
|
tags:
|
|
- UISettingsService
|
|
summary: List UI settings
|
|
description: Returns settings where isDeleted is false. Optional query param namespace filters by namespace (e.g. demo-dashboard:user123).
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: namespace
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: string
|
|
maxLength: 255
|
|
description: Filter by namespace (omit to list all).
|
|
responses:
|
|
"200":
|
|
description: List of settings.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UISettingListResponse"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/ui-settings/{id}:
|
|
parameters:
|
|
- $ref: "#/components/parameters/UISettingID"
|
|
get:
|
|
operationId: getUISetting
|
|
tags:
|
|
- UISettingsService
|
|
summary: Get a UI setting by ID
|
|
description: Returns a single setting by id. Returns 404 if not found or soft-deleted.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: Setting details.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UISetting"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
patch:
|
|
operationId: updateUISetting
|
|
tags:
|
|
- UISettingsService
|
|
summary: Update a UI setting
|
|
description: Updates the value of an existing setting. Returns 404 if not found or soft-deleted.
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: Updated UI setting value payload.
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UISettingUpdate"
|
|
responses:
|
|
"200":
|
|
description: Setting updated successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UISetting"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
delete:
|
|
operationId: deleteUISetting
|
|
tags:
|
|
- UISettingsService
|
|
summary: Soft-delete a UI setting
|
|
description: Sets isDeleted to true. Returns 204 on success, 404 if not found.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"204":
|
|
description: Setting soft-deleted.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/identity:
|
|
get:
|
|
operationId: getIdentity
|
|
tags:
|
|
- AuthService
|
|
summary: Get current user identity and roles
|
|
description: >-
|
|
Returns the authenticated user's assigned roles from Permit.io,
|
|
including the permissions granted by each role.
|
|
Any authenticated user can call this endpoint to discover their own roles.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: User roles and permissions retrieved successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/IdentityResponse"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"502":
|
|
description: Failed to retrieve roles from Permit.io
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorMessage"
|
|
|
|
/home:
|
|
get:
|
|
operationId: getHomePage
|
|
tags:
|
|
- AuthService
|
|
summary: Get the home page menu
|
|
description: >-
|
|
Returns the HTML menu page for authenticated users.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: Home page HTML
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
text/html:
|
|
schema:
|
|
type: string
|
|
description: HTML content for the home page menu
|
|
maxLength: 1048576
|
|
pattern: "^.*$"
|
|
format: html
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/admin/users:
|
|
post:
|
|
operationId: createAdminUser
|
|
tags:
|
|
- AdminService
|
|
summary: Create a new user
|
|
description: >-
|
|
Creates a new user in both AWS Cognito and Permit.io systems with optional role assignments.
|
|
Idempotent - returns 200 OK if user already exists with identical attributes.
|
|
|
|
|
|
**Creation Flow:**
|
|
|
|
1. User is created in AWS Cognito (primary authentication system)
|
|
|
|
2. If Cognito creation fails, operation fails with HTTP 502 (no user created)
|
|
|
|
3. User is created in Permit.io (authorization/role system)
|
|
|
|
4. If Permit.io creation fails, user still exists in Cognito but permit_synced=false
|
|
|
|
5. Roles are assigned in Permit.io (best-effort, continues on failures)
|
|
|
|
|
|
**Role Assignment Behavior:**
|
|
|
|
- Roles must exist in your Permit.io environment (e.g., super_admin, user_admin, auditor, client_user)
|
|
|
|
- Invalid/non-existent roles fail silently and are logged server-side
|
|
|
|
- Only successfully assigned roles appear in the roles_assigned response field
|
|
|
|
- The roles_assigned array may be a subset of the requested roles array
|
|
|
|
- If all roles fail, roles_assigned will be null or empty (user has no permissions)
|
|
|
|
|
|
**Partial Success Scenarios:**
|
|
|
|
- Returns HTTP 201 even if Permit.io creation or some role assignments fail
|
|
|
|
- Check permit_synced field: false indicates user was not created in Permit.io
|
|
|
|
- Compare roles_assigned vs requested roles to detect role assignment failures
|
|
|
|
- User can authenticate (Cognito) but may lack authorization (Permit.io) if sync fails
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: The user details required to create a user
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AdminUserCreate"
|
|
responses:
|
|
"201":
|
|
description: User created successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AdminUserCreateResponse"
|
|
"200":
|
|
description: User already exists with matching attributes (idempotent).
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AdminUserCreateResponse"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"409":
|
|
$ref: "#/components/responses/Conflict"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
"502":
|
|
$ref: "#/components/responses/BadGateway"
|
|
get:
|
|
operationId: listAdminUsers
|
|
tags:
|
|
- AdminService
|
|
summary: List users
|
|
description: >-
|
|
Lists users from AWS Cognito with pagination, filtering, and sorting support.
|
|
Note: The roles field is not populated in this response. To retrieve roles for
|
|
a specific user, call GET /admin/users/{email} which returns the full user
|
|
details including Permit.io roles.
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: page
|
|
in: query
|
|
description: Page number for pagination
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
default: 1
|
|
maximum: 10000
|
|
- name: page_size
|
|
in: query
|
|
description: Number of results per page
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 100
|
|
default: 50
|
|
- name: search
|
|
in: query
|
|
description: Search term for email/name filtering
|
|
schema:
|
|
type: string
|
|
maxLength: 256
|
|
pattern: "^.+$"
|
|
- name: status
|
|
in: query
|
|
description: Filter by user status
|
|
schema:
|
|
type: string
|
|
enum: [enabled, disabled, all]
|
|
default: all
|
|
- name: sort_by
|
|
in: query
|
|
description: Field to sort by
|
|
schema:
|
|
type: string
|
|
enum: [email, created_at, last_name]
|
|
default: email
|
|
- name: sort_order
|
|
in: query
|
|
description: Sort direction
|
|
schema:
|
|
type: string
|
|
enum: [asc, desc]
|
|
default: asc
|
|
responses:
|
|
"200":
|
|
description: List of users.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AdminUserList"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/admin/users/{email}:
|
|
parameters:
|
|
- $ref: "#/components/parameters/UserEmail"
|
|
get:
|
|
operationId: getAdminUser
|
|
tags:
|
|
- AdminService
|
|
summary: Get user by email
|
|
description: >-
|
|
Retrieves user details from both AWS Cognito and Permit.io by email address.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: User details.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AdminUserDetails"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
head:
|
|
operationId: checkAdminUserExists
|
|
tags:
|
|
- AdminService
|
|
summary: Check if user exists
|
|
description: >-
|
|
Checks if a user exists in Cognito and/or Permit.io without returning full details.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: User exists.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
X-User-Exists-Cognito:
|
|
schema:
|
|
type: boolean
|
|
description: Whether user exists in Cognito
|
|
X-User-Exists-PermitIO:
|
|
schema:
|
|
type: boolean
|
|
description: Whether user exists in Permit.io
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
description: User does not exist in either system
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
patch:
|
|
operationId: updateAdminUser
|
|
tags:
|
|
- AdminService
|
|
summary: Update user attributes and roles
|
|
description: >-
|
|
Updates user attributes (first_name, last_name) in Cognito and manages role assignments in Permit.io.
|
|
Email address cannot be changed (use email path parameter to identify user).
|
|
|
|
|
|
**Attribute Updates:**
|
|
|
|
- first_name and last_name are updated in AWS Cognito
|
|
|
|
- Omit fields you don't want to change (e.g., send only roles to change roles)
|
|
|
|
|
|
**Role Management (REPLACE Strategy):**
|
|
|
|
- Providing a roles array REPLACES all existing roles (not additive)
|
|
|
|
- To add a role: include ALL current roles PLUS the new role
|
|
|
|
- To remove a role: include only the roles you want to keep
|
|
|
|
- To remove all roles: send an empty array []
|
|
|
|
- Omitting the roles field leaves role assignments unchanged
|
|
|
|
|
|
**Role Assignment Behavior:**
|
|
|
|
- Roles must exist in your Permit.io environment
|
|
|
|
- Invalid/non-existent roles fail silently and are logged server-side
|
|
|
|
- Response.roles field shows the final state after successful assignments
|
|
|
|
- Compare response.roles vs requested roles to detect failures
|
|
|
|
|
|
**Example - Add a Role:**
|
|
|
|
Current roles: ["client_user"]
|
|
|
|
To add "auditor": send roles: ["client_user", "auditor"]
|
|
|
|
Result: ["client_user", "auditor"]
|
|
|
|
|
|
**Example - Replace All Roles:**
|
|
|
|
Current roles: ["auditor", "client_user"]
|
|
|
|
To change to just "super_admin": send roles: ["super_admin"]
|
|
|
|
Result: ["super_admin"] (auditor and client_user removed)
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: The user attributes to update
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AdminUserUpdate"
|
|
responses:
|
|
"200":
|
|
description: User updated successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AdminUserDetails"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
delete:
|
|
operationId: deleteAdminUser
|
|
tags:
|
|
- AdminService
|
|
summary: Delete user permanently
|
|
description: >-
|
|
Permanently deletes a user from both AWS Cognito and Permit.io.
|
|
This operation is irreversible. Requires confirm=true query parameter.
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: confirm
|
|
in: query
|
|
description: Must be set to true to confirm deletion
|
|
required: true
|
|
schema:
|
|
type: boolean
|
|
responses:
|
|
"200":
|
|
description: User deleted successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AdminUserDeleteResponse"
|
|
"207":
|
|
description: User partially deleted (multi-status).
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AdminUserDeleteResponse"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/admin/users/{email}/disable:
|
|
parameters:
|
|
- $ref: "#/components/parameters/UserEmail"
|
|
post:
|
|
operationId: disableAdminUser
|
|
tags:
|
|
- AdminService
|
|
summary: Disable user
|
|
description: >-
|
|
Disables a user in AWS Cognito, preventing authentication.
|
|
User data and roles are preserved. Idempotent.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: User disabled successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AdminUserActionResponse"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/admin/users/{email}/enable:
|
|
parameters:
|
|
- $ref: "#/components/parameters/UserEmail"
|
|
post:
|
|
operationId: enableAdminUser
|
|
tags:
|
|
- AdminService
|
|
summary: Enable user
|
|
description: >-
|
|
Re-enables a previously disabled user in AWS Cognito.
|
|
Restores authentication capability. Idempotent.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: User enabled successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AdminUserActionResponse"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
# EULA Public Endpoints
|
|
/eula:
|
|
get:
|
|
operationId: getCurrentEula
|
|
tags:
|
|
- EulaService
|
|
summary: Get current EULA version
|
|
description: Returns the current active End User License Agreement version. This endpoint is public and does not require authentication.
|
|
security: []
|
|
responses:
|
|
"200":
|
|
description: Current EULA version retrieved successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EulaPublicResponse"
|
|
example:
|
|
id: "019580df-ef65-7676-8de9-94435a93337a"
|
|
version: "1.0"
|
|
title: "Terms of Service v1.0"
|
|
content: "# Terms of Service\n\n## Section 1: Acceptance of Terms\n\nBy using this service, you agree to these terms..."
|
|
effectiveDate: "2026-01-01T00:00:00Z"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/eula/status:
|
|
get:
|
|
operationId: getEulaStatus
|
|
tags:
|
|
- EulaService
|
|
summary: Check user's EULA agreement status
|
|
description: |
|
|
Returns the current user's agreement status for the current EULA version.
|
|
Designed for the frontend to quickly determine if the user needs to be prompted to agree.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: EULA status retrieved successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EulaStatusResponse"
|
|
examples:
|
|
agreed:
|
|
summary: User has agreed to current EULA
|
|
value:
|
|
hasAgreed: true
|
|
currentVersion: "1.0"
|
|
currentVersionId: "019580df-ef65-7676-8de9-94435a93337a"
|
|
agreedAt: "2026-01-15T10:30:00Z"
|
|
agreedVersion: "1.0"
|
|
notAgreed:
|
|
summary: User has not agreed to current EULA
|
|
value:
|
|
hasAgreed: false
|
|
currentVersion: "2.0"
|
|
currentVersionId: "019580df-ef65-7676-8de9-94435a93337b"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/eula/agree:
|
|
post:
|
|
operationId: agreeToEula
|
|
tags:
|
|
- EulaService
|
|
summary: Record user agreement to current EULA
|
|
description: |
|
|
Records the user's agreement to the current EULA version.
|
|
Returns 201 for first agreement, 200 if user already agreed (idempotent).
|
|
The IP address is automatically captured from the request.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"201":
|
|
description: Agreement recorded successfully (first agreement).
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EulaAgreementResponse"
|
|
example:
|
|
id: "019580df-ef65-7676-8de9-94435a93337c"
|
|
eulaVersionId: "019580df-ef65-7676-8de9-94435a93337a"
|
|
eulaVersion: "1.0"
|
|
agreedAt: "2026-01-22T14:30:00Z"
|
|
"200":
|
|
description: User already agreed to current version (returns existing agreement).
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EulaAgreementResponse"
|
|
example:
|
|
id: "019580df-ef65-7676-8de9-94435a93337c"
|
|
eulaVersionId: "019580df-ef65-7676-8de9-94435a93337a"
|
|
eulaVersion: "1.0"
|
|
agreedAt: "2026-01-15T10:30:00Z"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
# EULA Admin Endpoints
|
|
/admin/eula:
|
|
get:
|
|
operationId: listEulaVersions
|
|
tags:
|
|
- EulaService
|
|
summary: List all EULA versions
|
|
description: Returns a paginated list of all EULA versions.
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: page
|
|
in: query
|
|
description: Page number for pagination
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 10000
|
|
default: 1
|
|
- name: page_size
|
|
in: query
|
|
description: Number of items per page
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 100
|
|
default: 20
|
|
responses:
|
|
"200":
|
|
description: List of EULA versions retrieved successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EulaVersionList"
|
|
example:
|
|
versions:
|
|
- id: "019580df-ef65-7676-8de9-94435a93337a"
|
|
version: "1.0"
|
|
title: "Terms of Service v1.0"
|
|
content: "# Terms of Service\n\n## Section 1\n\nBy using this service..."
|
|
effectiveDate: "2026-01-01T00:00:00Z"
|
|
createdAt: "2025-12-15T10:30:00Z"
|
|
createdBy: "admin@example.com"
|
|
isCurrent: true
|
|
activatedAt: "2026-01-01T00:00:00Z"
|
|
activatedBy: "admin@example.com"
|
|
- id: "019580df-ef65-7676-8de9-94435a93337b"
|
|
version: "0.9-beta"
|
|
title: "Terms of Service (Beta)"
|
|
content: "# Terms of Service (Beta)\n\n## Section 1\n\nThis is a beta version..."
|
|
effectiveDate: "2025-11-01T00:00:00Z"
|
|
createdAt: "2025-10-15T10:30:00Z"
|
|
createdBy: "admin@example.com"
|
|
isCurrent: false
|
|
total: 2
|
|
page: 1
|
|
page_size: 20
|
|
has_more: false
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
post:
|
|
operationId: createEulaVersion
|
|
tags:
|
|
- EulaService
|
|
summary: Create a new EULA version
|
|
description: Creates a new EULA version. The content should be in Markdown format.
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: EULA version details
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EulaVersionCreate"
|
|
example:
|
|
version: "2.0"
|
|
title: "Terms of Service v2.0"
|
|
content: "# Terms of Service v2.0\n\n## Section 1\n\nBy using this service..."
|
|
effectiveDate: "2026-02-01T00:00:00Z"
|
|
responses:
|
|
"201":
|
|
description: EULA version created successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EulaVersion"
|
|
example:
|
|
id: "019580df-ef65-7676-8de9-94435a93337d"
|
|
version: "2.0"
|
|
title: "Terms of Service v2.0"
|
|
content: "# Terms of Service v2.0\n\n## Section 1\n\nBy using this service..."
|
|
effectiveDate: "2026-02-01T00:00:00Z"
|
|
createdAt: "2026-01-22T14:30:00Z"
|
|
createdBy: "admin@example.com"
|
|
isCurrent: false
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"409":
|
|
$ref: "#/components/responses/Conflict"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/admin/eula/{version_id}:
|
|
parameters:
|
|
- $ref: "#/components/parameters/EulaVersionID"
|
|
get:
|
|
operationId: getEulaVersion
|
|
tags:
|
|
- EulaService
|
|
summary: Get a specific EULA version
|
|
description: Retrieves a specific EULA version by its ID.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: EULA version retrieved successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EulaVersion"
|
|
example:
|
|
id: "019580df-ef65-7676-8de9-94435a93337a"
|
|
version: "1.0"
|
|
title: "Terms of Service v1.0"
|
|
content: "# Terms of Service\n\n## Section 1: Acceptance of Terms\n\nBy using this service, you agree to these terms..."
|
|
effectiveDate: "2026-01-01T00:00:00Z"
|
|
createdAt: "2025-12-15T10:30:00Z"
|
|
createdBy: "admin@example.com"
|
|
isCurrent: true
|
|
activatedAt: "2026-01-01T00:00:00Z"
|
|
activatedBy: "admin@example.com"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
patch:
|
|
operationId: updateEulaVersion
|
|
tags:
|
|
- EulaService
|
|
summary: Update EULA version metadata
|
|
description: Updates only the metadata (title and effective date) of an EULA version. Content cannot be modified.
|
|
security:
|
|
- jwtAuth: []
|
|
requestBody:
|
|
description: Fields to update
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EulaVersionUpdate"
|
|
example:
|
|
title: "Terms of Service v1.0 (Revised)"
|
|
effectiveDate: "2026-01-15T00:00:00Z"
|
|
responses:
|
|
"200":
|
|
description: EULA version updated successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EulaVersion"
|
|
example:
|
|
id: "019580df-ef65-7676-8de9-94435a93337a"
|
|
version: "1.0"
|
|
title: "Terms of Service v1.0 (Revised)"
|
|
content: "# Terms of Service\n\n## Section 1: Acceptance of Terms\n\nBy using this service, you agree to these terms..."
|
|
effectiveDate: "2026-01-15T00:00:00Z"
|
|
createdAt: "2025-12-15T10:30:00Z"
|
|
createdBy: "admin@example.com"
|
|
isCurrent: true
|
|
activatedAt: "2026-01-01T00:00:00Z"
|
|
activatedBy: "admin@example.com"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/admin/eula/{version_id}/activate:
|
|
parameters:
|
|
- $ref: "#/components/parameters/EulaVersionID"
|
|
post:
|
|
operationId: activateEulaVersion
|
|
tags:
|
|
- EulaService
|
|
summary: Activate an EULA version
|
|
description: |
|
|
Sets this version as the current active EULA. Uses a database transaction to atomically
|
|
clear the previous current flag and set the new one. Returns 409 if another admin
|
|
activated a different version concurrently.
|
|
security:
|
|
- jwtAuth: []
|
|
responses:
|
|
"200":
|
|
description: EULA version activated successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EulaVersion"
|
|
example:
|
|
id: "019580df-ef65-7676-8de9-94435a93337d"
|
|
version: "2.0"
|
|
title: "Terms of Service v2.0"
|
|
content: "# Terms of Service v2.0\n\n## Section 1: Acceptance of Terms\n\nBy accessing or using our services..."
|
|
effectiveDate: "2026-02-01T00:00:00Z"
|
|
createdAt: "2026-01-22T14:30:00Z"
|
|
createdBy: "admin@example.com"
|
|
isCurrent: true
|
|
activatedAt: "2026-01-22T15:00:00Z"
|
|
activatedBy: "admin@example.com"
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Conflict"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/admin/eula/agreements:
|
|
get:
|
|
operationId: listEulaAgreements
|
|
tags:
|
|
- EulaService
|
|
summary: List EULA agreements
|
|
description: |
|
|
Returns a paginated list of user agreements. Use version_id to filter by
|
|
a specific EULA version. Use user_id to view a specific user's complete
|
|
EULA agreement history.
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: page
|
|
in: query
|
|
description: Page number for pagination
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 10000
|
|
default: 1
|
|
- name: page_size
|
|
in: query
|
|
description: Number of items per page
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 100
|
|
default: 20
|
|
- name: version_id
|
|
in: query
|
|
description: Filter by specific EULA version ID
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
- name: user_id
|
|
in: query
|
|
description: Filter by Cognito subject ID to see all EULAs a specific user agreed to
|
|
schema:
|
|
type: string
|
|
maxLength: 256
|
|
responses:
|
|
"200":
|
|
description: List of agreements retrieved successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EulaAgreementList"
|
|
example:
|
|
agreements:
|
|
- id: "019580df-ef65-7676-8de9-94435a93337c"
|
|
cognitoSubjectId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
userEmail: "user1@example.com"
|
|
eulaVersionId: "019580df-ef65-7676-8de9-94435a93337a"
|
|
eulaVersion: "1.0"
|
|
eulaVersionTitle: "Terms of Service v1.0"
|
|
agreedAt: "2026-01-15T10:30:00Z"
|
|
agreedFromIp: "192.168.1.100"
|
|
- id: "019580df-ef65-7676-8de9-94435a93337e"
|
|
cognitoSubjectId: "b2c3d4e5-f6a7-8901-bcde-f12345678901"
|
|
userEmail: "user2@example.com"
|
|
eulaVersionId: "019580df-ef65-7676-8de9-94435a93337a"
|
|
eulaVersion: "1.0"
|
|
eulaVersionTitle: "Terms of Service v1.0"
|
|
agreedAt: "2026-01-16T09:15:00Z"
|
|
agreedFromIp: "10.0.0.50"
|
|
total: 150
|
|
page: 1
|
|
page_size: 20
|
|
has_more: true
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
/admin/eula/compliance:
|
|
get:
|
|
operationId: getEulaCompliance
|
|
tags:
|
|
- EulaService
|
|
summary: Get EULA compliance report
|
|
description: |
|
|
Returns a comprehensive compliance report showing which users have and have not
|
|
agreed to a specific EULA version. Defaults to the current active version if
|
|
no version_id is provided. User data is fetched from Cognito for accuracy.
|
|
security:
|
|
- jwtAuth: []
|
|
parameters:
|
|
- name: page
|
|
in: query
|
|
description: Page number for pagination
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 10000
|
|
default: 1
|
|
- name: page_size
|
|
in: query
|
|
description: Number of items per page
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 100
|
|
default: 50
|
|
- name: version_id
|
|
in: query
|
|
description: Specific EULA version to report on. If omitted, uses current active version.
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
- name: agreed
|
|
in: query
|
|
description: Filter by agreement status. True for agreed only, false for not-agreed only.
|
|
schema:
|
|
type: boolean
|
|
responses:
|
|
"200":
|
|
description: Compliance report generated successfully.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EulaComplianceReport"
|
|
example:
|
|
eulaVersion:
|
|
id: "019580df-ef65-7676-8de9-94435a93337a"
|
|
version: "1.0"
|
|
title: "Terms of Service v1.0"
|
|
effectiveDate: "2026-01-01T00:00:00Z"
|
|
isCurrent: true
|
|
summary:
|
|
totalUsers: 150
|
|
agreedCount: 120
|
|
notAgreedCount: 30
|
|
compliancePercentage: 80.0
|
|
users:
|
|
- cognitoSubjectId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
email: "user1@example.com"
|
|
currentEmail: "user1@example.com"
|
|
agreed: true
|
|
agreedAt: "2026-01-15T10:30:00Z"
|
|
agreedFromIp: "192.168.1.100"
|
|
- cognitoSubjectId: "b2c3d4e5-f6a7-8901-bcde-f12345678901"
|
|
currentEmail: "user2@example.com"
|
|
agreed: false
|
|
- cognitoSubjectId: "c3d4e5f6-a7b8-9012-cdef-123456789012"
|
|
email: "user3-old@example.com"
|
|
currentEmail: "user3-new@example.com"
|
|
agreed: true
|
|
agreedAt: "2026-01-16T14:45:00Z"
|
|
agreedFromIp: "10.0.0.25"
|
|
pagination:
|
|
page: 1
|
|
pageSize: 50
|
|
totalPages: 3
|
|
totalItems: 150
|
|
"400":
|
|
$ref: "#/components/responses/InvalidRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"429":
|
|
$ref: "#/components/responses/TooManyRequests"
|
|
"500":
|
|
$ref: "#/components/responses/InternalError"
|
|
|
|
components:
|
|
parameters:
|
|
ClientID:
|
|
in: path
|
|
name: id
|
|
required: true
|
|
schema:
|
|
$ref: "#/components/schemas/ClientID"
|
|
description: The client ID.
|
|
|
|
ExportID:
|
|
in: path
|
|
name: id
|
|
required: true
|
|
schema:
|
|
$ref: "#/components/schemas/ExportID"
|
|
description: The export ID.
|
|
|
|
# QueryID parameter has been removed - see remove_query_plan.md
|
|
|
|
DocumentID:
|
|
in: path
|
|
name: id
|
|
required: true
|
|
schema:
|
|
$ref: "#/components/schemas/DocumentID"
|
|
description: The document ID.
|
|
|
|
BatchID:
|
|
in: path
|
|
name: batch_id
|
|
required: true
|
|
schema:
|
|
$ref: "#/components/schemas/BatchID"
|
|
description: The batch upload ID.
|
|
|
|
UserEmail:
|
|
in: path
|
|
name: email
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: email
|
|
maxLength: 320
|
|
description: URL-encoded user email address.
|
|
|
|
EulaVersionID:
|
|
in: path
|
|
name: version_id
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
description: The EULA version ID.
|
|
|
|
UISettingID:
|
|
in: path
|
|
name: id
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
description: The UI setting ID.
|
|
|
|
headers:
|
|
RateLimit:
|
|
schema:
|
|
type: string
|
|
pattern: "^[0-9]+;window=[0-9]+$"
|
|
maxLength: 32
|
|
example: 100;window=60
|
|
description: Rate limit information in format "limit;window=time-window"
|
|
example: "100;window=10"
|
|
|
|
securitySchemes:
|
|
jwtAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
description: >-
|
|
JWT token obtained after Cognito authentication. Implements RFC8725 JWT
|
|
best practices for security.
|
|
cognitoAuth:
|
|
type: oauth2
|
|
description: >-
|
|
Authentication using Amazon Cognito IDP. Implements RFC8725 JWT best
|
|
practices for security.
|
|
flows:
|
|
authorizationCode:
|
|
authorizationUrl: >-
|
|
https://doczy.auth.us-east-1.amazoncognito.com/oauth2/authorize
|
|
tokenUrl: >-
|
|
https://doczy.auth.us-east-1.amazoncognito.com/oauth2/token
|
|
scopes:
|
|
openid: Get OIDC token
|
|
email: Access to user's email
|
|
profile: Access to user's profile
|
|
|
|
responses:
|
|
InvalidRequest:
|
|
description: Invalid request body.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorMessage"
|
|
|
|
InternalError:
|
|
description: Internal server error.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorMessage"
|
|
|
|
TooManyRequests:
|
|
description: Response upon too many requests.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
Retry-After:
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 86400
|
|
description: Number of seconds before trying again.
|
|
example: 120
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorMessage"
|
|
|
|
Unauthorized:
|
|
description: Response when unauthorized.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorMessage"
|
|
|
|
NotFound:
|
|
description: Resource not found.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorMessage"
|
|
|
|
Forbidden:
|
|
description: Insufficient permissions to perform this action.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorMessage"
|
|
|
|
Conflict:
|
|
description: Resource already exists or state conflict.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorMessage"
|
|
|
|
BadGateway:
|
|
description: External service error.
|
|
headers:
|
|
RateLimit:
|
|
$ref: "#/components/headers/RateLimit"
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorMessage"
|
|
|
|
schemas:
|
|
# Query API schemas
|
|
ClientID:
|
|
type: string
|
|
description: The client external id
|
|
example: AAA
|
|
maxLength: 36
|
|
pattern: "^.+$"
|
|
|
|
DocumentID:
|
|
type: string
|
|
format: uuid
|
|
description: The document id.
|
|
example: 019580df-b3f8-7348-9ab1-1e55b3f18ed7
|
|
maxLength: 36
|
|
|
|
ExportID:
|
|
type: string
|
|
format: uuid
|
|
description: The export id.
|
|
example: 019580de-4d51-713c-98ee-464e83811f13
|
|
maxLength: 36
|
|
|
|
BatchID:
|
|
type: string
|
|
format: uuid
|
|
description: The batch upload id.
|
|
example: 019580df-ef65-7676-8de9-94435a93337a
|
|
maxLength: 36
|
|
|
|
BatchStatus:
|
|
type: string
|
|
enum:
|
|
- processing
|
|
- completed
|
|
- failed
|
|
- cancelled
|
|
description: The status of a batch upload
|
|
|
|
BatchUploadResponse:
|
|
type: object
|
|
description: Response returned when a batch upload is accepted for processing
|
|
required:
|
|
- batch_id
|
|
- status
|
|
- status_url
|
|
properties:
|
|
batch_id:
|
|
$ref: "#/components/schemas/BatchID"
|
|
status:
|
|
$ref: "#/components/schemas/BatchStatus"
|
|
status_url:
|
|
type: string
|
|
format: uri-reference
|
|
maxLength: 512
|
|
description: URL to check batch status
|
|
example: "/client/AAA/document/batch/019580df-ef65-7676-8de9-94435a93337a"
|
|
|
|
BatchUploadSummary:
|
|
type: object
|
|
description: Summary information about a batch upload
|
|
required:
|
|
- batch_id
|
|
- client_id
|
|
- original_filename
|
|
- status
|
|
- total_documents
|
|
- processed_documents
|
|
- failed_documents
|
|
- invalid_type_documents
|
|
- progress_percent
|
|
- created_at
|
|
properties:
|
|
batch_id:
|
|
$ref: "#/components/schemas/BatchID"
|
|
client_id:
|
|
$ref: "#/components/schemas/ClientID"
|
|
original_filename:
|
|
type: string
|
|
maxLength: 4096
|
|
pattern: "^.+$"
|
|
description: Original filename of the uploaded ZIP archive
|
|
example: "documents.zip"
|
|
status:
|
|
$ref: "#/components/schemas/BatchStatus"
|
|
total_documents:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
description: Total number of documents in the batch
|
|
example: 100
|
|
processed_documents:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
description: Number of documents processed so far
|
|
example: 42
|
|
failed_documents:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
description: Number of documents that failed processing
|
|
example: 2
|
|
invalid_type_documents:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
description: Number of non-PDF files found in archive
|
|
example: 1
|
|
progress_percent:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 100
|
|
description: Processing progress percentage
|
|
example: 42
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: When the batch upload was created
|
|
completed_at:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
nullable: true
|
|
description: When the batch upload completed processing
|
|
|
|
BatchDocumentOutcome:
|
|
type: object
|
|
description: Per-file outcome from batch extraction and pipeline processing
|
|
required: [filename, outcome]
|
|
properties:
|
|
filename:
|
|
type: string
|
|
maxLength: 4096
|
|
description: Original filename from the ZIP archive
|
|
outcome:
|
|
type: string
|
|
enum:
|
|
[
|
|
submitted,
|
|
duplicate,
|
|
failed_open,
|
|
failed_read,
|
|
failed_s3_upload,
|
|
failed_upload,
|
|
invalid_type,
|
|
init_complete,
|
|
init_duplicate,
|
|
sync_complete,
|
|
sync_skipped,
|
|
clean_passed,
|
|
clean_failed,
|
|
]
|
|
description: Current processing status
|
|
error_detail:
|
|
type: string
|
|
maxLength: 2048
|
|
nullable: true
|
|
description: Human-readable error message for failure outcomes
|
|
document_id:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
nullable: true
|
|
description: Assigned document ID (null for files that never became documents)
|
|
clean_fail_reason:
|
|
type: string
|
|
maxLength: 2048
|
|
nullable: true
|
|
description: >
|
|
Specific clean validation failure reason when outcome is clean_failed.
|
|
Null otherwise.
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: When the file was first extracted from the ZIP
|
|
updated_at:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: When the outcome was last updated by a pipeline stage
|
|
|
|
BatchUploadDetails:
|
|
description: Detailed information about a batch upload including failed filenames and per-file outcomes
|
|
allOf:
|
|
- $ref: "#/components/schemas/BatchUploadSummary"
|
|
- type: object
|
|
properties:
|
|
failed_filenames:
|
|
type: array
|
|
maxItems: 10000
|
|
items:
|
|
type: string
|
|
maxLength: 4096
|
|
pattern: "^.+$"
|
|
description: List of filenames that failed processing
|
|
example: ["doc3.pdf", "doc17.pdf"]
|
|
document_outcomes:
|
|
type: array
|
|
maxItems: 10000
|
|
items:
|
|
$ref: "#/components/schemas/BatchDocumentOutcome"
|
|
description: Per-file outcome tracking for all files in the batch
|
|
|
|
BatchUploadList:
|
|
type: object
|
|
description: List of batch uploads for a client
|
|
required:
|
|
- batches
|
|
- total_count
|
|
properties:
|
|
batches:
|
|
type: array
|
|
maxItems: 100
|
|
items:
|
|
$ref: "#/components/schemas/BatchUploadSummary"
|
|
total_count:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
description: Total number of batches for this client
|
|
example: 25
|
|
|
|
ClientName:
|
|
type: string
|
|
description: The client name
|
|
example: AArete
|
|
maxLength: 256
|
|
pattern: "^.+$"
|
|
|
|
ClientCanSync:
|
|
type: boolean
|
|
description: If the client is allowing active syncs
|
|
|
|
DocClient:
|
|
description: The properties of a client.
|
|
type: object
|
|
properties:
|
|
id:
|
|
$ref: "#/components/schemas/ClientID"
|
|
name:
|
|
$ref: "#/components/schemas/ClientName"
|
|
can_sync:
|
|
$ref: "#/components/schemas/ClientCanSync"
|
|
required:
|
|
- id
|
|
- name
|
|
- can_sync
|
|
|
|
ClientStatus:
|
|
type: string
|
|
enum:
|
|
- IN_SYNC
|
|
- NOT_SYNCED
|
|
- NOT_SYNCING
|
|
description: Specifies the status of a client.
|
|
|
|
ClientStatusBody:
|
|
description: A client status information object.
|
|
type: object
|
|
properties:
|
|
status:
|
|
$ref: "#/components/schemas/ClientStatus"
|
|
required:
|
|
- status
|
|
|
|
ClientIDBody:
|
|
description: The client id.
|
|
type: object
|
|
properties:
|
|
id:
|
|
$ref: "#/components/schemas/ClientID"
|
|
required:
|
|
- id
|
|
|
|
ClientListResponse:
|
|
description: Response containing a list of all clients.
|
|
type: object
|
|
properties:
|
|
clients:
|
|
type: array
|
|
description: List of clients in the system.
|
|
maxItems: 10000
|
|
items:
|
|
$ref: "#/components/schemas/DocClient"
|
|
totalCount:
|
|
type: integer
|
|
format: int32
|
|
description: Total number of clients.
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
required:
|
|
- clients
|
|
- totalCount
|
|
|
|
UISettingCreate:
|
|
type: object
|
|
description: Request body for creating a UI setting
|
|
required:
|
|
- namespace
|
|
- key
|
|
- value
|
|
properties:
|
|
namespace:
|
|
type: string
|
|
maxLength: 255
|
|
description: Scope for the setting (e.g. demo-dashboard:{userId}, feature-flags:global, saved-filters:{clientId})
|
|
key:
|
|
type: string
|
|
maxLength: 255
|
|
description: Setting key within the namespace
|
|
value:
|
|
type: object
|
|
description: JSON value (object) for the setting
|
|
|
|
UISetting:
|
|
type: object
|
|
description: A UI setting record
|
|
required:
|
|
- id
|
|
- namespace
|
|
- key
|
|
- value
|
|
- isDeleted
|
|
- createdAt
|
|
- updatedAt
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
namespace:
|
|
type: string
|
|
maxLength: 255
|
|
key:
|
|
type: string
|
|
maxLength: 255
|
|
value:
|
|
type: object
|
|
isDeleted:
|
|
type: boolean
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 32
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 32
|
|
|
|
UISettingUpdate:
|
|
type: object
|
|
description: Request body for updating a UI setting
|
|
required:
|
|
- value
|
|
properties:
|
|
value:
|
|
type: object
|
|
description: New JSON value for the setting
|
|
|
|
UISettingListResponse:
|
|
type: object
|
|
description: List of UI settings
|
|
required:
|
|
- settings
|
|
- totalCount
|
|
properties:
|
|
settings:
|
|
type: array
|
|
maxItems: 10000
|
|
items:
|
|
$ref: "#/components/schemas/UISetting"
|
|
totalCount:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 10000
|
|
|
|
ListDocuments:
|
|
type: array
|
|
description: The documents in the client.
|
|
maxItems: 256
|
|
items:
|
|
$ref: "#/components/schemas/DocumentSummary"
|
|
|
|
Hash:
|
|
type: string
|
|
description: The document hash
|
|
maxLength: 2048
|
|
pattern: "^.+$"
|
|
|
|
DocumentSummary:
|
|
description: The document summary properties.
|
|
type: object
|
|
properties:
|
|
id:
|
|
$ref: "#/components/schemas/DocumentID"
|
|
hash:
|
|
$ref: "#/components/schemas/Hash"
|
|
required:
|
|
- id
|
|
- hash
|
|
|
|
DocumentEnriched:
|
|
description: Enriched document details with additional metadata
|
|
type: object
|
|
required:
|
|
- id
|
|
- client_id
|
|
- hash
|
|
- hasTextRecord
|
|
- labels
|
|
properties:
|
|
id:
|
|
$ref: "#/components/schemas/DocumentID"
|
|
client_id:
|
|
$ref: "#/components/schemas/ClientID"
|
|
hash:
|
|
$ref: "#/components/schemas/Hash"
|
|
hasTextRecord:
|
|
type: boolean
|
|
description: "Whether a text extraction (field extraction) record exists for this document"
|
|
folderId:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
description: "Parent folder ID, null if document is not in a folder"
|
|
filename:
|
|
type: string
|
|
maxLength: 4096
|
|
description: "Original filename of the document"
|
|
originalPath:
|
|
type: string
|
|
maxLength: 4096
|
|
description: "Original path provided during upload (immutable)"
|
|
labels:
|
|
type: array
|
|
maxItems: 1000
|
|
items:
|
|
$ref: "#/components/schemas/LabelRecord"
|
|
description: "All labels applied to this document"
|
|
textRecord:
|
|
$ref: "#/components/schemas/FieldExtractionResponse"
|
|
fileSizeBytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
maximum: 4294967295
|
|
description: "File size in bytes (null for legacy documents)"
|
|
|
|
DocumentInFolder:
|
|
description: Document within a folder with enriched metadata (lighter format, excludes client_id and fields)
|
|
type: object
|
|
required:
|
|
- id
|
|
- hash
|
|
- hasTextRecord
|
|
- labels
|
|
properties:
|
|
id:
|
|
$ref: "#/components/schemas/DocumentID"
|
|
hash:
|
|
$ref: "#/components/schemas/Hash"
|
|
hasTextRecord:
|
|
type: boolean
|
|
description: "Whether a text extraction record exists for this document"
|
|
folderId:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
description: "Parent folder ID"
|
|
filename:
|
|
type: string
|
|
maxLength: 4096
|
|
description: "Original filename of the document"
|
|
originalPath:
|
|
type: string
|
|
maxLength: 4096
|
|
description: "Original path provided during upload (immutable)"
|
|
labels:
|
|
type: array
|
|
maxItems: 1000
|
|
items:
|
|
$ref: "#/components/schemas/LabelRecord"
|
|
description: "All labels applied to this document"
|
|
textRecord:
|
|
$ref: "#/components/schemas/FieldExtractionResponse"
|
|
fileSizeBytes:
|
|
type: integer
|
|
format: int64
|
|
minimum: 0
|
|
maximum: 4294967295
|
|
description: "File size in bytes (null for legacy documents)"
|
|
|
|
ClientCreate:
|
|
description: The properties for creation.
|
|
type: object
|
|
properties:
|
|
id:
|
|
$ref: "#/components/schemas/ClientID"
|
|
name:
|
|
$ref: "#/components/schemas/ClientName"
|
|
required:
|
|
- id
|
|
- name
|
|
|
|
ClientUpdate:
|
|
description: The properties that may be updated.
|
|
type: object
|
|
properties:
|
|
name:
|
|
$ref: "#/components/schemas/ClientName"
|
|
can_sync:
|
|
$ref: "#/components/schemas/ClientCanSync"
|
|
|
|
IdMessage:
|
|
description: A single uuid.
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
description: Unique identifier for entity.
|
|
maxLength: 36
|
|
required:
|
|
- id
|
|
|
|
CodeVersion:
|
|
type: integer
|
|
format: int64
|
|
minimum: 1
|
|
maximum: 9223372036854775808
|
|
description: The desired code version.
|
|
|
|
Version:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
description: The desired version.
|
|
|
|
Collector:
|
|
type: object
|
|
properties:
|
|
client_id:
|
|
$ref: "#/components/schemas/ClientID"
|
|
active_version:
|
|
$ref: "#/components/schemas/Version"
|
|
latest_version:
|
|
$ref: "#/components/schemas/Version"
|
|
minimum_cleaner_version:
|
|
$ref: "#/components/schemas/CodeVersion"
|
|
description: Collector model. Note - minimum_text_version has been removed since text extraction is deprecated.
|
|
required:
|
|
- client_id
|
|
- minimum_cleaner_version
|
|
- latest_version
|
|
- active_version
|
|
|
|
CollectorSet:
|
|
type: object
|
|
properties:
|
|
minimum_cleaner_version:
|
|
$ref: "#/components/schemas/CodeVersion"
|
|
active_version:
|
|
$ref: "#/components/schemas/Version"
|
|
description: Payload for updating a Collector. Note - minimum_text_version has been removed.
|
|
|
|
CollectorFieldName:
|
|
type: string
|
|
pattern: "^.+$"
|
|
maxLength: 256
|
|
description: The output field name.
|
|
|
|
ExportTrigger:
|
|
type: object
|
|
properties:
|
|
ingestion_filters:
|
|
type: object
|
|
description: Filter the scope based on ingestion parameters.
|
|
properties:
|
|
start_date:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 32
|
|
description: This first date of ingestion.
|
|
end_date:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 32
|
|
description: The last date of ingestion.
|
|
field_filters:
|
|
type: array
|
|
maxItems: 256
|
|
description: Filter the scope based on field output values.
|
|
items:
|
|
$ref: "#/components/schemas/FieldFilter"
|
|
description: Payload for triggering an export.
|
|
|
|
FieldFilter:
|
|
type: object
|
|
properties:
|
|
field_name:
|
|
$ref: "#/components/schemas/CollectorFieldName"
|
|
condition:
|
|
$ref: "#/components/schemas/FieldFilterCondition"
|
|
values:
|
|
type: array
|
|
description: The values useful to the filter.
|
|
maxItems: 100
|
|
items:
|
|
type: string
|
|
pattern: "^.+$"
|
|
maxLength: 256
|
|
description: Filtering a column
|
|
required:
|
|
- field_name
|
|
- condition
|
|
- values
|
|
|
|
FieldFilterCondition:
|
|
type: string
|
|
enum:
|
|
- less_than
|
|
- greater_than
|
|
- closed_interval
|
|
- open_interval
|
|
- left_closed_interval
|
|
- right_closed_interval
|
|
- include
|
|
- exclude
|
|
description: The possible field filtering conditions.
|
|
|
|
ExportStatus:
|
|
type: string
|
|
enum:
|
|
- completed
|
|
- in_progress
|
|
- failed
|
|
description: The possible export states.
|
|
|
|
ExportDetails:
|
|
type: object
|
|
properties:
|
|
client_id:
|
|
$ref: "#/components/schemas/ClientID"
|
|
status:
|
|
$ref: "#/components/schemas/ExportStatus"
|
|
output_location:
|
|
type: string
|
|
description: The location in which the export zip file will be found.
|
|
example: s3://a/A/export/20250213/uuid.csv
|
|
maxLength: 2048
|
|
pattern: '^s3://.+/.+/export/[0-9]{8}/.+\.csv$'
|
|
description: Payload for export trigger response.
|
|
required:
|
|
- client_id
|
|
- status
|
|
|
|
ErrorMessage:
|
|
description: Description of error
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
pattern: "^.+$"
|
|
description: Message describing the cause.
|
|
maxLength: 256
|
|
example: "you must give me good information"
|
|
error_type:
|
|
type: string
|
|
description: Machine-readable error classification for programmatic handling.
|
|
maxLength: 64
|
|
example: "UserNotFound"
|
|
details:
|
|
type: string
|
|
description: Additional error details for debugging (sanitized).
|
|
maxLength: 512
|
|
example: "The specified user does not exist in Cognito"
|
|
required:
|
|
- message
|
|
example:
|
|
message: you must include a message
|
|
error_type: InvalidParameter
|
|
details: The email format is invalid
|
|
|
|
# Identity API schemas
|
|
IdentityRole:
|
|
type: object
|
|
description: A role assigned to the user with its permissions
|
|
required:
|
|
- key
|
|
- name
|
|
- permissions
|
|
properties:
|
|
key:
|
|
type: string
|
|
description: The role key/identifier
|
|
maxLength: 128
|
|
pattern: "^[a-z0-9_-]+$"
|
|
example: "auditor"
|
|
name:
|
|
type: string
|
|
description: Human-readable role name
|
|
maxLength: 256
|
|
pattern: "^.+$"
|
|
example: "Auditor"
|
|
description:
|
|
type: string
|
|
description: Optional description of the role
|
|
maxLength: 1024
|
|
example: "Read-only access to view documents and exports"
|
|
permissions:
|
|
type: array
|
|
description: List of permissions granted by this role
|
|
maxItems: 500
|
|
items:
|
|
type: string
|
|
maxLength: 128
|
|
pattern: "^[a-z0-9_-]+:[a-z0-9_-]+$"
|
|
example: ["document:read", "document:list", "export:read"]
|
|
|
|
IdentityResponse:
|
|
type: object
|
|
description: Response containing the user's roles and their permissions
|
|
required:
|
|
- roles
|
|
properties:
|
|
roles:
|
|
type: array
|
|
description: List of roles assigned to the user with their permissions
|
|
maxItems: 100
|
|
items:
|
|
$ref: "#/components/schemas/IdentityRole"
|
|
|
|
# Admin API schemas
|
|
AdminUserCreate:
|
|
description: Request body for creating a new user with email, name, and role assignments
|
|
type: object
|
|
required:
|
|
- email
|
|
- first_name
|
|
- last_name
|
|
- roles
|
|
properties:
|
|
email:
|
|
type: string
|
|
format: email
|
|
maxLength: 320
|
|
pattern: '^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$'
|
|
description: User email address (used as Cognito username)
|
|
example: john.doe@example.com
|
|
first_name:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 100
|
|
pattern: "^.+$"
|
|
description: User's given name for account creation
|
|
example: John
|
|
last_name:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 100
|
|
pattern: "^.+$"
|
|
description: User's family name for account creation
|
|
example: Doe
|
|
roles:
|
|
type: array
|
|
minItems: 1
|
|
maxItems: 50
|
|
items:
|
|
type: string
|
|
pattern: "^.+$"
|
|
maxLength: 100
|
|
description: >-
|
|
List of role keys to assign in Permit.io (e.g., super_admin, user_admin, auditor, client_user).
|
|
Roles must exist in your Permit.io environment. Invalid roles fail silently - check roles_assigned in response.
|
|
example: ["user_admin", "auditor"]
|
|
|
|
AdminUserCreateResponse:
|
|
description: Response after creating a user, including Cognito subject ID and sync status
|
|
type: object
|
|
required:
|
|
- cognito_subject_id
|
|
- email
|
|
- status
|
|
- permit_synced
|
|
properties:
|
|
cognito_subject_id:
|
|
type: string
|
|
maxLength: 256
|
|
pattern: "^.+$"
|
|
description: Created user's Cognito unique subject identifier
|
|
example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
|
|
email:
|
|
type: string
|
|
format: email
|
|
maxLength: 320
|
|
description: User email address
|
|
example: john.doe@example.com
|
|
first_name:
|
|
type: string
|
|
maxLength: 100
|
|
pattern: "^.+$"
|
|
description: Created user's given name
|
|
example: John
|
|
last_name:
|
|
type: string
|
|
maxLength: 100
|
|
pattern: "^.+$"
|
|
description: Created user's family name
|
|
example: Doe
|
|
status:
|
|
type: string
|
|
maxLength: 50
|
|
pattern: "^.+$"
|
|
description: Cognito user status
|
|
example: FORCE_CHANGE_PASSWORD
|
|
enabled:
|
|
type: boolean
|
|
description: Whether the created user is enabled in Cognito
|
|
example: true
|
|
permit_synced:
|
|
type: boolean
|
|
description: >-
|
|
Whether user was successfully created in Permit.io authorization system.
|
|
If false, user exists in Cognito (can authenticate) but not in Permit.io (has no authorization/permissions).
|
|
Manual sync or retry may be required.
|
|
example: true
|
|
roles_assigned:
|
|
type: array
|
|
maxItems: 50
|
|
items:
|
|
type: string
|
|
maxLength: 100
|
|
pattern: "^.+$"
|
|
description: >-
|
|
Roles that were successfully assigned in Permit.io. May be a subset of requested roles if some failed.
|
|
Compare with requested roles array to detect assignment failures. If null or empty, no roles were assigned
|
|
(user has no permissions). Only present if permit_synced is true.
|
|
example: ["user_admin", "auditor"]
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: Timestamp when the user was created in the system
|
|
example: "2025-10-16T14:23:45Z"
|
|
|
|
AdminUserDetails:
|
|
description: Complete user information from Cognito and Permit.io including roles and timestamps
|
|
type: object
|
|
required:
|
|
- cognito_subject_id
|
|
- email
|
|
- status
|
|
- enabled
|
|
properties:
|
|
cognito_subject_id:
|
|
type: string
|
|
maxLength: 256
|
|
pattern: "^.+$"
|
|
description: User's Cognito unique subject identifier from authentication system
|
|
example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
|
|
email:
|
|
type: string
|
|
format: email
|
|
maxLength: 320
|
|
description: Email address of the user account
|
|
example: john.doe@example.com
|
|
first_name:
|
|
type: string
|
|
maxLength: 100
|
|
pattern: "^.+$"
|
|
description: User's given name retrieved from Cognito
|
|
example: John
|
|
last_name:
|
|
type: string
|
|
maxLength: 100
|
|
pattern: "^.+$"
|
|
description: User's family name retrieved from Cognito
|
|
example: Doe
|
|
status:
|
|
type: string
|
|
maxLength: 50
|
|
pattern: "^.+$"
|
|
description: Current Cognito user account status
|
|
example: CONFIRMED
|
|
enabled:
|
|
type: boolean
|
|
description: Current enabled status of the user in Cognito
|
|
example: true
|
|
roles:
|
|
type: array
|
|
maxItems: 50
|
|
items:
|
|
type: string
|
|
maxLength: 100
|
|
pattern: "^.+$"
|
|
description: >-
|
|
Roles assigned in Permit.io. Only populated by GET /admin/users/{email}.
|
|
Not populated by GET /admin/users (list endpoint) for performance reasons.
|
|
example: ["admin", "viewer"]
|
|
created_at:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: Timestamp when the user account was created
|
|
example: "2025-10-15T09:15:30Z"
|
|
updated_at:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: Timestamp of last update
|
|
example: "2025-10-16T14:20:10Z"
|
|
|
|
AdminUserUpdate:
|
|
description: Request body for updating user attributes (first name, last name, and roles)
|
|
type: object
|
|
properties:
|
|
first_name:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 100
|
|
pattern: "^.+$"
|
|
description: Updated given name for the user
|
|
example: Jonathan
|
|
last_name:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 100
|
|
pattern: "^.+$"
|
|
description: Updated family name for the user
|
|
example: Doe-Smith
|
|
roles:
|
|
type: array
|
|
minItems: 1
|
|
maxItems: 50
|
|
items:
|
|
type: string
|
|
pattern: "^.+$"
|
|
maxLength: 100
|
|
description: >-
|
|
Complete list of role keys to assign in Permit.io - REPLACES all existing roles (not additive).
|
|
To add a role, include all current roles plus the new one. To remove a role, omit it from the array.
|
|
Roles must exist in Permit.io environment. Invalid roles fail silently - check response.roles for final state.
|
|
Omit this field entirely to leave roles unchanged.
|
|
example: ["user_admin", "auditor"]
|
|
|
|
AdminUserList:
|
|
description: Paginated list of users with total count and pagination metadata
|
|
type: object
|
|
required:
|
|
- users
|
|
- total
|
|
- page
|
|
- page_size
|
|
properties:
|
|
users:
|
|
type: array
|
|
maxItems: 100
|
|
items:
|
|
$ref: '#/components/schemas/AdminUserDetails'
|
|
description: List of users for current page
|
|
total:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
description: Total number of users matching filter
|
|
example: 147
|
|
page:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 10000
|
|
description: Current page number
|
|
example: 1
|
|
page_size:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 100
|
|
description: Number of users per page
|
|
example: 20
|
|
has_more:
|
|
type: boolean
|
|
description: Whether more pages are available
|
|
example: true
|
|
|
|
AdminUserActionResponse:
|
|
description: Response for user enable/disable actions with success status and timestamp
|
|
type: object
|
|
required:
|
|
- success
|
|
- email
|
|
- action
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
description: Whether the action succeeded
|
|
example: true
|
|
email:
|
|
type: string
|
|
format: email
|
|
maxLength: 320
|
|
description: Email of the user acted upon
|
|
example: john.doe@example.com
|
|
action:
|
|
type: string
|
|
enum: [disable, enable]
|
|
description: Action performed
|
|
example: disable
|
|
cognito_subject_id:
|
|
type: string
|
|
maxLength: 256
|
|
pattern: "^.+$"
|
|
description: Cognito subject identifier for the action response
|
|
example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: Timestamp of the action
|
|
example: "2025-10-16T14:25:33Z"
|
|
|
|
AdminUserDeleteResponse:
|
|
description: Response for user deletion with status from each system (Cognito and Permit.io)
|
|
type: object
|
|
required:
|
|
- success
|
|
- email
|
|
- deleted_from
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
description: Whether the deletion succeeded
|
|
example: true
|
|
email:
|
|
type: string
|
|
format: email
|
|
maxLength: 320
|
|
description: Email of the deleted user
|
|
example: john.doe@example.com
|
|
cognito_subject_id:
|
|
type: string
|
|
maxLength: 256
|
|
pattern: "^.+$"
|
|
description: Cognito subject identifier of the deleted user
|
|
example: a1b2c3d4-e5f6-7890-abcd-ef1234567890
|
|
deleted_from:
|
|
type: object
|
|
required:
|
|
- cognito
|
|
- permit
|
|
properties:
|
|
cognito:
|
|
type: boolean
|
|
description: Whether user was deleted from Cognito
|
|
example: true
|
|
permit:
|
|
type: boolean
|
|
description: Whether user was deleted from Permit.io
|
|
example: true
|
|
description: Deletion status from each system
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: Timestamp of the deletion
|
|
example: "2025-10-16T14:27:15Z"
|
|
|
|
# Folder schemas
|
|
FolderCreate:
|
|
description: Request to create a new folder for organizing documents
|
|
type: object
|
|
required:
|
|
- path
|
|
- clientId
|
|
- createdBy
|
|
properties:
|
|
path:
|
|
type: string
|
|
maxLength: 1000
|
|
pattern: "^/.*$"
|
|
description: Folder path (must start with /). Use "/" for root folder.
|
|
example: "/documents/2024"
|
|
parentId:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
description: Optional parent folder ID
|
|
example: "019580df-ef65-7676-8de9-94435a93337a"
|
|
clientId:
|
|
$ref: "#/components/schemas/ClientID"
|
|
createdBy:
|
|
type: string
|
|
format: email
|
|
maxLength: 320
|
|
description: Email of user who created the folder
|
|
example: user@example.com
|
|
|
|
FolderRename:
|
|
description: Request to rename an existing folder
|
|
type: object
|
|
required:
|
|
- path
|
|
properties:
|
|
path:
|
|
type: string
|
|
maxLength: 1000
|
|
pattern: "^/.*$"
|
|
description: New folder path (must start with /). Use "/" for root folder.
|
|
example: "/documents/2024-renamed"
|
|
|
|
Folder:
|
|
description: Folder information for organizing documents
|
|
type: object
|
|
required:
|
|
- id
|
|
- path
|
|
- clientId
|
|
- createdAt
|
|
- createdBy
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
description: Folder ID
|
|
example: "019580df-ef65-7676-8de9-94435a93337a"
|
|
path:
|
|
type: string
|
|
maxLength: 1000
|
|
pattern: "^/.*$"
|
|
description: Folder path (must start with /). Root folder has path "/".
|
|
example: "/documents/2024"
|
|
parentId:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
nullable: true
|
|
description: Parent folder ID
|
|
example: "019580df-ef65-7676-8de9-94435a93337b"
|
|
clientId:
|
|
$ref: "#/components/schemas/ClientID"
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: Creation timestamp
|
|
example: "2025-10-16T14:27:15Z"
|
|
createdBy:
|
|
type: string
|
|
format: email
|
|
maxLength: 320
|
|
description: Email of the user who created this folder
|
|
example: user@example.com
|
|
metrics:
|
|
allOf:
|
|
- $ref: "#/components/schemas/FolderMetricsInline"
|
|
nullable: true
|
|
description: |
|
|
Processing metrics for this folder. Only populated when metrics=true
|
|
is specified in the request. Null otherwise.
|
|
|
|
FolderList:
|
|
description: List of folders for a client
|
|
type: object
|
|
required:
|
|
- folders
|
|
properties:
|
|
folders:
|
|
type: array
|
|
maxItems: 10000
|
|
description: |
|
|
List of folders. Each folder includes its ID, path, and parentId.
|
|
Root-level folders have parentId set to null. Clients can use
|
|
parentId to reconstruct the folder hierarchy/tree structure.
|
|
items:
|
|
$ref: "#/components/schemas/Folder"
|
|
|
|
FolderMetrics:
|
|
description: Processing metrics for a folder including document counts
|
|
type: object
|
|
required:
|
|
- folderId
|
|
- totalDocuments
|
|
- byLabel
|
|
properties:
|
|
folderId:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
description: Unique identifier for the folder
|
|
example: "019580df-ef65-7676-8de9-94435a93337a"
|
|
totalDocuments:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 1000000
|
|
description: Total number of documents in folder
|
|
example: 150
|
|
byLabel:
|
|
type: object
|
|
maxProperties: 100
|
|
additionalProperties:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 1000000
|
|
description: Document counts by label
|
|
example:
|
|
Ingested: 150
|
|
OCR_Processed: 120
|
|
Dashboard_Ready: 100
|
|
|
|
FolderMetricsInline:
|
|
description: Inline processing metrics for a folder (excludes folderId since it's on parent)
|
|
type: object
|
|
required:
|
|
- totalDocuments
|
|
- byLabel
|
|
properties:
|
|
totalDocuments:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 1000000
|
|
description: Total number of documents in folder
|
|
example: 150
|
|
byLabel:
|
|
type: object
|
|
maxProperties: 100
|
|
additionalProperties:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 1000000
|
|
description: Document counts by label
|
|
example:
|
|
Ingested: 150
|
|
OCR_Processed: 120
|
|
Dashboard_Ready: 100
|
|
|
|
# Label schemas
|
|
LabelApplication:
|
|
description: Request to apply a workflow label to a document
|
|
type: object
|
|
required:
|
|
- label
|
|
- appliedBy
|
|
properties:
|
|
label:
|
|
type: string
|
|
maxLength: 100
|
|
pattern: "^[A-Za-z0-9_]+$"
|
|
description: Label name (alphanumeric and underscore only)
|
|
example: "OCR_Processed"
|
|
appliedBy:
|
|
type: string
|
|
format: email
|
|
maxLength: 320
|
|
description: Email of user applying the label
|
|
example: user@example.com
|
|
|
|
LabelRecord:
|
|
description: Record of a label applied to a document
|
|
type: object
|
|
required:
|
|
- id
|
|
- documentId
|
|
- label
|
|
- appliedBy
|
|
- appliedAt
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
description: Label record ID
|
|
example: "019580df-ef65-7676-8de9-94435a93337a"
|
|
documentId:
|
|
$ref: "#/components/schemas/DocumentID"
|
|
label:
|
|
type: string
|
|
maxLength: 100
|
|
pattern: "^[A-Za-z0-9_]+$"
|
|
description: Workflow label name (alphanumeric and underscore only)
|
|
example: "OCR_Processed"
|
|
appliedBy:
|
|
type: string
|
|
format: email
|
|
maxLength: 320
|
|
description: Email of the user who applied this label
|
|
example: user@example.com
|
|
appliedAt:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: Timestamp when label was applied
|
|
example: "2025-10-16T14:27:15Z"
|
|
|
|
# Field Extraction schemas
|
|
FieldExtractionRequest:
|
|
description: Request to create a new field extraction with single and array fields
|
|
type: object
|
|
required:
|
|
- documentId
|
|
- singleFields
|
|
- arrayFields
|
|
- createdBy
|
|
properties:
|
|
documentId:
|
|
$ref: "#/components/schemas/DocumentID"
|
|
singleFields:
|
|
$ref: "#/components/schemas/SingleFields"
|
|
arrayFields:
|
|
type: array
|
|
maxItems: 10000
|
|
items:
|
|
$ref: "#/components/schemas/ArrayFieldItem"
|
|
description: Array of field extraction items (all must have consistent structure)
|
|
createdBy:
|
|
type: string
|
|
format: email
|
|
maxLength: 320
|
|
description: Email of user creating the extraction
|
|
example: user@example.com
|
|
|
|
SingleFields:
|
|
description: Single-value fields for a document extraction (1:1 relationship)
|
|
type: object
|
|
properties:
|
|
fileName:
|
|
type: string
|
|
maxLength: 500
|
|
description: Original file name
|
|
example: "contract_2024.pdf"
|
|
contractTitle:
|
|
type: string
|
|
maxLength: 500
|
|
description: Title of the contract
|
|
aareteDerivedAmendmentNum:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 999
|
|
description: Amendment number derived by Aarete
|
|
clientName:
|
|
type: string
|
|
maxLength: 500
|
|
description: Name of the client
|
|
payerName:
|
|
type: string
|
|
maxLength: 500
|
|
description: Name of the payer
|
|
payerState:
|
|
type: string
|
|
maxLength: 2
|
|
pattern: "^[A-Z]{2}$"
|
|
description: Two-letter state code for payer
|
|
example: "CA"
|
|
providerState:
|
|
type: string
|
|
maxLength: 2
|
|
pattern: "^[A-Z]{2}$"
|
|
description: Two-letter state code for provider
|
|
example: "NY"
|
|
filenameTin:
|
|
type: string
|
|
maxLength: 20
|
|
description: Tax Identification Number from filename
|
|
provGroupTin:
|
|
type: string
|
|
maxLength: 20
|
|
description: Provider group TIN
|
|
provGroupNpi:
|
|
type: string
|
|
maxLength: 20
|
|
description: Provider group NPI
|
|
provGroupNameFull:
|
|
type: string
|
|
maxLength: 500
|
|
description: Full name of provider group
|
|
provOtherTin:
|
|
type: string
|
|
maxLength: 20
|
|
description: Other provider TIN
|
|
provOtherNpi:
|
|
type: string
|
|
maxLength: 20
|
|
description: Other provider NPI
|
|
provOtherNameFull:
|
|
type: string
|
|
maxLength: 500
|
|
description: Full name of other provider
|
|
aareteDerivedEffectiveDt:
|
|
type: string
|
|
format: date
|
|
maxLength: 50
|
|
description: Contract effective date
|
|
example: "2024-01-01"
|
|
aareteDerivedTerminationDt:
|
|
type: string
|
|
format: date
|
|
maxLength: 50
|
|
description: Contract termination date
|
|
example: "2025-12-31"
|
|
autoRenewalInd:
|
|
type: boolean
|
|
description: Auto-renewal indicator
|
|
autoRenewalTerm:
|
|
type: string
|
|
maxLength: 200
|
|
description: Auto-renewal terms
|
|
|
|
ArrayFieldItem:
|
|
description: Single row of array field data (112 fields forming one row)
|
|
type: object
|
|
properties:
|
|
exhibitTitle:
|
|
type: string
|
|
maxLength: 500
|
|
exhibitPage:
|
|
type: string
|
|
maxLength: 100
|
|
reimbProvTin:
|
|
type: string
|
|
maxLength: 20
|
|
reimbProvNpi:
|
|
type: string
|
|
maxLength: 20
|
|
reimbProvName:
|
|
type: string
|
|
maxLength: 500
|
|
reimbEffectiveDt:
|
|
type: string
|
|
format: date
|
|
maxLength: 50
|
|
reimbTerminationDt:
|
|
type: string
|
|
format: date
|
|
maxLength: 50
|
|
aareteDerivedClaimTypeCd:
|
|
type: string
|
|
maxLength: 100
|
|
aareteDerivedProduct:
|
|
type: string
|
|
maxLength: 200
|
|
aareteDerivedLob:
|
|
type: string
|
|
maxLength: 200
|
|
aareteDerivedProgram:
|
|
type: string
|
|
maxLength: 200
|
|
aareteDerivedNetwork:
|
|
type: string
|
|
maxLength: 200
|
|
aareteDerivedProvType:
|
|
type: string
|
|
maxLength: 200
|
|
provTaxonomyCd:
|
|
type: string
|
|
maxLength: 100
|
|
provTaxonomyCdDesc:
|
|
type: string
|
|
maxLength: 500
|
|
provSpecialtyCd:
|
|
type: string
|
|
maxLength: 100
|
|
provSpecialtyCdDesc:
|
|
type: string
|
|
maxLength: 500
|
|
placeOfServiceCd:
|
|
type: string
|
|
maxLength: 100
|
|
placeOfServiceCdDesc:
|
|
type: string
|
|
maxLength: 500
|
|
billTypeCd:
|
|
type: string
|
|
maxLength: 100
|
|
billTypeCdDesc:
|
|
type: string
|
|
maxLength: 500
|
|
patientAgeMin:
|
|
type: string
|
|
maxLength: 50
|
|
patientAgeMax:
|
|
type: string
|
|
maxLength: 50
|
|
reimbTerm:
|
|
type: string
|
|
maxLength: 500
|
|
lobProgramRelationship:
|
|
type: string
|
|
maxLength: 200
|
|
lobProductRelationship:
|
|
type: string
|
|
maxLength: 200
|
|
carveoutInd:
|
|
type: boolean
|
|
carveoutCd:
|
|
type: string
|
|
maxLength: 100
|
|
lesserOfInd:
|
|
type: boolean
|
|
greaterOfInd:
|
|
type: boolean
|
|
aareteDerivedReimbMethod:
|
|
type: string
|
|
maxLength: 200
|
|
unitOfMeasure:
|
|
type: string
|
|
maxLength: 100
|
|
reimbPctRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 999.9999
|
|
reimbFeeRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
reimbConversionFactor:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 99999999.9999
|
|
triggerCapThresholdAmt:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
triggerBaseThreshold:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
defaultInd:
|
|
type: boolean
|
|
additionDesc:
|
|
type: string
|
|
maxLength: 1000
|
|
additionMaxFeeRateInc:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
additionMaxPctRateInc:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 999.9999
|
|
aareteDerivedAdditionRateChangeTimeline:
|
|
type: string
|
|
maxLength: 200
|
|
aareteDerivedFeeSchedule:
|
|
type: string
|
|
maxLength: 200
|
|
aareteDerivedFeeScheduleVersion:
|
|
type: string
|
|
maxLength: 100
|
|
serviceTerm:
|
|
type: string
|
|
maxLength: 500
|
|
cpt4ProcCd:
|
|
type: string
|
|
maxLength: 100
|
|
cpt4ProcCdDesc:
|
|
type: string
|
|
maxLength: 500
|
|
cpt4ProcMod:
|
|
type: string
|
|
maxLength: 100
|
|
cpt4ProcModDesc:
|
|
type: string
|
|
maxLength: 500
|
|
revenueCd:
|
|
type: string
|
|
maxLength: 100
|
|
revenueCdDesc:
|
|
type: string
|
|
maxLength: 500
|
|
diagCd:
|
|
type: string
|
|
maxLength: 100
|
|
diagCdDesc:
|
|
type: string
|
|
maxLength: 500
|
|
ndcCd:
|
|
type: string
|
|
maxLength: 100
|
|
ndcCdDesc:
|
|
type: string
|
|
maxLength: 500
|
|
claimAdmitTypeCd:
|
|
type: string
|
|
maxLength: 100
|
|
authAdmitTypeDesc:
|
|
type: string
|
|
maxLength: 500
|
|
claimStatusCd:
|
|
type: string
|
|
maxLength: 100
|
|
claimStatusCdDesc:
|
|
type: string
|
|
maxLength: 500
|
|
grouperType:
|
|
type: string
|
|
maxLength: 100
|
|
grouperCd:
|
|
type: string
|
|
maxLength: 100
|
|
grouperCdDesc:
|
|
type: string
|
|
maxLength: 500
|
|
grouperPctRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 999.9999
|
|
grouperBaseRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
# Grouper Extended Fields
|
|
aareteDerivedGrouperVersion:
|
|
type: string
|
|
maxLength: 200
|
|
grouperAlternativeLevelOfCare:
|
|
type: string
|
|
maxLength: 200
|
|
grouperSeverityInd:
|
|
type: boolean
|
|
grouperSeverity:
|
|
type: string
|
|
maxLength: 100
|
|
grouperRiskOfMortalitySubclass:
|
|
type: string
|
|
maxLength: 100
|
|
grouperTransferInd:
|
|
type: boolean
|
|
grouperReadmissionsInd:
|
|
type: boolean
|
|
grouperHacInd:
|
|
type: boolean
|
|
# Outlier Fields
|
|
outlierTerm:
|
|
type: string
|
|
maxLength: 500
|
|
outlierFirstDollarInd:
|
|
type: boolean
|
|
rangeNbrDays:
|
|
type: string
|
|
maxLength: 100
|
|
outlierFixedLossNbrDaysThreshold:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 99999999.99
|
|
outlierFixedLossThreshold:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
outlierMaximum:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
outlierMaximumFrequency:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 99999999.99
|
|
outlierPctRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 999.9999
|
|
outlierExclusionCd:
|
|
type: string
|
|
maxLength: 100
|
|
outlierExclusionCdDesc:
|
|
type: string
|
|
maxLength: 500
|
|
# Facility Adjustment Fields
|
|
facilityAdjustmentTerm:
|
|
type: string
|
|
maxLength: 500
|
|
dshInd:
|
|
type: boolean
|
|
dshPctRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 999.9999
|
|
dshFeeRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
imeInd:
|
|
type: boolean
|
|
imePctRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 999.9999
|
|
imeFeeRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
ntapInd:
|
|
type: boolean
|
|
ntapPctRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 999.9999
|
|
ntapFeeRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
ucInd:
|
|
type: boolean
|
|
ucPctRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 999.9999
|
|
ucFeeRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
gmeInd:
|
|
type: boolean
|
|
gmePctRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 999.9999
|
|
gmeFeeRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
# Rate Escalator Fields
|
|
rateEscalatorInd:
|
|
type: boolean
|
|
rateEscalatorDesc:
|
|
type: string
|
|
maxLength: 500
|
|
rateEscalatorMaxRateIncPct:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 999.9999
|
|
rateEscalatorRateChangeTimeline:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 99999999.99
|
|
# Stop Loss Fields
|
|
stopLossTerm:
|
|
type: string
|
|
maxLength: 500
|
|
stopLossFirstDollarInd:
|
|
type: boolean
|
|
stopLossRangeNbrDays:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 99999999.99
|
|
stopLossFixedLossThreshold:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
stopLossMaximum:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
stopLossMaximumFrequency:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 99999999.99
|
|
stopLossDailyMaxRate:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 9999999999.99
|
|
stopLossPctRateOnExcessCharges:
|
|
type: number
|
|
format: double
|
|
minimum: 0
|
|
maximum: 999.9999
|
|
stopLossExclusionCd:
|
|
type: string
|
|
maxLength: 100
|
|
stopLossExclusionDesc:
|
|
type: string
|
|
maxLength: 500
|
|
|
|
FieldExtractionResponse:
|
|
description: Field extraction with version information
|
|
type: object
|
|
required:
|
|
- id
|
|
- documentId
|
|
- version
|
|
- singleFields
|
|
- arrayFields
|
|
- createdAt
|
|
- createdBy
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
description: Field extraction ID
|
|
example: "019580df-ef65-7676-8de9-94435a93337a"
|
|
documentId:
|
|
$ref: "#/components/schemas/DocumentID"
|
|
version:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 9999
|
|
description: Version number (1-based)
|
|
example: 1
|
|
singleFields:
|
|
$ref: "#/components/schemas/SingleFields"
|
|
arrayFields:
|
|
type: array
|
|
maxItems: 10000
|
|
items:
|
|
$ref: "#/components/schemas/ArrayFieldItem"
|
|
description: Array of field extraction items
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: Creation timestamp
|
|
example: "2025-10-16T14:27:15Z"
|
|
createdBy:
|
|
type: string
|
|
format: email
|
|
maxLength: 320
|
|
description: Email of user who created this extraction
|
|
example: user@example.com
|
|
|
|
FieldExtractionVersion:
|
|
description: Field extraction version summary for history
|
|
type: object
|
|
required:
|
|
- id
|
|
- documentId
|
|
- version
|
|
- createdAt
|
|
- createdBy
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 50
|
|
description: Field extraction ID
|
|
example: "019580df-ef65-7676-8de9-94435a93337a"
|
|
documentId:
|
|
$ref: "#/components/schemas/DocumentID"
|
|
version:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 9999
|
|
description: Version number (1-based)
|
|
example: 1
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: Creation timestamp
|
|
example: "2025-10-16T14:27:15Z"
|
|
createdBy:
|
|
type: string
|
|
format: email
|
|
maxLength: 320
|
|
description: Email of user who created this version
|
|
example: user@example.com
|
|
|
|
# EULA Schemas
|
|
EulaVersion:
|
|
description: Full EULA version details
|
|
type: object
|
|
required:
|
|
- id
|
|
- version
|
|
- title
|
|
- content
|
|
- createdAt
|
|
- createdBy
|
|
- isCurrent
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
description: EULA version ID
|
|
version:
|
|
type: string
|
|
maxLength: 50
|
|
pattern: "^.+$"
|
|
description: Version string (e.g., "1.0", "2024-01")
|
|
example: "1.0"
|
|
title:
|
|
type: string
|
|
maxLength: 500
|
|
pattern: "^.+$"
|
|
description: Human-readable title
|
|
example: "Terms of Service v1.0"
|
|
content:
|
|
type: string
|
|
maxLength: 1048576
|
|
description: Full EULA text in Markdown format
|
|
example: "# Terms of Service\n\n## Section 1\n\nBy using this service..."
|
|
effectiveDate:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
nullable: true
|
|
description: When this version becomes effective (optional)
|
|
example: "2026-01-01T00:00:00Z"
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: Creation timestamp
|
|
example: "2025-12-15T10:30:00Z"
|
|
createdBy:
|
|
type: string
|
|
maxLength: 320
|
|
description: Identifier of admin who created this version (email, username, or subject ID)
|
|
example: admin@example.com
|
|
isCurrent:
|
|
type: boolean
|
|
description: Whether this is the current active version
|
|
example: true
|
|
activatedAt:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
nullable: true
|
|
description: When this version was activated
|
|
example: "2026-01-01T00:00:00Z"
|
|
activatedBy:
|
|
type: string
|
|
maxLength: 320
|
|
nullable: true
|
|
description: Identifier of admin who activated this version (email, username, or subject ID)
|
|
example: admin@example.com
|
|
|
|
EulaVersionSummary:
|
|
description: Abbreviated EULA version for lists
|
|
type: object
|
|
required:
|
|
- id
|
|
- version
|
|
- title
|
|
- isCurrent
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
description: EULA version ID
|
|
version:
|
|
type: string
|
|
maxLength: 50
|
|
pattern: "^.+$"
|
|
description: Version string
|
|
example: "1.0"
|
|
title:
|
|
type: string
|
|
maxLength: 500
|
|
pattern: "^.+$"
|
|
description: Human-readable title
|
|
example: "Terms of Service v1.0"
|
|
effectiveDate:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
nullable: true
|
|
description: When this version becomes effective (optional)
|
|
example: "2026-01-01T00:00:00Z"
|
|
isCurrent:
|
|
type: boolean
|
|
description: Whether this is the current active version
|
|
example: true
|
|
|
|
EulaVersionCreate:
|
|
description: Request body for creating a new EULA version
|
|
type: object
|
|
required:
|
|
- version
|
|
- title
|
|
- content
|
|
properties:
|
|
version:
|
|
type: string
|
|
maxLength: 50
|
|
minLength: 1
|
|
pattern: "^.+$"
|
|
description: Version string (must be unique)
|
|
example: "1.0"
|
|
title:
|
|
type: string
|
|
maxLength: 500
|
|
minLength: 1
|
|
pattern: "^.+$"
|
|
description: Human-readable title
|
|
example: "Terms of Service v1.0"
|
|
content:
|
|
type: string
|
|
maxLength: 1048576
|
|
minLength: 1
|
|
description: Full EULA text in Markdown format
|
|
example: "# Terms of Service\n\n## Section 1\n\nBy using this service..."
|
|
effectiveDate:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
nullable: true
|
|
description: When this version becomes effective (optional)
|
|
example: "2026-01-01T00:00:00Z"
|
|
|
|
EulaVersionUpdate:
|
|
description: Request body for updating EULA version metadata
|
|
type: object
|
|
properties:
|
|
title:
|
|
type: string
|
|
maxLength: 500
|
|
minLength: 1
|
|
pattern: "^.+$"
|
|
description: Human-readable title
|
|
example: "Terms of Service v1.0 (Updated)"
|
|
effectiveDate:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: When this version becomes effective
|
|
example: "2026-01-15T00:00:00Z"
|
|
|
|
EulaVersionList:
|
|
description: Paginated list of EULA versions
|
|
type: object
|
|
required:
|
|
- versions
|
|
- total
|
|
- page
|
|
- page_size
|
|
properties:
|
|
versions:
|
|
type: array
|
|
maxItems: 100
|
|
items:
|
|
$ref: "#/components/schemas/EulaVersion"
|
|
description: List of EULA versions
|
|
total:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
description: Total number of EULA versions
|
|
example: 5
|
|
page:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 10000
|
|
description: Current page number
|
|
example: 1
|
|
page_size:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 100
|
|
description: Number of items per page
|
|
example: 20
|
|
has_more:
|
|
type: boolean
|
|
description: Whether more pages are available
|
|
example: false
|
|
|
|
EulaPublicResponse:
|
|
description: Public response for current EULA version
|
|
type: object
|
|
required:
|
|
- id
|
|
- version
|
|
- title
|
|
- content
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
description: EULA version ID
|
|
version:
|
|
type: string
|
|
maxLength: 50
|
|
pattern: "^.+$"
|
|
description: Version string
|
|
example: "1.0"
|
|
title:
|
|
type: string
|
|
maxLength: 500
|
|
pattern: "^.+$"
|
|
description: Human-readable title
|
|
example: "Terms of Service v1.0"
|
|
content:
|
|
type: string
|
|
maxLength: 1048576
|
|
description: Full EULA text in Markdown format
|
|
example: "# Terms of Service\n\n## Section 1\n\nBy using this service..."
|
|
effectiveDate:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
nullable: true
|
|
description: When this version became effective (optional)
|
|
example: "2026-01-01T00:00:00Z"
|
|
|
|
EulaStatusResponse:
|
|
description: User's EULA agreement status
|
|
type: object
|
|
required:
|
|
- hasAgreed
|
|
- currentVersion
|
|
- currentVersionId
|
|
properties:
|
|
hasAgreed:
|
|
type: boolean
|
|
description: Whether the user has agreed to the current EULA
|
|
example: true
|
|
currentVersion:
|
|
type: string
|
|
maxLength: 50
|
|
pattern: "^.+$"
|
|
description: Current EULA version string
|
|
example: "2.0"
|
|
currentVersionId:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
description: EULA version ID
|
|
agreedAt:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
nullable: true
|
|
description: When the user agreed (null if not agreed)
|
|
example: "2026-01-15T10:30:00Z"
|
|
agreedVersion:
|
|
type: string
|
|
maxLength: 50
|
|
nullable: true
|
|
description: Version the user agreed to (null if not agreed)
|
|
example: "2.0"
|
|
|
|
EulaAgreementResponse:
|
|
description: Response after recording an agreement
|
|
type: object
|
|
required:
|
|
- id
|
|
- eulaVersionId
|
|
- eulaVersion
|
|
- agreedAt
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
description: Agreement record ID
|
|
example: "019580df-ef65-7676-8de9-94435a93337a"
|
|
eulaVersionId:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
description: EULA version ID
|
|
eulaVersion:
|
|
type: string
|
|
maxLength: 50
|
|
pattern: "^.+$"
|
|
description: EULA version string
|
|
example: "1.0"
|
|
agreedAt:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: When the agreement was recorded
|
|
example: "2026-01-15T10:30:00Z"
|
|
|
|
EulaAgreement:
|
|
description: EULA agreement record
|
|
type: object
|
|
required:
|
|
- id
|
|
- cognitoSubjectId
|
|
- userEmail
|
|
- eulaVersionId
|
|
- eulaVersion
|
|
- agreedAt
|
|
- agreedFromIp
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
description: Agreement record ID
|
|
example: "019580df-ef65-7676-8de9-94435a93337a"
|
|
cognitoSubjectId:
|
|
type: string
|
|
maxLength: 256
|
|
pattern: "^.+$"
|
|
description: User's Cognito subject ID
|
|
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
userEmail:
|
|
type: string
|
|
maxLength: 320
|
|
description: User identifier at time of agreement (email, username, or subject ID)
|
|
example: user@example.com
|
|
eulaVersionId:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
description: EULA version ID
|
|
eulaVersion:
|
|
type: string
|
|
maxLength: 50
|
|
pattern: "^.+$"
|
|
description: EULA version string
|
|
example: "1.0"
|
|
eulaVersionTitle:
|
|
type: string
|
|
maxLength: 500
|
|
description: EULA version title (for user history view)
|
|
example: "Terms of Service v1.0"
|
|
agreedAt:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
description: When the agreement was recorded
|
|
example: "2026-01-15T10:30:00Z"
|
|
agreedFromIp:
|
|
type: string
|
|
maxLength: 45
|
|
description: IP address from which the user agreed
|
|
example: "192.168.1.100"
|
|
|
|
EulaAgreementList:
|
|
description: Paginated list of EULA agreements
|
|
type: object
|
|
required:
|
|
- agreements
|
|
- total
|
|
- page
|
|
- page_size
|
|
properties:
|
|
agreements:
|
|
type: array
|
|
maxItems: 100
|
|
items:
|
|
$ref: "#/components/schemas/EulaAgreement"
|
|
description: List of EULA agreements
|
|
total:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
description: Total number of agreements matching filter
|
|
example: 150
|
|
page:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 10000
|
|
description: Current page number
|
|
example: 1
|
|
page_size:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 100
|
|
description: Number of items per page
|
|
example: 20
|
|
has_more:
|
|
type: boolean
|
|
description: Whether more pages are available
|
|
example: true
|
|
|
|
EulaComplianceReport:
|
|
description: EULA compliance report with user agreement status
|
|
type: object
|
|
required:
|
|
- eulaVersion
|
|
- summary
|
|
- users
|
|
- pagination
|
|
properties:
|
|
eulaVersion:
|
|
$ref: "#/components/schemas/EulaVersionSummary"
|
|
summary:
|
|
$ref: "#/components/schemas/EulaComplianceSummary"
|
|
users:
|
|
type: array
|
|
maxItems: 100
|
|
items:
|
|
$ref: "#/components/schemas/EulaComplianceUser"
|
|
description: Unified list of users with agreement status
|
|
pagination:
|
|
$ref: "#/components/schemas/EulaCompliancePagination"
|
|
|
|
EulaComplianceSummary:
|
|
description: Summary statistics for compliance report
|
|
type: object
|
|
required:
|
|
- totalUsers
|
|
- agreedCount
|
|
- notAgreedCount
|
|
- compliancePercentage
|
|
properties:
|
|
totalUsers:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
description: Total number of users in the system
|
|
example: 150
|
|
agreedCount:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
description: Number of users who have agreed
|
|
example: 120
|
|
notAgreedCount:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
description: Number of users who have not agreed
|
|
example: 30
|
|
compliancePercentage:
|
|
type: number
|
|
format: float
|
|
minimum: 0
|
|
maximum: 100
|
|
description: Percentage of users who have agreed
|
|
example: 80.0
|
|
|
|
EulaComplianceUser:
|
|
description: User record in compliance report
|
|
type: object
|
|
required:
|
|
- cognitoSubjectId
|
|
- currentEmail
|
|
- agreed
|
|
properties:
|
|
cognitoSubjectId:
|
|
type: string
|
|
maxLength: 256
|
|
pattern: "^.+$"
|
|
description: User's Cognito subject ID
|
|
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
email:
|
|
type: string
|
|
maxLength: 320
|
|
nullable: true
|
|
description: User identifier at time of agreement (email, username, or subject ID; null if not agreed)
|
|
example: user@example.com
|
|
currentEmail:
|
|
type: string
|
|
maxLength: 320
|
|
description: User's current email from Cognito (may be empty or a non-email identifier)
|
|
example: user-updated@example.com
|
|
agreed:
|
|
type: boolean
|
|
description: Whether the user has agreed to this EULA version
|
|
example: true
|
|
agreedAt:
|
|
type: string
|
|
format: date-time
|
|
maxLength: 50
|
|
nullable: true
|
|
description: When the user agreed (null if not agreed)
|
|
example: "2026-01-15T10:30:00Z"
|
|
agreedFromIp:
|
|
type: string
|
|
maxLength: 45
|
|
nullable: true
|
|
description: IP address from which the user agreed (null if not agreed)
|
|
example: "192.168.1.100"
|
|
|
|
EulaCompliancePagination:
|
|
description: Pagination information for compliance report
|
|
type: object
|
|
required:
|
|
- page
|
|
- pageSize
|
|
- totalPages
|
|
- totalItems
|
|
properties:
|
|
page:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 10000
|
|
description: Current page number
|
|
example: 1
|
|
pageSize:
|
|
type: integer
|
|
format: int32
|
|
minimum: 1
|
|
maximum: 100
|
|
description: Number of items per page
|
|
example: 50
|
|
totalPages:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 10000
|
|
description: Total number of pages
|
|
example: 3
|
|
totalItems:
|
|
type: integer
|
|
format: int32
|
|
minimum: 0
|
|
maximum: 2147483647
|
|
description: Total number of items
|
|
example: 150
|
|
|
|
DeleteResponse:
|
|
description: Response for hard-delete operations when verbose=true
|
|
type: object
|
|
required:
|
|
- deletedDocuments
|
|
properties:
|
|
deletedDocuments:
|
|
type: array
|
|
description: S3 paths of orphaned source documents (only populated when verbose=true)
|
|
maxItems: 100000
|
|
items:
|
|
type: object
|
|
required:
|
|
- documentId
|
|
- s3Path
|
|
properties:
|
|
documentId:
|
|
type: string
|
|
format: uuid
|
|
maxLength: 36
|
|
description: ID of the deleted document
|
|
s3Path:
|
|
type: string
|
|
maxLength: 1024
|
|
description: Full S3 path (s3://bucket/key) of the orphaned source file
|