Files
query-orchestration/docs/ai.generated/03-api-documentation.md
T
Jay Brown a94637ab13 Merged in feature/fix_test_timeouts (pull request #194)
text extractions tests

* increase timeout

for slow ci/cd systems

* add tests
2025-12-04 22:45:15 +00:00

38 KiB

API Documentation

API Overview

The DoczyAI Query Orchestration Platform exposes a comprehensive REST API following OpenAPI 3.0.3 specification. The API is automatically generated from the specification file serviceAPIs/queryAPI.yaml using oapi-codegen.

Base Configuration

  • Base URL: https://doczy.com/v1 (production), http://localhost:8080 (development)
  • API Version: 0.0.1
  • Content Type: application/json
  • Documentation: Auto-generated Swagger UI at /swagger/index.html

API Services

The API is organized into the following service groups:

Service Description
ClientService Operations related to clients
CollectorService Operations related to collectors
DocumentsService Operations related to documents
FolderService Operations related to document folders and organization
LabelService Operations related to document labels and workflow tracking
FieldExtractionService Operations related to document field extractions
QueryService Operations related to queries
ExportService Operations related to exports
AuthService Operations related to authentication
AdminService Operations related to user management and administration

Authentication and Authorization

Security Schemes

JWT Authentication

  • Type: Bearer token authentication
  • Header: Authorization: Bearer <token>
  • Token Source: JWT cookie set via OAuth flow

OAuth2 Flow

  • Type: OAuth2 Authorization Code Flow
  • Provider: AWS Cognito
  • Scopes: openid, email, profile

Authentication Endpoints

GET /login

Initiates OAuth2 authentication flow with AWS Cognito.

Security: Public (no authentication required) Response: 302 Redirect to Cognito login page

GET /login-callback

OAuth2 callback handler that processes authentication response.

Security: Public Parameters:

  • code (query, required): Authorization code from Cognito (max 2048 chars)
  • state (query, required): CSRF protection parameter (max 1024 chars)

Response: 302 Sets JWT cookie and redirects to application

GET /logout

Terminates user session and clears authentication cookies.

Security: Requires JWT authentication Response: 302 Redirect to Cognito logout page or application home

GET /home

Returns the HTML menu page for authenticated users.

Security: Requires JWT authentication Response: 200 HTML content

Rate Limiting

The queryAPI service implements dual-layer rate limiting to protect against DDoS attacks and ensure fair resource allocation.

Rate Limit Architecture

Dual-Layer Protection:

  • Layer 1: Global/Aggregate Rate Limiting - Protects total system capacity across all IP addresses
  • Layer 2: Per-IP Rate Limiting - Prevents individual client abuse

Both layers must pass for a request to proceed. The global limiter checks first for faster failure paths under DDoS conditions.

Default Rate Limits

By default, all endpoints are limited to:

  • Global: 500 requests per second total (1000 burst)
  • Per-IP: 5 requests per second per IP (10 burst)
  • Cleanup Interval: 3 minutes for inactive IP limiters

Important: No endpoints are exempt from rate limiting. This is a security requirement to prevent DDoS attacks.

Configuration

Rate limits are configured via environment variables:

# Global/Aggregate rate limiting (protects total system capacity)
RATE_LIMIT_GLOBAL_RATE=500         # total req/s across ALL IPs
RATE_LIMIT_GLOBAL_BURST=1000        # total burst capacity across ALL IPs

# Per-IP rate limiting (protects against individual abusers)
RATE_LIMIT_DEFAULT_RATE=5          # req/s per IP
RATE_LIMIT_DEFAULT_BURST=10         # burst per IP
RATE_LIMIT_EXPIRES_IN=180           # seconds (3 minutes)

# Per-endpoint overrides (JSON format)
RATE_LIMIT_ENDPOINT_OVERRIDES={}

Rate Limit Headers

All API responses include a RateLimit header indicating the current limit:

RateLimit: 20;window=2

Format: {burst};window={seconds}

Rate Limit Exceeded Response

HTTP Status: 429 Too Many Requests

Headers:

  • Retry-After: {seconds} - Number of seconds before retrying
  • RateLimit: {burst};window={seconds} - Current rate limit

Response Body:

{
  "message": "rate limit exceeded"
}

Client Management (ClientService)

POST /client

Creates a new client in the system.

Security: Requires JWT authentication

Request Body (ClientCreate):

{
  "id": "string (max 36 chars, required)",
  "name": "string (max 256 chars, required)"
}

Responses:

  • 201: Client created successfully
    {
      "id": "AAA"
    }
    
  • 400: Invalid request data
  • 401: Authentication required
  • 429: Rate limit exceeded
  • 500: Internal server error

GET /client/{id}

Retrieves client details by ID.

Security: Requires JWT authentication

Path Parameters:

  • id: Client identifier (string, max 36 chars)

Response (DocClient):

{
  "id": "AAA",
  "name": "ACME Corporation",
  "can_sync": true
}

PATCH /client/{id}

Updates client information.

Security: Requires JWT authentication

Request Body (ClientUpdate):

{
  "name": "string (max 256 chars, optional)",
  "can_sync": "boolean (optional)"
}

Response: 200 Client updated successfully

GET /client/{id}/status

Returns client synchronization status.

Security: Requires JWT authentication

Response (ClientStatusBody):

{
  "status": "IN_SYNC"
}

Status Values: IN_SYNC, NOT_SYNCED, NOT_SYNCING


Document Operations (DocumentsService)

POST /client/{id}/document

Uploads a document for a specific client.

Security: Requires JWT authentication Content Type: multipart/form-data Max File Size: 100GB

Form Parameters:

  • file (required): Document file (PDF)
  • filename (optional): Custom filename (max 4096 chars)

Response: 200 Document uploaded

GET /client/{id}/document

Lists documents for a client.

Security: Requires JWT authentication

Response (ListDocuments):

[
  {
    "id": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
    "hash": "sha256:abc123..."
  }
]

GET /document/{id}

Retrieves document details by ID.

Security: Requires JWT authentication

Path Parameters:

  • id: Document UUID (max 36 chars)

Response (Document):

{
  "id": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
  "client_id": "AAA",
  "hash": "sha256:abc123...",
  "fields": {
    "property1": "string value",
    "property2": 42
  }
}

Batch Document Operations (DocumentsService)

POST /client/{id}/document/batch

Uploads a ZIP archive containing multiple PDF documents for asynchronous batch processing.

Security: Requires JWT authentication Content Type: multipart/form-data Max Archive Size: 1GB Supported Archive Type: ZIP only

Form Parameters:

  • archive (required): ZIP file containing PDF documents

Response (202 Accepted):

{
  "batch_id": "019580df-ef65-7676-8de9-94435a93337a",
  "status": "processing",
  "status_url": "/client/AAA/document/batch/019580df-ef65-7676-8de9-94435a93337a"
}

GET /client/{id}/document/batch

Lists batch uploads for a client with pagination support.

Security: Requires JWT authentication

Query Parameters:

  • limit: Maximum results (integer, 1-100, default: 20)
  • offset: Pagination offset (integer, default: 0)

Response (BatchUploadList):

{
  "batches": [
    {
      "batch_id": "019580df-ef65-7676-8de9-94435a93337a",
      "client_id": "AAA",
      "original_filename": "documents.zip",
      "status": "completed",
      "total_documents": 100,
      "processed_documents": 100,
      "failed_documents": 2,
      "invalid_type_documents": 1,
      "progress_percent": 100,
      "created_at": "2024-01-01T00:00:00Z",
      "completed_at": "2024-01-01T00:05:00Z"
    }
  ],
  "total_count": 25
}

Batch Status Values: processing, completed, failed, cancelled

GET /client/{id}/document/batch/{batch_id}

Retrieves detailed status information for a specific batch upload.

Security: Requires JWT authentication

Path Parameters:

  • batch_id: Batch upload identifier (UUID)

Response (BatchUploadDetails):

{
  "batch_id": "019580df-ef65-7676-8de9-94435a93337a",
  "client_id": "AAA",
  "original_filename": "documents.zip",
  "status": "completed",
  "total_documents": 100,
  "processed_documents": 100,
  "failed_documents": 2,
  "invalid_type_documents": 1,
  "progress_percent": 100,
  "created_at": "2024-01-01T00:00:00Z",
  "completed_at": "2024-01-01T00:05:00Z",
  "failed_filenames": ["doc3.pdf", "doc17.pdf"]
}

DELETE /client/{id}/document/batch/{batch_id}

Cancels a batch upload that is currently processing.

Security: Requires JWT authentication

Response:

  • 204: Batch upload cancelled successfully
  • 404: Batch not found

Folder Operations (FolderService)

Folder Path Constraints

All folder paths must comply with the following constraints when creating or renaming folders:

  • Must start with /: All paths must begin with a forward slash
  • Maximum path length: 1000 characters
  • Maximum segment length: 255 characters per path segment
  • Maximum depth: 20 levels of nesting
  • Valid characters only: Alphanumeric (a-z, A-Z, 0-9), hyphen (-), underscore (_), period (.), and space ( )
  • Segment must start with alphanumeric: Each path segment must begin with a letter or number
  • No empty segments: Double slashes (//) or trailing slashes are not allowed
  • No path traversal: Sequences like .. or ./ are blocked
  • No hidden folders: Segments cannot start with a period (e.g., /.hidden)
  • No leading/trailing whitespace: Spaces within segment names are allowed, but not at the start or end
  • No control characters: ASCII control characters (0x00-0x1F, 0x7F) are blocked
  • No Windows reserved names: Names like CON, PRN, AUX, NUL, COM1-COM9, LPT1-LPT9 are blocked
  • Root folder restrictions: The root path / can only exist once per client and cannot be renamed
  • Path uniqueness: Each path must be unique within a client (enforced by database)
  • Unicode normalization: Paths are normalized to NFC form

Valid path examples:

  • /documents
  • /documents/2024/Q1
  • /client-data/reports_2024
  • /My Documents/Archive

Invalid path examples:

  • documents (missing leading /)
  • /documents/ (trailing slash)
  • /foo//bar (empty segment)
  • /foo/../bar (path traversal)
  • /.hidden (dot prefix)
  • /foo@bar (invalid character)
  • /CON (Windows reserved name)

GET /clients/{clientId}/folders

Lists all folders for a specific client, including the folder hierarchy.

Security: Requires JWT authentication

Path Parameters:

  • clientId: Client external ID (string, max 36 chars)

Response (200 OK):

{
  "folders": [
    {
      "id": "019580df-ef65-7676-8de9-94435a93337a",
      "path": "/",
      "parentId": null,
      "clientId": "AAA",
      "createdAt": "2025-10-16T14:27:15Z",
      "createdBy": "system"
    },
    {
      "id": "019580df-ef65-7676-8de9-94435a93337b",
      "path": "/documents",
      "parentId": "019580df-ef65-7676-8de9-94435a93337a",
      "clientId": "AAA",
      "createdAt": "2025-10-16T14:30:00Z",
      "createdBy": "user@example.com"
    },
    {
      "id": "019580df-ef65-7676-8de9-94435a93337c",
      "path": "/documents/2024",
      "parentId": "019580df-ef65-7676-8de9-94435a93337b",
      "clientId": "AAA",
      "createdAt": "2025-10-16T14:35:00Z",
      "createdBy": "user@example.com"
    }
  ]
}

Notes:

  • Returns all folders for the client, including nested folders
  • Folders are returned in a flat list; use parentId to reconstruct the hierarchy
  • The root folder (path="/") is included if it exists

POST /folders

Creates a new folder for organizing documents.

Security: Requires JWT authentication

Request Body (FolderCreate):

{
  "path": "/documents/2024",
  "clientId": "AAA",
  "createdBy": "user@example.com",
  "parentId": "019580df-ef65-7676-8de9-94435a93337a"
}
Field Type Required Description
path string Yes Folder path, must start with "/" (max 1000 chars)
clientId string Yes Client external ID
createdBy string Yes Email of user creating the folder
parentId uuid No Parent folder ID for nested folders

Response (201 Created):

{
  "id": "019580df-ef65-7676-8de9-94435a93337a",
  "path": "/documents/2024",
  "parentId": null,
  "clientId": "AAA",
  "createdAt": "2025-10-16T14:27:15Z",
  "createdBy": "user@example.com"
}

PATCH /folders/{folderId}

Renames an existing folder.

Security: Requires JWT authentication

Path Parameters:

  • folderId: Folder UUID

Request Body (FolderRename):

{
  "path": "/documents/2024-renamed"
}

Response (200 OK): Updated folder object

GET /folders/{folderId}/documents

Retrieves all documents within a specific folder.

Security: Requires JWT authentication

Response:

{
  "documents": [
    {
      "id": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
      "client_id": "AAA",
      "hash": "sha256:abc123...",
      "fields": {}
    }
  ]
}

GET /folders/{folderId}/metrics

Retrieves processing progress metrics for documents in a folder.

Security: Requires JWT authentication

Response (FolderMetrics):

{
  "folderId": "019580df-ef65-7676-8de9-94435a93337a",
  "totalDocuments": 150,
  "byLabel": {
    "Ingested": 150,
    "OCR_Processed": 120,
    "Dashboard_Ready": 100
  }
}

Label Operations (LabelService)

POST /documents/{documentId}/labels

Applies a workflow label to a document for tracking processing state.

Security: Requires JWT authentication

Path Parameters:

  • documentId: Document UUID

Request Body (LabelApplication):

{
  "label": "OCR_Processed",
  "appliedBy": "user@example.com"
}
Field Type Required Description
label string Yes Label name (alphanumeric and underscore only, max 100 chars)
appliedBy string Yes Email of user applying the label

Response (201 Created):

{
  "id": "019580df-ef65-7676-8de9-94435a93337a",
  "documentId": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
  "label": "OCR_Processed",
  "appliedBy": "user@example.com",
  "appliedAt": "2025-10-16T14:27:15Z"
}

GET /documents/{documentId}/labels

Retrieves all labels that have been applied to a document, ordered by most recent first.

Security: Requires JWT authentication

Response:

{
  "labels": [
    {
      "id": "019580df-ef65-7676-8de9-94435a93337a",
      "documentId": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
      "label": "OCR_Processed",
      "appliedBy": "user@example.com",
      "appliedAt": "2025-10-16T14:27:15Z"
    }
  ]
}

GET /labels/{labelName}/documents

Retrieves all documents that have been tagged with a specific label.

Security: Requires JWT authentication

Path Parameters:

  • labelName: Label name (alphanumeric and underscore only, max 100 chars)

Query Parameters:

  • clientId (required): Client ID to filter documents (UUID)

Response:

{
  "documents": [
    {
      "id": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
      "hash": "sha256:abc123..."
    }
  ]
}

Field Extraction Operations (FieldExtractionService)

POST /field-extractions

Creates a new field extraction with single-value and array fields for a document.

Security: Requires JWT authentication

Request Body (FieldExtractionRequest):

{
  "documentId": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
  "singleFields": {
    "fileName": "contract_2024.pdf",
    "contractTitle": "Service Agreement",
    "clientName": "ACME Corp",
    "payerName": "Insurance Co",
    "payerState": "CA",
    "providerState": "NY",
    "aareteDerivedEffectiveDt": "2024-01-01",
    "aareteDerivedTerminationDt": "2025-12-31",
    "autoRenewalInd": true
  },
  "arrayFields": [
    {
      "exhibitTitle": "Exhibit A",
      "exhibitPage": "15",
      "reimbProvTin": "123456789",
      "reimbProvNpi": "1234567890",
      "reimbProvName": "Provider Name",
      "reimbEffectiveDt": "2024-01-01",
      "aareteDerivedClaimTypeCd": "INPATIENT",
      "aareteDerivedReimbMethod": "Per Diem",
      "reimbPctRate": 85.5,
      "reimbFeeRate": 150.00
    }
  ],
  "createdBy": "user@example.com"
}

Single Fields (1:1 relationship with document):

  • fileName, contractTitle, clientName, payerName
  • payerState, providerState (2-letter state codes)
  • filenameTin, provGroupTin, provGroupNpi, provGroupNameFull
  • provOtherTin, provOtherNpi, provOtherNameFull
  • aareteDerivedEffectiveDt, aareteDerivedTerminationDt (dates)
  • aareteDerivedAmendmentNum (integer)
  • autoRenewalInd (boolean), autoRenewalTerm

Array Fields (1:N relationship - multiple rows per document):

  • Provider info: reimbProvTin, reimbProvNpi, reimbProvName
  • Dates: reimbEffectiveDt, reimbTerminationDt
  • Classifications: aareteDerivedClaimTypeCd, aareteDerivedProduct, aareteDerivedLob, aareteDerivedProgram, aareteDerivedNetwork, aareteDerivedProvType
  • Codes: provTaxonomyCd, provSpecialtyCd, placeOfServiceCd, billTypeCd, cpt4ProcCd, revenueCd, diagCd, ndcCd
  • Rates: reimbPctRate, reimbFeeRate, reimbConversionFactor, grouperPctRate, grouperBaseRate
  • Indicators: carveoutInd, lesserOfInd, greaterOfInd, defaultInd

Response (201 Created):

{
  "id": "019580df-ef65-7676-8de9-94435a93337a",
  "documentId": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
  "version": 1,
  "singleFields": { ... },
  "arrayFields": [ ... ],
  "createdAt": "2025-10-16T14:27:15Z",
  "createdBy": "user@example.com"
}

GET /field-extractions

Retrieves the most recent field extraction for a document.

Security: Requires JWT authentication

Query Parameters:

  • documentId (required): Document UUID

Response: FieldExtractionResponse (same as POST response)

GET /field-extractions/history

Retrieves all versions of field extractions for a document, ordered by most recent first.

Security: Requires JWT authentication

Query Parameters:

  • documentId (required): Document UUID

Response:

{
  "versions": [
    {
      "id": "019580df-ef65-7676-8de9-94435a93337a",
      "documentId": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
      "version": 2,
      "createdAt": "2025-10-17T10:00:00Z",
      "createdBy": "user@example.com"
    },
    {
      "id": "019580df-ef65-7676-8de9-94435a93337b",
      "documentId": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
      "version": 1,
      "createdAt": "2025-10-16T14:27:15Z",
      "createdBy": "user@example.com"
    }
  ]
}

GET /field-extractions/version

Retrieves a specific version of a field extraction for a document by version number.

Security: Requires JWT authentication

Query Parameters:

  • documentId (required): Document UUID
  • version (required): Version number (integer, minimum 1)

Response (200 OK):

{
  "id": "019580df-ef65-7676-8de9-94435a93337a",
  "documentId": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
  "version": 1,
  "singleFields": {
    "fileName": "contract_2024.pdf",
    "contractTitle": "Service Agreement",
    "clientName": "ACME Corp"
  },
  "arrayFields": [],
  "createdAt": "2025-10-16T14:27:15Z",
  "createdBy": "user@example.com"
}

Error Responses:

  • 400: Missing required query parameters
  • 404: Version not found for the specified document

Query Management (QueryService)

GET /query

Lists all available queries in the system.

Security: Requires JWT authentication

Response (ListQueries):

{
  "queries": [
    {
      "id": "019580df-ef65-7676-8de9-94435a93337a",
      "type": "JSON_EXTRACTOR",
      "active_version": 1,
      "latest_version": 2,
      "config": "{...}",
      "required_queries": ["019580df-ef65-7676-8de9-94435a93337b"]
    }
  ]
}

Query Types: JSON_EXTRACTOR, CONTEXT_FULL

POST /query

Creates a new query definition.

Security: Requires JWT authentication

Request Body (QueryCreate):

{
  "type": "JSON_EXTRACTOR",
  "config": "{\"key\": \"value\"}",
  "required_queries": ["019580df-ef65-7676-8de9-94435a93337b"]
}

Response (201 Created):

{
  "id": "019580df-ef65-7676-8de9-94435a93337a"
}

GET /query/{id}

Retrieves query details including configuration.

Security: Requires JWT authentication

Response: Query object

PATCH /query/{id}

Updates query definition.

Security: Requires JWT authentication

Request Body (QueryUpdate):

{
  "config": "{\"updated\": true}",
  "active_version": 2,
  "required_queries": []
}

POST /query/{id}/test

Tests query execution against a document.

Security: Requires JWT authentication

Request Body (QueryTestRequest):

{
  "document_id": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
  "query_version": 1
}

Response (QueryTestResponse):

{
  "value": "extracted result"
}

Collector Configuration (CollectorService)

GET /client/{id}/collector

Retrieves collector configuration for a client.

Security: Requires JWT authentication

Response (Collector):

{
  "client_id": "AAA",
  "active_version": 1,
  "latest_version": 2,
  "minimum_cleaner_version": 1,
  "minimum_text_version": 1,
  "fields": [
    {
      "name": "contract_date",
      "query_id": "019580df-ef65-7676-8de9-94435a93337a"
    }
  ]
}

PATCH /client/{id}/collector

Updates collector configuration.

Security: Requires JWT authentication

Request Body (CollectorSet):

{
  "minimum_cleaner_version": 2,
  "minimum_text_version": 2,
  "active_version": 1,
  "fields": [
    {
      "name": "contract_date",
      "query_id": "019580df-ef65-7676-8de9-94435a93337a"
    }
  ]
}

Response: 204 Collector set successfully


Export Operations (ExportService)

POST /client/{id}/export

Triggers data export for a client.

Security: Requires JWT authentication

Request Body (ExportTrigger):

{
  "ingestion_filters": {
    "start_date": "2024-01-01T00:00:00Z",
    "end_date": "2024-12-31T23:59:59Z"
  },
  "field_filters": [
    {
      "field_name": "contract_type",
      "condition": "include",
      "values": ["SERVICE", "PRODUCT"]
    }
  ]
}

Filter Conditions: less_than, greater_than, closed_interval, open_interval, left_closed_interval, right_closed_interval, include, exclude

Response (201 Created):

{
  "id": "019580de-4d51-713c-98ee-464e83811f13"
}

GET /export/{id}

Checks export status and retrieves download URL.

Security: Requires JWT authentication

Response (ExportDetails):

{
  "client_id": "AAA",
  "status": "completed",
  "output_location": "s3://bucket/AAA/export/20250213/uuid.csv"
}

Export Status Values: completed, in_progress, failed


User Administration (AdminService)

POST /admin/users

Creates a new user in both AWS Cognito and Permit.io systems with optional role assignments.

Security: Requires JWT authentication

Creation Flow:

  1. User is created in AWS Cognito (primary authentication system)
  2. If Cognito creation fails, operation fails with HTTP 502
  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)

Request Body (AdminUserCreate):

{
  "email": "john.doe@example.com",
  "first_name": "John",
  "last_name": "Doe",
  "roles": ["user_admin", "auditor"]
}
Field Type Required Description
email string Yes User email address (max 320 chars)
first_name string Yes User's given name (max 100 chars)
last_name string Yes User's family name (max 100 chars)
roles array Yes List of role keys to assign (1-50 roles)

Response (201 Created or 200 OK if user exists):

{
  "cognito_subject_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "email": "john.doe@example.com",
  "first_name": "John",
  "last_name": "Doe",
  "status": "FORCE_CHANGE_PASSWORD",
  "enabled": true,
  "permit_synced": true,
  "roles_assigned": ["user_admin", "auditor"],
  "created_at": "2025-10-16T14:23:45Z"
}

Error Responses:

  • 400: Invalid request data
  • 401: Authentication required
  • 403: Insufficient permissions
  • 409: User already exists with different attributes
  • 429: Rate limit exceeded
  • 502: External service (Cognito) error

GET /admin/users

Lists users from AWS Cognito with pagination, filtering, and sorting support.

Security: Requires JWT authentication

Query Parameters:

Parameter Type Default Description
page integer 1 Page number (1-10000)
page_size integer 50 Results per page (1-100)
search string - Search term for email/name filtering
status string all Filter by status: enabled, disabled, all
sort_by string email Sort field: email, created_at, last_name
sort_order string asc Sort direction: asc, desc

Response (AdminUserList):

{
  "users": [
    {
      "cognito_subject_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "email": "john.doe@example.com",
      "first_name": "John",
      "last_name": "Doe",
      "status": "CONFIRMED",
      "enabled": true,
      "roles": ["admin", "viewer"],
      "created_at": "2025-10-15T09:15:30Z",
      "updated_at": "2025-10-16T14:20:10Z"
    }
  ],
  "total": 147,
  "page": 1,
  "page_size": 50,
  "has_more": true
}

GET /admin/users/{email}

Retrieves user details from both AWS Cognito and Permit.io by email address.

Security: Requires JWT authentication

Path Parameters:

  • email: URL-encoded user email address (max 320 chars)

Response (AdminUserDetails): Same structure as user list item

HEAD /admin/users/{email}

Checks if a user exists in Cognito and/or Permit.io without returning full details.

Security: Requires JWT authentication

Response Headers:

  • X-User-Exists-Cognito: boolean
  • X-User-Exists-PermitIO: boolean

Response:

  • 200: User exists (at least in one system)
  • 404: User does not exist in either system

PATCH /admin/users/{email}

Updates user attributes (first_name, last_name) in Cognito and manages role assignments in Permit.io.

Security: Requires JWT authentication

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

Request Body (AdminUserUpdate):

{
  "first_name": "Jonathan",
  "last_name": "Doe-Smith",
  "roles": ["user_admin", "auditor"]
}

Response (200 OK): Updated AdminUserDetails

DELETE /admin/users/{email}

Permanently deletes a user from both AWS Cognito and Permit.io. This operation is irreversible.

Security: Requires JWT authentication

Query Parameters:

  • confirm (required): Must be true to confirm deletion

Response (200 OK or 207 Multi-Status):

{
  "success": true,
  "email": "john.doe@example.com",
  "cognito_subject_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "deleted_from": {
    "cognito": true,
    "permit": true
  },
  "timestamp": "2025-10-16T14:27:15Z"
}

