72de690894
Chatbot functionality * baseline working * missing test file * more tests
7281 lines
219 KiB
YAML
7281 lines
219 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})
|
||
- name: SuperAdminSchemaService
|
||
description: |
|
||
Super-admin-only endpoints for managing client-scoped JSON Schemas
|
||
used to validate custom document metadata. All routes under this tag
|
||
require the super_admin Permit.io role; user_admin and below are
|
||
denied by the resource-action gate on the super-admin resource.
|
||
- name: CustomMetadataService
|
||
description: |
|
||
Read/write operations for a document's mutable custom metadata
|
||
payload. Available to client_user, user_admin, and super_admin
|
||
(auditor is read-only). Requires the owning document to first be
|
||
bound to a client_metadata_schemas row via PATCH
|
||
/super-admin/documents/{id}/schema.
|
||
- name: BotService
|
||
description: |
|
||
Owner-scoped chatbot session/scope/turn endpoints for client_user.
|
||
Sessions are visible only to their creator within a client.
|
||
Routes use the singular `/client/{clientId}/...` form per plan §3.
|
||
- name: SuperAdminBotService
|
||
description: |
|
||
Super-admin-only chatbot session endpoints. Lists, reads, and
|
||
soft-deletes bot sessions across all users within a client.
|
||
Restricted to the super_admin Permit.io role.
|
||
|
||
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"
|
||
|
||
/document/{id}/download:
|
||
parameters:
|
||
- $ref: "#/components/parameters/DocumentID"
|
||
get:
|
||
operationId: downloadDocument
|
||
tags:
|
||
- DocumentsService
|
||
summary: Download the original document file
|
||
description: |
|
||
Streams the original uploaded document file. The response Content-Type
|
||
is auto-detected from the stored filename extension. No query parameters
|
||
are required; the system resolves the file type automatically.
|
||
security:
|
||
- jwtAuth: []
|
||
responses:
|
||
"200":
|
||
description: Document file bytes.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
Content-Disposition:
|
||
schema:
|
||
type: string
|
||
maxLength: 4096
|
||
description: 'Attachment header with original filename, e.g. attachment; filename="report.pdf"'
|
||
content:
|
||
application/octet-stream:
|
||
schema:
|
||
type: string
|
||
format: binary
|
||
maxLength: 107374182400
|
||
"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"
|
||
|
||
/super-admin/custom-schemas:
|
||
post:
|
||
operationId: createCustomSchema
|
||
tags:
|
||
- SuperAdminSchemaService
|
||
summary: Create a custom metadata schema
|
||
description: >-
|
||
Creates a new client-scoped JSON Schema used to validate custom
|
||
document metadata. Restricted to the super_admin role.
|
||
security:
|
||
- jwtAuth: []
|
||
requestBody:
|
||
description: The schema to create
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CustomSchemaRequest"
|
||
responses:
|
||
"201":
|
||
description: Schema created successfully.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CustomSchemaResponse"
|
||
"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"
|
||
get:
|
||
operationId: listCustomSchemas
|
||
tags:
|
||
- SuperAdminSchemaService
|
||
summary: List custom metadata schemas for a client
|
||
description: >-
|
||
Lists client-scoped JSON Schemas. Supports filtering by name, status
|
||
and optional inclusion of all historical versions. Restricted to the
|
||
super_admin role.
|
||
security:
|
||
- jwtAuth: []
|
||
parameters:
|
||
- name: clientId
|
||
in: query
|
||
description: The client whose schemas to list.
|
||
required: true
|
||
schema:
|
||
type: string
|
||
maxLength: 36
|
||
- name: name
|
||
in: query
|
||
description: Filter by schema name (exact match).
|
||
required: false
|
||
schema:
|
||
type: string
|
||
maxLength: 255
|
||
- name: status
|
||
in: query
|
||
description: >-
|
||
Filter by lifecycle status. The sentinel `any` returns rows in
|
||
all statuses. Defaults to `active` when omitted.
|
||
required: false
|
||
schema:
|
||
type: string
|
||
enum:
|
||
- active
|
||
- superseded
|
||
- retired
|
||
- any
|
||
- name: includeAllVersions
|
||
in: query
|
||
description: >-
|
||
When false, return only the latest version per (clientId, name)
|
||
lineage. When true, return every version that matches the other
|
||
filters.
|
||
required: false
|
||
schema:
|
||
type: boolean
|
||
default: false
|
||
- name: limit
|
||
in: query
|
||
description: Maximum number of results to return.
|
||
required: false
|
||
schema:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 200
|
||
default: 50
|
||
- name: offset
|
||
in: query
|
||
description: Number of results to skip for pagination.
|
||
required: false
|
||
schema:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
maximum: 2147483647
|
||
default: 0
|
||
responses:
|
||
"200":
|
||
description: Schema list retrieved successfully.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CustomSchemaListResponse"
|
||
"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"
|
||
|
||
/super-admin/custom-schemas/{schemaId}:
|
||
parameters:
|
||
- name: schemaId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
description: The custom metadata schema ID.
|
||
get:
|
||
operationId: getCustomSchema
|
||
tags:
|
||
- SuperAdminSchemaService
|
||
summary: Get a custom metadata schema by ID
|
||
description: >-
|
||
Returns the full JSON Schema document plus lifecycle metadata for
|
||
the specified schema row. Restricted to the super_admin role.
|
||
security:
|
||
- jwtAuth: []
|
||
responses:
|
||
"200":
|
||
description: Schema retrieved successfully.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CustomSchemaResponse"
|
||
"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: deleteCustomSchema
|
||
tags:
|
||
- SuperAdminSchemaService
|
||
summary: Retire a custom metadata schema
|
||
description: >-
|
||
Marks the schema as retired. Fails with 409 Conflict if any document
|
||
still references the schema. Restricted to the super_admin role.
|
||
security:
|
||
- jwtAuth: []
|
||
responses:
|
||
"204":
|
||
description: Schema retired successfully.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
"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"
|
||
|
||
/super-admin/custom-schemas/{schemaId}/versions:
|
||
parameters:
|
||
- name: schemaId
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
description: The parent custom metadata schema ID whose lineage is being extended.
|
||
post:
|
||
operationId: createCustomSchemaVersion
|
||
tags:
|
||
- SuperAdminSchemaService
|
||
summary: Create a new version of a custom metadata schema
|
||
description: >-
|
||
Creates a new schema row with a new ID that inherits the parent
|
||
schema's clientId and name. The parent row must currently have
|
||
status=active; it is marked superseded in the same transaction.
|
||
Restricted to the super_admin role.
|
||
security:
|
||
- jwtAuth: []
|
||
requestBody:
|
||
description: The new schema version payload.
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CustomSchemaVersionRequest"
|
||
responses:
|
||
"201":
|
||
description: Schema version created successfully.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CustomSchemaResponse"
|
||
"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"
|
||
|
||
/super-admin/documents/{id}/schema:
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
description: The document ID whose schema binding is being mutated.
|
||
patch:
|
||
operationId: assignDocumentSchema
|
||
tags:
|
||
- SuperAdminSchemaService
|
||
summary: Assign (or clear) a custom schema for a document
|
||
description: >-
|
||
Binds a document to a client_metadata_schemas row, or clears the
|
||
binding when customSchemaId is null. The service layer enforces
|
||
every invariant from plan Section 7.3 before the UPDATE: document
|
||
must have no existing custom metadata, no legacy field extractions,
|
||
and the schema must belong to the same client. Restricted to the
|
||
super_admin role.
|
||
security:
|
||
- jwtAuth: []
|
||
requestBody:
|
||
description: The new schema binding.
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/DocumentSchemaAssignRequest"
|
||
responses:
|
||
"200":
|
||
description: Binding updated.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/DocumentSchemaAssignResponse"
|
||
"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"
|
||
|
||
/super-admin/documents/{id}/reset-metadata:
|
||
parameters:
|
||
- name: id
|
||
in: path
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
description: The document ID whose custom metadata is being reset.
|
||
post:
|
||
operationId: resetDocumentMetadata
|
||
tags:
|
||
- SuperAdminSchemaService
|
||
summary: Reset a document's custom metadata and schema binding
|
||
description: >-
|
||
Atomically deletes every document_custom_metadata row for the
|
||
document and nullifies documents.custom_schema_id in a single
|
||
transaction. Returns previous schema binding details and the
|
||
count of deleted metadata versions. Idempotent: already-clean
|
||
documents return 200 with metadataVersionsDeleted set to 0.
|
||
Rejects documents carrying legacy field extractions with 409.
|
||
Restricted to the super_admin role.
|
||
security:
|
||
- jwtAuth: []
|
||
responses:
|
||
"200":
|
||
description: Reset completed.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/DocumentMetadataResetResponse"
|
||
"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"
|
||
|
||
/custom-metadata:
|
||
get:
|
||
operationId: getCurrentCustomMetadata
|
||
tags:
|
||
- CustomMetadataService
|
||
summary: Get the current custom metadata row for a document
|
||
description: >-
|
||
Returns the most recent document_custom_metadata row for the
|
||
specified document, decorated with the bound schema id, name, and
|
||
version.
|
||
security:
|
||
- jwtAuth: []
|
||
parameters:
|
||
- name: documentId
|
||
in: query
|
||
required: true
|
||
description: The document whose current metadata is being requested.
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
responses:
|
||
"200":
|
||
description: Latest metadata row.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CustomMetadataResponse"
|
||
"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"
|
||
post:
|
||
operationId: setCustomMetadata
|
||
tags:
|
||
- CustomMetadataService
|
||
summary: Write a new custom metadata version for a document
|
||
description: >-
|
||
Validates the supplied metadata payload against the document's
|
||
bound schema and appends a new version row. The actor is derived
|
||
from the JWT sub claim; the request body has no createdBy field.
|
||
security:
|
||
- jwtAuth: []
|
||
requestBody:
|
||
description: Metadata payload + the target document id.
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CustomMetadataRequest"
|
||
responses:
|
||
"201":
|
||
description: Metadata version written.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CustomMetadataResponse"
|
||
"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"
|
||
|
||
/custom-metadata/version:
|
||
get:
|
||
operationId: getCustomMetadataByVersion
|
||
tags:
|
||
- CustomMetadataService
|
||
summary: Get a specific historical metadata version
|
||
description: >-
|
||
Returns the metadata row whose version matches the query parameter,
|
||
decorated with schema id/name/version. Returns 404 when the row
|
||
does not exist and 400 when version is less than 1.
|
||
security:
|
||
- jwtAuth: []
|
||
parameters:
|
||
- name: documentId
|
||
in: query
|
||
required: true
|
||
description: The document whose historical metadata version is being requested.
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
- name: version
|
||
in: query
|
||
required: true
|
||
description: The metadata version number (>= 1) to return.
|
||
schema:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 2147483647
|
||
responses:
|
||
"200":
|
||
description: Metadata row at the requested version.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CustomMetadataResponse"
|
||
"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"
|
||
|
||
/custom-metadata/history:
|
||
get:
|
||
operationId: getCustomMetadataHistory
|
||
tags:
|
||
- CustomMetadataService
|
||
summary: List version summaries for a document's metadata
|
||
description: >-
|
||
Returns a paged list of (version, createdAt, createdBy) tuples in
|
||
descending version order. limit must be in [1, 200]; values above
|
||
200 are clamped. offset must be >= 0.
|
||
security:
|
||
- jwtAuth: []
|
||
parameters:
|
||
- name: documentId
|
||
in: query
|
||
required: true
|
||
description: The document whose metadata history is being requested.
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
- name: limit
|
||
in: query
|
||
required: false
|
||
description: Maximum number of version summaries to return per page (1-200, default 50).
|
||
schema:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 200
|
||
default: 50
|
||
- name: offset
|
||
in: query
|
||
required: false
|
||
description: Number of version summaries to skip before the page starts (default 0).
|
||
schema:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
maximum: 2147483647
|
||
default: 0
|
||
responses:
|
||
"200":
|
||
description: Version summaries in descending version order.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CustomMetadataHistoryResponse"
|
||
"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"
|
||
|
||
/client/{clientId}/bot/sessions:
|
||
parameters:
|
||
- $ref: "#/components/parameters/BotClientID"
|
||
post:
|
||
operationId: createBotSession
|
||
tags:
|
||
- BotService
|
||
summary: Create a new chatbot session
|
||
description: >-
|
||
Creates an owner-scoped chatbot session for the authenticated
|
||
client_user. The Cognito subject (JWT sub) becomes createdBy.
|
||
Title defaults to empty until the first turn arrives.
|
||
security:
|
||
- jwtAuth: []
|
||
requestBody:
|
||
description: Empty body — accepted for forward compatibility.
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CreateBotSessionRequest"
|
||
responses:
|
||
"201":
|
||
description: Session created.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BotSessionResponse"
|
||
"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: listBotSessions
|
||
tags:
|
||
- BotService
|
||
summary: List the caller's chatbot sessions for a client
|
||
description: >-
|
||
Returns sessions owned by the authenticated user under this
|
||
clientId, newest-updated first. Each session carries a recentTurns
|
||
preview whose length is min(request.limit, cfg.RecentTurns)
|
||
per plan §3. Plan §3 bounds: limit in [1, 200] and offset >= 0.
|
||
security:
|
||
- jwtAuth: []
|
||
parameters:
|
||
- name: limit
|
||
in: query
|
||
required: false
|
||
description: Maximum number of sessions to return (1-200, default 20).
|
||
schema:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 200
|
||
default: 20
|
||
- name: offset
|
||
in: query
|
||
required: false
|
||
description: Number of sessions to skip for pagination (default 0).
|
||
schema:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
maximum: 2147483647
|
||
default: 0
|
||
responses:
|
||
"200":
|
||
description: Session list with embedded recent-turn previews.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BotSessionListResponse"
|
||
"400":
|
||
$ref: "#/components/responses/InvalidRequest"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"429":
|
||
$ref: "#/components/responses/TooManyRequests"
|
||
"500":
|
||
$ref: "#/components/responses/InternalError"
|
||
|
||
/client/{clientId}/bot/sessions/{sessionId}:
|
||
parameters:
|
||
- $ref: "#/components/parameters/BotClientID"
|
||
- $ref: "#/components/parameters/BotSessionID"
|
||
get:
|
||
operationId: getBotSession
|
||
tags:
|
||
- BotService
|
||
summary: Get one chatbot session by id
|
||
description: >-
|
||
Owner-scoped read. Returns 404 when the session belongs to a
|
||
different client, a different user, or has been soft-deleted.
|
||
security:
|
||
- jwtAuth: []
|
||
responses:
|
||
"200":
|
||
description: Session details.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BotSessionResponse"
|
||
"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/{clientId}/bot/sessions/{sessionId}/turns:
|
||
parameters:
|
||
- $ref: "#/components/parameters/BotClientID"
|
||
- $ref: "#/components/parameters/BotSessionID"
|
||
post:
|
||
operationId: createBotTurn
|
||
tags:
|
||
- BotService
|
||
summary: Submit a new chatbot turn
|
||
description: >-
|
||
Posts a new turn to the chatbot session. Plan §6 algorithm: tx1
|
||
locks the session, abandons grace-expired in_flight rows, and
|
||
either inserts a fresh in_flight row at the next ordinal or
|
||
resets a terminal-failure row for retry. The FastAPI agent is
|
||
called outside any DB transaction, then tx2 records the
|
||
outcome via compare-and-set on attempt_id. Returns 201 on
|
||
success with the persisted turn body. FastAPI failures persist
|
||
an errored row and return 502 with the error body.
|
||
security:
|
||
- jwtAuth: []
|
||
requestBody:
|
||
description: Prompt to submit.
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/CreateBotTurnRequest"
|
||
responses:
|
||
"201":
|
||
description: Turn completed.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BotTurnResponse"
|
||
"400":
|
||
$ref: "#/components/responses/InvalidRequest"
|
||
"401":
|
||
$ref: "#/components/responses/Unauthorized"
|
||
"404":
|
||
$ref: "#/components/responses/NotFound"
|
||
"409":
|
||
$ref: "#/components/responses/Conflict"
|
||
"410":
|
||
description: Session was deleted while the agent call was in flight.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ErrorMessage"
|
||
"429":
|
||
$ref: "#/components/responses/TooManyRequests"
|
||
"500":
|
||
$ref: "#/components/responses/InternalError"
|
||
"502":
|
||
description: FastAPI agent failed; persisted errored row in body.
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/ErrorMessage"
|
||
get:
|
||
operationId: listBotTurns
|
||
tags:
|
||
- BotService
|
||
summary: List all turns for a chatbot session
|
||
description: >-
|
||
Returns every persisted turn for the owner-scoped session,
|
||
ordered ASC by ordinal. Plan §11.
|
||
security:
|
||
- jwtAuth: []
|
||
responses:
|
||
"200":
|
||
description: Ordered list of turns.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BotTurnListResponse"
|
||
"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/{clientId}/bot/sessions/{sessionId}/scope:
|
||
parameters:
|
||
- $ref: "#/components/parameters/BotClientID"
|
||
- $ref: "#/components/parameters/BotSessionID"
|
||
patch:
|
||
operationId: patchBotSessionScope
|
||
tags:
|
||
- BotService
|
||
summary: Patch a session's document/folder scope
|
||
description: >-
|
||
Adds or removes documents and folders from a session's scope.
|
||
Duplicate ids inside add/remove are deduplicated. An id appearing
|
||
in both add and remove returns 400 add_remove_conflict. A document
|
||
or folder belonging to a different client returns 400
|
||
document_cross_client / folder_cross_client. The persisted scope
|
||
is the union of (existing - remove) ∪ add.
|
||
security:
|
||
- jwtAuth: []
|
||
requestBody:
|
||
description: Add/remove sets for documents and folders.
|
||
required: true
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BotSessionScopePatchRequest"
|
||
responses:
|
||
"200":
|
||
description: Updated session, including the new scope.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BotSessionResponse"
|
||
"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/{clientId}/documents/{documentId}/schema:
|
||
parameters:
|
||
- $ref: "#/components/parameters/BotClientID"
|
||
- $ref: "#/components/parameters/M5DocumentID"
|
||
get:
|
||
operationId: getDocumentSchema
|
||
tags:
|
||
- BotService
|
||
summary: Get the bound custom schema for a document
|
||
description: >-
|
||
Returns the JSON Schema body bound to the document via
|
||
documents.custom_schema_id. The composite FK in migration 128
|
||
guarantees the schema row's client_id matches the document's
|
||
clientId, so the M1 GetDocumentEnrichedForClient query is
|
||
sufficient for cross-client rejection. When the document has no
|
||
schema bound, the endpoint returns 200 with `schema: null`. Plan
|
||
§3 + §10 M5.
|
||
security:
|
||
- jwtAuth: []
|
||
responses:
|
||
"200":
|
||
description: Schema body or null when unbound.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/DocumentSchemaResponse"
|
||
"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/{clientId}/documents/{documentId}/all-metadata:
|
||
parameters:
|
||
- $ref: "#/components/parameters/BotClientID"
|
||
- $ref: "#/components/parameters/M5DocumentID"
|
||
get:
|
||
operationId: getDocumentAllMetadata
|
||
tags:
|
||
- BotService
|
||
summary: Get document metadata bundle (document + labels + customMetadata)
|
||
description: >-
|
||
Composes three M1 client-scoped reads
|
||
(GetDocumentEnrichedForClient, GetDocumentLabelsForClient,
|
||
GetCurrentDocumentCustomMetadataForClient) into a single bundle
|
||
for the chatbot UI. labels is always a non-null array; when the
|
||
document has no schema bound or no metadata rows, customMetadata
|
||
is null. Plan §3 + §10 M5.
|
||
security:
|
||
- jwtAuth: []
|
||
responses:
|
||
"200":
|
||
description: Document, labels, and customMetadata.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/DocumentAllMetadataResponse"
|
||
"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"
|
||
|
||
/super-admin/bot/sessions:
|
||
get:
|
||
operationId: listBotSessionsAsSuperAdmin
|
||
tags:
|
||
- SuperAdminBotService
|
||
summary: List chatbot sessions for a client (super-admin)
|
||
description: >-
|
||
Super-admin client-scoped list. Filters on clientId and
|
||
is_deleted=false; no created_by predicate. limit in [1, 200],
|
||
offset >= 0.
|
||
security:
|
||
- jwtAuth: []
|
||
parameters:
|
||
- name: clientId
|
||
in: query
|
||
required: true
|
||
description: The client whose sessions to list.
|
||
schema:
|
||
type: string
|
||
maxLength: 255
|
||
- name: limit
|
||
in: query
|
||
required: false
|
||
description: Maximum number of sessions to return (1-200, default 20).
|
||
schema:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 200
|
||
default: 20
|
||
- name: offset
|
||
in: query
|
||
required: false
|
||
description: Number of sessions to skip for pagination (default 0).
|
||
schema:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
maximum: 2147483647
|
||
default: 0
|
||
responses:
|
||
"200":
|
||
description: Session list across all users in the client.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BotSessionListResponse"
|
||
"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"
|
||
|
||
/super-admin/bot/sessions/{sessionId}:
|
||
parameters:
|
||
- $ref: "#/components/parameters/BotSessionID"
|
||
get:
|
||
operationId: getBotSessionAsSuperAdmin
|
||
tags:
|
||
- SuperAdminBotService
|
||
summary: Get one chatbot session by id (super-admin)
|
||
description: >-
|
||
Super-admin read. Filters on clientId (query param) and
|
||
is_deleted=false. Returns 404 when the session does not match.
|
||
security:
|
||
- jwtAuth: []
|
||
parameters:
|
||
- name: clientId
|
||
in: query
|
||
required: true
|
||
description: The client that owns the session.
|
||
schema:
|
||
type: string
|
||
maxLength: 255
|
||
responses:
|
||
"200":
|
||
description: Session details.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
content:
|
||
application/json:
|
||
schema:
|
||
$ref: "#/components/schemas/BotSessionResponse"
|
||
"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: deleteBotSessionAsSuperAdmin
|
||
tags:
|
||
- SuperAdminBotService
|
||
summary: Soft-delete a chatbot session (super-admin)
|
||
description: >-
|
||
Sets is_deleted=true on the session. Any in-flight turns on the
|
||
session transition to status='session_deleted' so the M4 AddTurn
|
||
tx2 callback finds a terminal row.
|
||
security:
|
||
- jwtAuth: []
|
||
parameters:
|
||
- name: clientId
|
||
in: query
|
||
required: true
|
||
description: The client that owns the session.
|
||
schema:
|
||
type: string
|
||
maxLength: 255
|
||
responses:
|
||
"204":
|
||
description: Session soft-deleted.
|
||
headers:
|
||
RateLimit:
|
||
$ref: "#/components/headers/RateLimit"
|
||
"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.
|
||
|
||
BotClientID:
|
||
in: path
|
||
name: clientId
|
||
required: true
|
||
schema:
|
||
type: string
|
||
maxLength: 255
|
||
description: The owning client ID for chatbot routes.
|
||
|
||
BotSessionID:
|
||
in: path
|
||
name: sessionId
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
description: The chatbot session ID.
|
||
|
||
M5DocumentID:
|
||
in: path
|
||
name: documentId
|
||
required: true
|
||
schema:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
description: The document ID for the M5 schema/all-metadata routes.
|
||
|
||
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)"
|
||
customSchemaId:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
description: >-
|
||
Mutable-metadata feature: the client_metadata_schemas row id
|
||
this document is currently bound to, or null when the document
|
||
has not been opted in to the custom schema system. A document
|
||
with a non-null customSchemaId rejects legacy field extraction
|
||
writes.
|
||
hasCustomMetadata:
|
||
type: boolean
|
||
description: >-
|
||
True iff at least one document_custom_metadata row exists for
|
||
this document. A document can have customSchemaId set but
|
||
hasCustomMetadata false (schema bound, no metadata written
|
||
yet).
|
||
|
||
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)"
|
||
|
||
SchemaStatus:
|
||
type: string
|
||
enum:
|
||
- active
|
||
- superseded
|
||
- retired
|
||
description: |
|
||
Lifecycle state of a client_metadata_schemas row. `active` is
|
||
the version currently assignable to new documents. `superseded`
|
||
is automatically set when a newer version of the same (clientId,
|
||
name) lineage is created via POST /versions. `retired` is set
|
||
when a super_admin explicitly deletes an unused schema.
|
||
|
||
CustomSchemaRequest:
|
||
description: >-
|
||
Request body for creating a new custom metadata schema. Does not
|
||
include a createdBy field; the handler derives the actor from the
|
||
authenticated JWT subject.
|
||
type: object
|
||
required:
|
||
- clientId
|
||
- name
|
||
- schema
|
||
properties:
|
||
clientId:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 36
|
||
description: The client that owns this schema.
|
||
name:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 255
|
||
description: Unique schema name within the client lineage.
|
||
description:
|
||
type: string
|
||
maxLength: 1024
|
||
description: Optional human-readable description of the schema.
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
maxProperties: 1024
|
||
description: >-
|
||
The full JSON Schema document (Draft 2020-12) used to validate
|
||
custom document metadata. Must declare root type=object and
|
||
must explicitly set additionalProperties. The maxProperties cap
|
||
is a defense-in-depth limit against malformed schema payloads;
|
||
the byte-level cap (65 536) lives in the customschema validator.
|
||
|
||
CustomSchemaVersionRequest:
|
||
description: >-
|
||
Request body for creating a new version of an existing custom
|
||
metadata schema. The parent schema row supplies clientId and name;
|
||
the actor is derived from the authenticated JWT subject.
|
||
type: object
|
||
required:
|
||
- schema
|
||
properties:
|
||
description:
|
||
type: string
|
||
maxLength: 1024
|
||
description: Optional human-readable description of this new version.
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
maxProperties: 1024
|
||
description: >-
|
||
The full JSON Schema document (Draft 2020-12) for the new
|
||
version. Same validation rules as CustomSchemaRequest.schema.
|
||
|
||
CustomSchemaResponse:
|
||
description: >-
|
||
Full custom metadata schema row including the JSON Schema document
|
||
and lifecycle metadata.
|
||
type: object
|
||
required:
|
||
- id
|
||
- clientId
|
||
- name
|
||
- schema
|
||
- version
|
||
- status
|
||
- documentCount
|
||
- canDelete
|
||
- createdAt
|
||
- createdBy
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
description: The schema row ID.
|
||
clientId:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 36
|
||
description: The client that owns this schema.
|
||
name:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 255
|
||
description: The schema name (shared across versions in a lineage).
|
||
description:
|
||
type: string
|
||
maxLength: 1024
|
||
description: Optional human-readable description of the schema.
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
maxProperties: 1024
|
||
description: The full JSON Schema document (Draft 2020-12).
|
||
version:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 2147483647
|
||
description: Monotonic version number within the (clientId, name) lineage.
|
||
status:
|
||
$ref: "#/components/schemas/SchemaStatus"
|
||
documentCount:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
maximum: 2147483647
|
||
description: Number of documents currently referencing this schema version.
|
||
canDelete:
|
||
type: boolean
|
||
description: True when documentCount is zero and the schema can be retired.
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
maxLength: 64
|
||
description: Timestamp when this schema row was created.
|
||
createdBy:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 255
|
||
description: >-
|
||
Cognito subject ID (JWT sub claim) of the caller. Opaque UUID,
|
||
not an email.
|
||
example: "b7a4c1d2-8e3f-4a5b-9c6d-0e1f2a3b4c5d"
|
||
|
||
CustomSchemaListResponse:
|
||
description: >-
|
||
List of custom metadata schemas for a client. Each row omits the
|
||
full JSON Schema document; use GET /super-admin/custom-schemas/
|
||
{schemaId} to retrieve it.
|
||
type: object
|
||
required:
|
||
- schemas
|
||
properties:
|
||
schemas:
|
||
type: array
|
||
maxItems: 200
|
||
description: The schema rows matching the query filters.
|
||
items:
|
||
type: object
|
||
required:
|
||
- id
|
||
- clientId
|
||
- name
|
||
- version
|
||
- status
|
||
- documentCount
|
||
- canDelete
|
||
- createdAt
|
||
- createdBy
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
description: The schema row ID.
|
||
clientId:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 36
|
||
description: The client that owns this schema.
|
||
name:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 255
|
||
description: The schema name (shared across versions in a lineage).
|
||
description:
|
||
type: string
|
||
maxLength: 1024
|
||
description: Optional human-readable description of the schema.
|
||
version:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 2147483647
|
||
description: Monotonic version number within the lineage.
|
||
status:
|
||
$ref: "#/components/schemas/SchemaStatus"
|
||
documentCount:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
maximum: 2147483647
|
||
description: Number of documents referencing this schema version.
|
||
canDelete:
|
||
type: boolean
|
||
description: True when documentCount is zero.
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
maxLength: 64
|
||
description: Timestamp when this schema row was created.
|
||
createdBy:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 255
|
||
description: >-
|
||
Cognito subject ID (JWT sub claim) of the caller. Opaque
|
||
UUID, not an email.
|
||
example: "b7a4c1d2-8e3f-4a5b-9c6d-0e1f2a3b4c5d"
|
||
|
||
DocumentSchemaAssignRequest:
|
||
description: >-
|
||
Request body for PATCH /super-admin/documents/{id}/schema. The
|
||
actor is derived from the JWT sub claim; the body has no createdBy
|
||
field. A null customSchemaId clears the binding.
|
||
type: object
|
||
properties:
|
||
customSchemaId:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
nullable: true
|
||
description: The client_metadata_schemas row id to bind, or null to clear.
|
||
|
||
DocumentSchemaAssignResponse:
|
||
description: >-
|
||
Result of a schema binding mutation. Returns the bound schema
|
||
metadata (or nulls when cleared).
|
||
type: object
|
||
required:
|
||
- documentId
|
||
properties:
|
||
documentId:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
customSchemaId:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
nullable: true
|
||
schemaName:
|
||
type: string
|
||
maxLength: 255
|
||
nullable: true
|
||
schemaVersion:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 2147483647
|
||
nullable: true
|
||
|
||
DocumentMetadataResetResponse:
|
||
description: >-
|
||
Result of a reset-metadata operation. The previous* fields
|
||
describe the document's schema binding before the reset ran so
|
||
the caller can log or display what was wiped. Fields are null
|
||
when the document had no schema bound at reset time (the
|
||
idempotent no-op case, returned alongside
|
||
metadataVersionsDeleted set to 0).
|
||
type: object
|
||
required:
|
||
- documentId
|
||
- previousSchemaId
|
||
- previousSchemaName
|
||
- previousSchemaVersion
|
||
- metadataVersionsDeleted
|
||
- resetAt
|
||
- resetBy
|
||
properties:
|
||
documentId:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
description: The document whose metadata was reset.
|
||
previousSchemaId:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
nullable: true
|
||
description: >-
|
||
The document's custom_schema_id before the reset ran.
|
||
Null when no schema was bound.
|
||
previousSchemaName:
|
||
type: string
|
||
maxLength: 255
|
||
nullable: true
|
||
description: >-
|
||
Name of the previously bound schema, or null when no schema
|
||
was bound.
|
||
previousSchemaVersion:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 2147483647
|
||
nullable: true
|
||
description: >-
|
||
Version of the previously bound schema row, or null when no
|
||
schema was bound.
|
||
metadataVersionsDeleted:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
maximum: 2147483647
|
||
description: >-
|
||
Number of document_custom_metadata rows that existed (and
|
||
were deleted) at reset time. Zero is valid: the reset
|
||
endpoint is idempotent on already-clean documents.
|
||
resetAt:
|
||
type: string
|
||
format: date-time
|
||
maxLength: 64
|
||
description: UTC timestamp when the reset completed.
|
||
resetBy:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 255
|
||
description: >-
|
||
Cognito subject ID (JWT sub claim) of the caller. Opaque
|
||
UUID, not an email.
|
||
example: "b7a4c1d2-8e3f-4a5b-9c6d-0e1f2a3b4c5d"
|
||
|
||
CustomMetadataRequest:
|
||
description: >-
|
||
POST /custom-metadata body. No createdBy field — the actor is
|
||
derived from the JWT sub claim.
|
||
type: object
|
||
required:
|
||
- documentId
|
||
- metadata
|
||
properties:
|
||
documentId:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
metadata:
|
||
type: object
|
||
additionalProperties: true
|
||
maxProperties: 1024
|
||
description: >-
|
||
Arbitrary JSON object that must conform to the document's
|
||
bound schema_def. The byte-level cap (1 048 576) lives in the
|
||
service layer constant MaxMetadataPayloadBytes.
|
||
|
||
CustomMetadataResponse:
|
||
description: >-
|
||
Full metadata row decorated with the document's bound schema id,
|
||
name, and version.
|
||
type: object
|
||
required:
|
||
- id
|
||
- documentId
|
||
- metadata
|
||
- version
|
||
- createdAt
|
||
- createdBy
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
documentId:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
metadata:
|
||
type: object
|
||
additionalProperties: true
|
||
maxProperties: 1024
|
||
version:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 2147483647
|
||
schemaId:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
nullable: true
|
||
schemaName:
|
||
type: string
|
||
maxLength: 255
|
||
nullable: true
|
||
schemaVersion:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 2147483647
|
||
nullable: true
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
maxLength: 64
|
||
createdBy:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 255
|
||
description: Cognito subject ID (JWT sub claim) of the writer.
|
||
example: "b7a4c1d2-8e3f-4a5b-9c6d-0e1f2a3b4c5d"
|
||
|
||
CustomMetadataHistoryResponse:
|
||
description: Paged list of version summaries, newest first.
|
||
type: object
|
||
required:
|
||
- versions
|
||
properties:
|
||
versions:
|
||
type: array
|
||
maxItems: 200
|
||
items:
|
||
type: object
|
||
required:
|
||
- version
|
||
- createdAt
|
||
- createdBy
|
||
properties:
|
||
version:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 2147483647
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
maxLength: 64
|
||
createdBy:
|
||
type: string
|
||
minLength: 1
|
||
maxLength: 255
|
||
example: "b7a4c1d2-8e3f-4a5b-9c6d-0e1f2a3b4c5d"
|
||
|
||
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
|
||
|
||
# ---------- Bot (chatbot) M2 schemas ----------
|
||
|
||
BotSessionScope:
|
||
description: |
|
||
The persisted document/folder scope of a chatbot session.
|
||
Empty arrays mean "all documents for the client" per plan §4.
|
||
Folder ids are returned as-is; folder expansion to documents
|
||
happens only in the M3 FastAPI payload assembly path, not here.
|
||
type: object
|
||
required:
|
||
- documentIds
|
||
- folderIds
|
||
properties:
|
||
documentIds:
|
||
type: array
|
||
maxItems: 10000
|
||
items:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
description: Document ids in the session scope.
|
||
folderIds:
|
||
type: array
|
||
maxItems: 10000
|
||
items:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
description: Folder ids in the session scope.
|
||
|
||
BotTurnPreview:
|
||
description: |
|
||
A single turn surfaced inside a session list response. M2 returns
|
||
only the columns the UI needs to render preview cards: ordinal,
|
||
prompt, optional completion, status, createdAt. Plan §5
|
||
ListLastTurnsForSessions returns the full row column set; the
|
||
response trims it to the preview view here.
|
||
type: object
|
||
required:
|
||
- ordinal
|
||
- prompt
|
||
- status
|
||
- createdAt
|
||
properties:
|
||
ordinal:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 2147483647
|
||
description: 1-based turn ordinal within the session.
|
||
prompt:
|
||
type: string
|
||
maxLength: 65536
|
||
description: User prompt text.
|
||
completion:
|
||
type: string
|
||
maxLength: 65536
|
||
nullable: true
|
||
description: Assistant completion (markdown) when status=completed.
|
||
status:
|
||
type: string
|
||
enum:
|
||
- in_flight
|
||
- completed
|
||
- errored
|
||
- abandoned
|
||
- session_deleted
|
||
description: Turn status per plan §4.
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
maxLength: 50
|
||
description: When the turn was inserted.
|
||
|
||
BotSessionResponse:
|
||
description: |
|
||
The canonical chatbot session entity. Used as the response body
|
||
for create / get / patch and as the element type of the list
|
||
response. lastTurn is the derived last_terminal_ordinal from
|
||
plan §4 — never the in-flight ordinal.
|
||
type: object
|
||
required:
|
||
- id
|
||
- clientId
|
||
- createdBy
|
||
- title
|
||
- state
|
||
- lastTurn
|
||
- createdAt
|
||
- updatedAt
|
||
- scope
|
||
- recentTurns
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
clientId:
|
||
type: string
|
||
maxLength: 255
|
||
createdBy:
|
||
type: string
|
||
maxLength: 255
|
||
description: Cognito subject (JWT sub) of the creator.
|
||
title:
|
||
type: string
|
||
maxLength: 255
|
||
description: Empty until the first turn arrives (plan §6).
|
||
state:
|
||
type: object
|
||
additionalProperties: true
|
||
maxProperties: 1024
|
||
description: Session state object persisted as jsonb.
|
||
lastTurn:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
maximum: 2147483647
|
||
description: |
|
||
Derived last_terminal_ordinal per plan §4. 0 when the session
|
||
has no terminal turns yet.
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
maxLength: 50
|
||
updatedAt:
|
||
type: string
|
||
format: date-time
|
||
maxLength: 50
|
||
scope:
|
||
$ref: "#/components/schemas/BotSessionScope"
|
||
recentTurns:
|
||
type: array
|
||
maxItems: 5
|
||
description: |
|
||
Most recent terminal turns. Populated by the list endpoint
|
||
with min(request.limit, cfg.RecentTurns) entries per plan §3.
|
||
Single-session reads (GET / POST / PATCH) emit an empty array.
|
||
items:
|
||
$ref: "#/components/schemas/BotTurnPreview"
|
||
|
||
BotSessionListResponse:
|
||
description: Paged list of chatbot sessions.
|
||
type: object
|
||
required:
|
||
- sessions
|
||
properties:
|
||
sessions:
|
||
type: array
|
||
maxItems: 200
|
||
items:
|
||
$ref: "#/components/schemas/BotSessionResponse"
|
||
|
||
CreateBotSessionRequest:
|
||
description: |
|
||
Empty body for now — accepted as JSON object to leave room for
|
||
future fields (title hint, initial scope) without a breaking
|
||
change. M2 ignores any properties the caller supplies.
|
||
type: object
|
||
additionalProperties: true
|
||
maxProperties: 32
|
||
|
||
BotSessionScopePatchRequest:
|
||
description: |
|
||
Add/remove sets for documents and folders. Each array is
|
||
deduplicated server-side. An id appearing in both add and remove
|
||
sets is rejected with 400 add_remove_conflict. Cross-client ids
|
||
are rejected with 400 document_cross_client / folder_cross_client.
|
||
type: object
|
||
properties:
|
||
addDocuments:
|
||
type: array
|
||
maxItems: 10000
|
||
items:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
removeDocuments:
|
||
type: array
|
||
maxItems: 10000
|
||
items:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
addFolders:
|
||
type: array
|
||
maxItems: 10000
|
||
items:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
removeFolders:
|
||
type: array
|
||
maxItems: 10000
|
||
items:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
|
||
# ---------- M4: bot turn schemas ----------
|
||
|
||
CreateBotTurnRequest:
|
||
description: |
|
||
Body for POST /client/{clientId}/bot/sessions/{sessionId}/turns.
|
||
The handler computes the target ordinal from session state via
|
||
prompt-match semantics (a retry of an existing terminal-failure
|
||
or completed turn reuses that row's ordinal). The wire body
|
||
therefore carries only the prompt; plan §6.
|
||
type: object
|
||
required:
|
||
- prompt
|
||
properties:
|
||
prompt:
|
||
type: string
|
||
maxLength: 65536
|
||
description: User prompt. Plan §6 mandates 1 <= rune count <= MaxTurnChars.
|
||
|
||
BotTurnResponse:
|
||
description: |
|
||
One persisted bot_turns row exposed on the wire. Status enum
|
||
mirrors the bot_turns_status_values CHECK constraint from
|
||
migration 131. error is the persisted JSON when status is
|
||
errored / abandoned / session_deleted, omitted otherwise.
|
||
type: object
|
||
required:
|
||
- ordinal
|
||
- prompt
|
||
- status
|
||
- createdAt
|
||
properties:
|
||
ordinal:
|
||
type: integer
|
||
format: int32
|
||
minimum: 1
|
||
maximum: 2147483647
|
||
prompt:
|
||
type: string
|
||
maxLength: 65536
|
||
completion:
|
||
type: string
|
||
maxLength: 65536
|
||
status:
|
||
type: string
|
||
enum:
|
||
- completed
|
||
- errored
|
||
- abandoned
|
||
- session_deleted
|
||
- in_flight
|
||
latencyMs:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
maximum: 2147483647
|
||
tokensIn:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
maximum: 2147483647
|
||
tokensOut:
|
||
type: integer
|
||
format: int32
|
||
minimum: 0
|
||
maximum: 2147483647
|
||
error:
|
||
type: object
|
||
additionalProperties: true
|
||
maxProperties: 32
|
||
createdAt:
|
||
type: string
|
||
format: date-time
|
||
maxLength: 50
|
||
|
||
BotTurnListResponse:
|
||
description: |
|
||
GET turns response. Turns are ordered ASC by ordinal.
|
||
type: object
|
||
required:
|
||
- turns
|
||
properties:
|
||
turns:
|
||
type: array
|
||
maxItems: 10000
|
||
items:
|
||
$ref: "#/components/schemas/BotTurnResponse"
|
||
|
||
# ---------- M5: read-only document endpoints ----------
|
||
|
||
DocumentSchemaResponse:
|
||
description: |
|
||
Body returned by GET /client/{clientId}/documents/{documentId}/schema.
|
||
schema is the JSON Schema body bound to the document, or null
|
||
when the document has no custom_schema_id binding. The
|
||
clientId / documentId echo the URL parameters so the caller can
|
||
reuse the response without parsing the path.
|
||
type: object
|
||
required:
|
||
- documentId
|
||
- clientId
|
||
properties:
|
||
documentId:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
clientId:
|
||
type: string
|
||
maxLength: 255
|
||
schema:
|
||
type: object
|
||
additionalProperties: true
|
||
maxProperties: 1024
|
||
description: |
|
||
JSON Schema body, or null when the document has no schema
|
||
bound. The body round-trips verbatim from
|
||
client_metadata_schemas.schema_def.
|
||
|
||
DocumentAllMetadataResponse:
|
||
description: |
|
||
Bundle returned by GET /client/{clientId}/documents/{documentId}/all-metadata.
|
||
document is the M1 enriched-document shape; labels is always a
|
||
non-null array (empty when no labels are applied); customMetadata
|
||
is null when no schema is bound or no metadata rows exist.
|
||
type: object
|
||
required:
|
||
- document
|
||
- labels
|
||
properties:
|
||
document:
|
||
$ref: "#/components/schemas/DocumentEnriched"
|
||
labels:
|
||
type: array
|
||
maxItems: 10000
|
||
items:
|
||
$ref: "#/components/schemas/BotLabelRecord"
|
||
customMetadata:
|
||
type: object
|
||
additionalProperties: true
|
||
maxProperties: 1024
|
||
description: |
|
||
Latest custom metadata payload for the document, or null
|
||
when no schema is bound / no metadata rows exist.
|
||
|
||
BotLabelRecord:
|
||
description: |
|
||
Label record exposed by the M5 all-metadata endpoint. Mirrors
|
||
LabelRecord but treats appliedBy as a plain string so the
|
||
bundle survives non-email AppliedBy values (the underlying
|
||
documentLabels.appliedBy is varchar(255), not email-validated
|
||
at the database layer).
|
||
type: object
|
||
required:
|
||
- id
|
||
- documentId
|
||
- label
|
||
- appliedBy
|
||
- appliedAt
|
||
properties:
|
||
id:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
documentId:
|
||
type: string
|
||
format: uuid
|
||
maxLength: 36
|
||
label:
|
||
type: string
|
||
maxLength: 255
|
||
appliedBy:
|
||
type: string
|
||
maxLength: 320
|
||
appliedAt:
|
||
type: string
|
||
format: date-time
|
||
maxLength: 50
|