Files
query-orchestration/docs/ai.generated/03-api-documentation.md
T

1082 lines
26 KiB
Markdown
Raw Normal View History

# 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:
```bash
# 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:**
```json
{
"message": "rate limit exceeded"
}
```
---
## Client Management (ClientService)
### `POST /client`
Creates a new client in the system.
**Security**: Requires JWT authentication
**Request Body** (`ClientCreate`):
```json
{
"id": "string (max 36 chars, required)",
"name": "string (max 256 chars, required)"
}
```
**Responses**:
- `201`: Client created successfully
```json
{
"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`):
```json
{
"id": "AAA",
"name": "ACME Corporation",
"can_sync": true
}
```
### `PATCH /client/{id}`
Updates client information.
**Security**: Requires JWT authentication
**Request Body** (`ClientUpdate`):
```json
{
"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`):
```json
{
"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`):
```json
[
{
"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`):
```json
{
"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`):
```json
{
"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`):
```json
{
"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`):
```json
{
"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)
### `POST /folders`
Creates a new folder for organizing documents.
**Security**: Requires JWT authentication
**Request Body** (`FolderCreate`):
```json
{
"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`):
```json
{
"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`):
```json
{
"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**:
```json
{
"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`):
```json
{
"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`):
```json
{
"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`):
```json
{
"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**:
```json
{
"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**:
```json
{
"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`):
```json
{
"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`):
```json
{
"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**:
```json
{
"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"
}
]
}
```
---
## Query Management (QueryService)
### `GET /query`
Lists all available queries in the system.
**Security**: Requires JWT authentication
**Response** (`ListQueries`):
```json
{
"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`):
```json
{
"type": "JSON_EXTRACTOR",
"config": "{\"key\": \"value\"}",
"required_queries": ["019580df-ef65-7676-8de9-94435a93337b"]
}
```
**Response** (`201 Created`):
```json
{
"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`):
```json
{
"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`):
```json
{
"document_id": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
"query_version": 1
}
```
**Response** (`QueryTestResponse`):
```json
{
"value": "extracted result"
}
```
---
## Collector Configuration (CollectorService)
### `GET /client/{id}/collector`
Retrieves collector configuration for a client.
**Security**: Requires JWT authentication
**Response** (`Collector`):
```json
{
"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`):
```json
{
"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`):
```json
{
"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`):
```json
{
"id": "019580de-4d51-713c-98ee-464e83811f13"
}
```
### `GET /export/{id}`
Checks export status and retrieves download URL.
**Security**: Requires JWT authentication
**Response** (`ExportDetails`):
```json
{
"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`):
```json
{
"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):
```json
{
"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`):
```json
{
"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`):
```json
{
"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`):
```json
{
"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`):
```json
{
"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
```json
{
"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
---
## Code Generation
### OpenAPI Integration
The API is generated from the OpenAPI specification using:
```bash
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