POST /admin/users/{email}/disable

Disables a user in AWS Cognito, preventing authentication. User data and roles are preserved. Idempotent.

Security: Requires JWT authentication

Response (AdminUserActionResponse):

{
  "success": true,
  "email": "john.doe@example.com",
  "action": "disable",
  "cognito_subject_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "timestamp": "2025-10-16T14:25:33Z"
}

POST /admin/users/{email}/enable

Re-enables a previously disabled user in AWS Cognito. Restores authentication capability. Idempotent.

Security: Requires JWT authentication

Response: Same as disable endpoint with "action": "enable"


Request/Response Schemas

Standard Response Headers

All API responses include:

  • RateLimit: Current rate limit status (format: 100;window=60)
  • Content-Type: application/json (except file downloads and HTML pages)

Error Response Format

{
  "message": "Error description (max 256 chars)"
}

Common HTTP Status Codes

Code Description
200 Success
201 Created
202 Accepted (async processing)
204 No Content (success with no body)
207 Multi-Status (partial success)
302 Redirect
400 Bad Request (validation errors)
401 Unauthorized (authentication required)
403 Forbidden (insufficient permissions)
404 Not Found
409 Conflict (resource exists or state conflict)
429 Too Many Requests (rate limited)
500 Internal Server Error
502 Bad Gateway (external service error)

API Versioning

Current Strategy

  • URL-based versioning: /v1 prefix
  • Backward Compatibility: Maintained within major versions
  • OpenAPI Version: 0.0.1 (development phase)

Future Considerations

  • Semantic versioning for production releases
  • Deprecation notices for breaking changes
  • Version sunset policies

Authorization Reference (Permit.io Integration)

The API uses Permit.io for fine-grained authorization. This section documents what data is sent to Permit.io for each endpoint, enabling system administrators to configure the correct resources, actions, and roles in Permit.io.

Authorization Flow

  1. Authentication: User authenticates via AWS Cognito, receiving a JWT token
  2. User Identification: The sub (subject) claim from the JWT is extracted as the user identifier
  3. Resource Mapping: The first path segment of the URL becomes the resource (e.g., /client/{id}/documentclient)
  4. Action Mapping: The HTTP method is converted to lowercase to become the action (e.g., GETget)
  5. Permission Check: Permit.io checks if the user has permission to perform the action on the resource

Permit.io Data Mapping Logic

Resource Extraction (from internal/cognitoauth/mapping.go):

  • The resource is derived from the first segment of the URL path
  • Leading slashes are removed
  • Example: /client/{id}/document/batch/{batch_id} → resource: client

Action Extraction:

  • HTTP method is converted to lowercase
  • GETget, POSTpost, PATCHpatch, DELETEdelete, HEADhead

Endpoints Exempt from Authorization

The following endpoints skip authentication and Permit.io authorization entirely:

Endpoint Purpose
GET /home Public home/menu page
GET /logout Session termination
GET /health Health check endpoint
GET /swagger/* Swagger UI documentation
GET /metrics Prometheus metrics

Special Authentication Endpoints

These endpoints handle authentication flows and bypass normal authorization:

Endpoint Purpose
GET /login Initiates OAuth2/PKCE login flow with Cognito
GET /login-callback Handles OAuth2 callback from Cognito

Authorization Reference Table

The following table shows what data is passed to Permit.io for each protected endpoint:

HTTP Method Endpoint Resource Action Notes
Client Management
POST /client client post Create new client
GET /clients clients get List all clients
GET /client/{id} client get Get client details
PATCH /client/{id} client patch Update client
GET /client/{id}/status client get Get client sync status
Document Operations
POST /client/{id}/document client post Upload document
GET /client/{id}/document client get List client documents
GET /document/{id} document get Get document details
Batch Document Operations
POST /client/{id}/document/batch client post Upload batch (ZIP)
GET /client/{id}/document/batch client get List batch uploads
GET /client/{id}/document/batch/{batch_id} client get Get batch status
DELETE /client/{id}/document/batch/{batch_id} client delete Cancel batch upload
Folder Operations
GET /client/{id}/folders client get List client folders
POST /folders folders post Create folder
PATCH /folders/{folderId} folders patch Rename folder
GET /folders/{folderId}/documents folders get List folder documents
GET /folders/{folderId}/metrics folders get Get folder metrics
Label Operations
POST /documents/{documentId}/labels documents post Apply label to document
GET /documents/{documentId}/labels documents get Get document labels
GET /labels/{labelName}/documents labels get Get documents by label
Field Extraction Operations
POST /field-extractions field-extractions post Create field extraction
GET /field-extractions field-extractions get Get latest extraction
GET /field-extractions/version field-extractions get Get specific version
GET /field-extractions/history field-extractions get Get extraction history
Query Management
GET /query query get List queries
POST /query query post Create query
GET /query/{id} query get Get query details
PATCH /query/{id} query patch Update query
POST /query/{id}/test query post Test query execution
Collector Configuration
GET /client/{id}/collector client get Get collector config
PATCH /client/{id}/collector client patch Update collector config
Export Operations
POST /client/{id}/export client post Trigger export
GET /export/{id} export get Get export status
User Administration
POST /admin/users admin post Create user
GET /admin/users admin get List users
GET /admin/users/{email} admin get Get user details
HEAD /admin/users/{email} admin head Check user existence
PATCH /admin/users/{email} admin patch Update user
DELETE /admin/users/{email} admin delete Delete user
POST /admin/users/{email}/disable admin post Disable user
POST /admin/users/{email}/enable admin post Enable user

Permit.io Configuration Requirements

To configure Permit.io to work with this API, administrators must create:

Resources

Resource Key Description
client Client management and client-scoped operations
clients Client listing (plural form)
document Individual document operations
documents Document collection and label operations
folders Folder management
labels Label-based document queries
field-extractions Field extraction operations
query Query definition management
export Export operations
admin User administration

Actions

Action Key HTTP Method Description
get GET Read/retrieve resources
post POST Create resources
patch PATCH Update resources
delete DELETE Delete resources
head HEAD Check resource existence

Example Role Configuration

Typical role assignments for common personas:

Role Resources Actions Use Case
viewer client, clients, document, documents, folders, query, export get Read-only access
editor client, document, documents, folders, field-extractions, query get, post, patch Content management
admin All resources All actions Full administrative access
user_admin admin All actions User management only

Authorization Error Responses

When authorization fails, the API returns:

HTTP 401 Unauthorized - No valid JWT token:

{
  "error": "Authorization required",
  "message": "This endpoint requires authentication. Please obtain a valid JWT token.",
  "login_url": "/login"
}

HTTP 403 Forbidden - Insufficient permissions:

{
  "error": "Insufficient permissions",
  "message": "Access denied by authorization service",
  "user": "<cognito-subject-id>",
  "resource": "<resource-name>",
  "action": "<action-name>"
}

Code Generation

OpenAPI Integration

The API is generated from the OpenAPI specification using:

oapi-codegen -generate "types,server" -o api.gen.go serviceAPIs/queryAPI.yaml

Generated Artifacts

  • Type-safe Go structs for requests/responses
  • Echo framework route handlers
  • OpenAPI validation middleware
  • Swagger documentation

Validation

  • Automatic request validation against OpenAPI schema
  • Response validation in development mode
  • Parameter binding with type safety