2025-06-24 19:56:56 +00:00
# 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`
2025-11-26 19:23:42 +00:00
### 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 |
2025-06-24 19:56:56 +00:00
## 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
2025-11-26 19:23:42 +00:00
- **Scopes**: `openid` , `email` , `profile`
2025-06-24 19:56:56 +00:00
### Authentication Endpoints
#### `GET /login`
Initiates OAuth2 authentication flow with AWS Cognito.
2025-11-26 19:23:42 +00:00
**Security ** : Public (no authentication required)
**Response ** : `302` Redirect to Cognito login page
2025-06-24 19:56:56 +00:00
#### `GET /login-callback`
OAuth2 callback handler that processes authentication response.
2025-11-26 19:23:42 +00:00
**Security ** : Public
2025-06-24 19:56:56 +00:00
**Parameters ** :
2025-11-26 19:23:42 +00:00
- `code` (query, required): Authorization code from Cognito (max 2048 chars)
- `state` (query, required): CSRF protection parameter (max 1024 chars)
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**Response ** : `302` Sets JWT cookie and redirects to application
2025-06-24 19:56:56 +00:00
#### `GET /logout`
Terminates user session and clears authentication cookies.
2025-11-26 19:23:42 +00:00
**Security ** : Requires JWT authentication
**Response ** : `302` Redirect to Cognito logout page or application home
2025-06-24 19:56:56 +00:00
#### `GET /home`
2025-11-26 19:23:42 +00:00
Returns the HTML menu page for authenticated users.
**Security ** : Requires JWT authentication
**Response ** : `200` HTML content
2025-06-24 19:56:56 +00:00
2025-10-13 22:13:15 +00:00
## 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 = { }
```
2025-11-26 19:23:42 +00:00
### Rate Limit Headers
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
All API responses include a `RateLimit` header indicating the current limit:
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
```
RateLimit: 20;window=2
```
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Format: ** `{burst};window={seconds}`
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
### Rate Limit Exceeded Response
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**HTTP Status: ** `429 Too Many Requests`
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Headers: **
- `Retry-After: {seconds}` - Number of seconds before retrying
- `RateLimit: {burst};window={seconds}` - Current rate limit
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Response Body: **
2025-10-13 22:13:15 +00:00
``` json
{
2025-11-26 19:23:42 +00:00
"message" : "rate limit exceeded"
2025-10-13 22:13:15 +00:00
}
```
2025-11-26 19:23:42 +00:00
---
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
## Client Management (ClientService)
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
### `POST /client`
Creates a new client in the system.
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Security ** : Requires JWT authentication
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Request Body ** (`ClientCreate` ):
2025-10-13 22:13:15 +00:00
``` json
{
2025-11-26 19:23:42 +00:00
"id" : "string (max 36 chars, required)" ,
"name" : "string (max 256 chars, required)"
2025-10-13 22:13:15 +00:00
}
```
2025-11-26 19:23:42 +00:00
**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`):
2025-10-13 22:13:15 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"id": "AAA",
"name": "ACME Corporation",
"can_sync": true
2025-10-13 22:13:15 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
### ` PATCH /client/{id}`
Updates client information.
**Security**: Requires JWT authentication
**Request Body** (` ClientUpdate`):
2025-10-13 22:13:15 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"name": "string (max 256 chars, optional)",
"can_sync": "boolean (optional)"
2025-10-13 22:13:15 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
**Response**: ` 200` Client updated successfully
### ` GET /client/{id}/status`
Returns client synchronization status.
**Security**: Requires JWT authentication
**Response** (` ClientStatusBody`):
2025-10-13 22:13:15 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"status": "IN_SYNC"
2025-10-13 22:13:15 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
**Status Values**: ` IN_SYNC`, ` NOT_SYNCED`, ` NOT_SYNCING`
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
---
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
## Document Operations (DocumentsService)
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
### ` POST /client/{id}/document`
Uploads a document for a specific client.
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Security**: Requires JWT authentication
**Content Type**: ` multipart/form-data`
**Max File Size**: 100GB
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Form Parameters**:
- ` file` (required): Document file (PDF)
- ` filename` (optional): Custom filename (max 4096 chars)
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Response**: ` 200` Document uploaded
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
### ` GET /client/{id}/document`
Lists documents for a client.
**Security**: Requires JWT authentication
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Response** (` ListDocuments`):
` ``json
[
{
"id": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
"hash": "sha256:abc123..."
}
]
2025-10-13 22:13:15 +00:00
` ``
2025-11-26 19:23:42 +00:00
### ` 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
}
}
2025-10-13 22:13:15 +00:00
` ``
2025-11-26 19:23:42 +00:00
---
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
## Batch Document Operations (DocumentsService)
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
### ` POST /client/{id}/document/batch`
Uploads a ZIP archive containing multiple PDF documents for asynchronous batch processing.
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Security**: Requires JWT authentication
**Content Type**: ` multipart/form-data`
**Max Archive Size**: 1GB
**Supported Archive Type**: ZIP only
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Form Parameters**:
- ` archive` (required): ZIP file containing PDF documents
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Response** (` 202 Accepted`):
2025-10-13 22:13:15 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"batch_id": "019580df-ef65-7676-8de9-94435a93337a",
"status": "processing",
"status_url": "/client/AAA/document/batch/019580df-ef65-7676-8de9-94435a93337a"
2025-10-13 22:13:15 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
### ` GET /client/{id}/document/batch`
Lists batch uploads for a client with pagination support.
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Security**: Requires JWT authentication
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**Query Parameters**:
- ` limit`: Maximum results (integer, 1-100, default: 20)
- ` offset`: Pagination offset (integer, default: 0)
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
**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
}
2025-10-13 22:13:15 +00:00
` ``
2025-11-26 19:23:42 +00:00
**Batch Status Values**: ` processing`, ` completed`, ` failed`, ` cancelled`
2025-10-13 22:13:15 +00:00
2025-11-26 19:23:42 +00:00
### ` GET /client/{id}/document/batch/{batch_id}`
Retrieves detailed status information for a specific batch upload.
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**Security**: Requires JWT authentication
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**Path Parameters**:
- ` batch_id`: Batch upload identifier (UUID)
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**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"]
}
2025-06-24 19:56:56 +00:00
` ``
2025-11-26 19:23:42 +00:00
### ` DELETE /client/{id}/document/batch/{batch_id}`
Cancels a batch upload that is currently processing.
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**Security**: Requires JWT authentication
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**Response**:
- ` 204`: Batch upload cancelled successfully
- ` 404`: Batch not found
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
---
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
## Folder Operations (FolderService)
2025-12-04 22:45:15 +00:00
### 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`):
` ``json
{
"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
2025-11-26 19:23:42 +00:00
### ` POST /folders`
Creates a new folder for organizing documents.
**Security**: Requires JWT authentication
**Request Body** (` FolderCreate`):
2025-06-24 19:56:56 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"path": "/documents/2024",
"clientId": "AAA",
"createdBy": "user@example.com",
"parentId": "019580df-ef65-7676-8de9-94435a93337a"
2025-06-24 19:56:56 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
| 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 |
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**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
2025-06-24 19:56:56 +00:00
**Path Parameters**:
2025-11-26 19:23:42 +00:00
- ` folderId`: Folder UUID
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**Request Body** (` FolderRename`):
2025-06-24 19:56:56 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"path": "/documents/2024-renamed"
2025-06-24 19:56:56 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
**Response** (` 200 OK`): Updated folder object
### ` GET /folders/{folderId}/documents`
Retrieves all documents within a specific folder.
**Security**: Requires JWT authentication
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**Response**:
2025-06-24 19:56:56 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"documents": [
{
"id": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
"client_id": "AAA",
"hash": "sha256:abc123...",
"fields": {}
}
]
2025-06-24 19:56:56 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
### ` GET /folders/{folderId}/metrics`
Retrieves processing progress metrics for documents in a folder.
**Security**: Requires JWT authentication
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**Response** (` FolderMetrics`):
2025-06-24 19:56:56 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"folderId": "019580df-ef65-7676-8de9-94435a93337a",
"totalDocuments": 150,
"byLabel": {
"Ingested": 150,
"OCR_Processed": 120,
"Dashboard_Ready": 100
}
2025-06-24 19:56:56 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
---
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
## Label Operations (LabelService)
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
### ` POST /documents/{documentId}/labels`
Applies a workflow label to a document for tracking processing state.
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**Security**: Requires JWT authentication
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**Path Parameters**:
- ` documentId`: Document UUID
**Request Body** (` LabelApplication`):
2025-06-24 19:56:56 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"label": "OCR_Processed",
"appliedBy": "user@example.com"
2025-06-24 19:56:56 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
| 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 |
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**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
2025-06-24 19:56:56 +00:00
**Response**:
` ``json
{
2025-11-26 19:23:42 +00:00
"labels": [
2025-06-24 19:56:56 +00:00
{
2025-11-26 19:23:42 +00:00
"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"
2025-06-24 19:56:56 +00:00
}
2025-11-26 19:23:42 +00:00
]
2025-06-24 19:56:56 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
### ` GET /labels/{labelName}/documents`
Retrieves all documents that have been tagged with a specific label.
2025-09-09 19:34:03 +00:00
2025-11-26 19:23:42 +00:00
**Security**: Requires JWT authentication
2025-09-09 19:34:03 +00:00
2025-11-26 19:23:42 +00:00
**Path Parameters**:
- ` labelName`: Label name (alphanumeric and underscore only, max 100 chars)
2025-09-09 19:34:03 +00:00
2025-11-26 19:23:42 +00:00
**Query Parameters**:
- ` clientId` (required): Client ID to filter documents (UUID)
2025-09-09 19:34:03 +00:00
2025-11-26 19:23:42 +00:00
**Response**:
2025-09-09 19:34:03 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"documents": [
{
"id": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
"hash": "sha256:abc123..."
}
]
2025-09-09 19:34:03 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
---
2025-09-09 19:34:03 +00:00
2025-11-26 19:23:42 +00:00
## Field Extraction Operations (FieldExtractionService)
2025-09-09 19:34:03 +00:00
2025-11-26 19:23:42 +00:00
### ` POST /field-extractions`
Creates a new field extraction with single-value and array fields for a document.
**Security**: Requires JWT authentication
**Request Body** (` FieldExtractionRequest`):
2025-09-09 19:34:03 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"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": [
2025-09-09 19:34:03 +00:00
{
2025-11-26 19:23:42 +00:00
"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
2025-09-09 19:34:03 +00:00
}
],
2025-11-26 19:23:42 +00:00
"createdBy": "user@example.com"
2025-09-09 19:34:03 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
**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`):
2025-09-09 19:34:03 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"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"
2025-09-09 19:34:03 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
### ` GET /field-extractions`
Retrieves the most recent field extraction for a document.
2025-09-09 19:34:03 +00:00
2025-11-26 19:23:42 +00:00
**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
2025-09-09 19:34:03 +00:00
**Response**:
2025-11-26 19:23:42 +00:00
` ``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"
}
]
}
` ``
2025-09-09 19:34:03 +00:00
2025-12-04 22:45:15 +00:00
### ` 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`):
` ``json
{
"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
2025-11-26 19:23:42 +00:00
---
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
## Query Management (QueryService)
### ` GET /query`
2025-06-24 19:56:56 +00:00
Lists all available queries in the system.
2025-11-26 19:23:42 +00:00
**Security**: Requires JWT authentication
**Response** (` ListQueries`):
2025-06-24 19:56:56 +00:00
` ``json
{
"queries": [
{
2025-11-26 19:23:42 +00:00
"id": "019580df-ef65-7676-8de9-94435a93337a",
"type": "JSON_EXTRACTOR",
"active_version": 1,
"latest_version": 2,
"config": "{...}",
"required_queries": ["019580df-ef65-7676-8de9-94435a93337b"]
2025-06-24 19:56:56 +00:00
}
]
}
` ``
2025-11-26 19:23:42 +00:00
**Query Types**: ` JSON_EXTRACTOR`, ` CONTEXT_FULL`
### ` POST /query`
2025-06-24 19:56:56 +00:00
Creates a new query definition.
2025-11-26 19:23:42 +00:00
**Security**: Requires JWT authentication
**Request Body** (` QueryCreate`):
2025-06-24 19:56:56 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"type": "JSON_EXTRACTOR",
"config": "{\"key\": \"value\"}",
"required_queries": ["019580df-ef65-7676-8de9-94435a93337b"]
2025-06-24 19:56:56 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
**Response** (` 201 Created`):
` ``json
{
"id": "019580df-ef65-7676-8de9-94435a93337a"
}
` ``
### ` GET /query/{id}`
2025-06-24 19:56:56 +00:00
Retrieves query details including configuration.
2025-11-26 19:23:42 +00:00
**Security**: Requires JWT authentication
**Response**: ` Query` object
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
### ` PATCH /query/{id}`
Updates query definition.
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**Security**: Requires JWT authentication
**Request Body** (` QueryUpdate`):
2025-06-24 19:56:56 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"config": "{\"updated\": true}",
"active_version": 2,
"required_queries": []
2025-06-24 19:56:56 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
### ` POST /query/{id}/test`
Tests query execution against a document.
**Security**: Requires JWT authentication
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
**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`
2025-06-24 19:56:56 +00:00
Retrieves collector configuration for a client.
2025-11-26 19:23:42 +00:00
**Security**: Requires JWT authentication
**Response** (` Collector`):
2025-06-24 19:56:56 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"client_id": "AAA",
"active_version": 1,
"latest_version": 2,
"minimum_cleaner_version": 1,
"minimum_text_version": 1,
"fields": [
2025-06-24 19:56:56 +00:00
{
2025-11-26 19:23:42 +00:00
"name": "contract_date",
"query_id": "019580df-ef65-7676-8de9-94435a93337a"
2025-06-24 19:56:56 +00:00
}
2025-11-26 19:23:42 +00:00
]
2025-06-24 19:56:56 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
### ` PATCH /client/{id}/collector`
2025-06-24 19:56:56 +00:00
Updates collector configuration.
2025-11-26 19:23:42 +00:00
**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)
2025-06-24 19:56:56 +00:00
2025-11-26 19:23:42 +00:00
### ` POST /client/{id}/export`
2025-06-24 19:56:56 +00:00
Triggers data export for a client.
2025-11-26 19:23:42 +00:00
**Security**: Requires JWT authentication
**Request Body** (` ExportTrigger`):
2025-06-24 19:56:56 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"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"]
2025-06-24 19:56:56 +00:00
}
2025-11-26 19:23:42 +00:00
]
2025-06-24 19:56:56 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
**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}`
2025-06-24 19:56:56 +00:00
Checks export status and retrieves download URL.
2025-11-26 19:23:42 +00:00
**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
2025-06-24 19:56:56 +00:00
**Response**:
2025-11-26 19:23:42 +00:00
- ` 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`):
2025-06-24 19:56:56 +00:00
` ``json
{
2025-11-26 19:23:42 +00:00
"success": true,
"email": "john.doe@example.com",
"action": "disable",
"cognito_subject_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2025-10-16T14:25:33Z"
2025-06-24 19:56:56 +00:00
}
` ``
2025-11-26 19:23:42 +00:00
### ` 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"`
---
2025-06-24 19:56:56 +00:00
## Request/Response Schemas
### Standard Response Headers
All API responses include:
- ` RateLimit`: Current rate limit status (format: ` 100;window=60`)
2025-11-26 19:23:42 +00:00
- ` Content-Type`: ` application/json` (except file downloads and HTML pages)
2025-06-24 19:56:56 +00:00
### Error Response Format
` ``json
{
"message": "Error description (max 256 chars)"
}
` ``
### Common HTTP Status Codes
2025-11-26 19:23:42 +00:00
| 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) |
---
2025-06-24 19:56:56 +00:00
## 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
2025-11-26 19:23:42 +00:00
---
2025-12-04 22:45:15 +00:00
## 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}/document` → ` client`)
4. **Action Mapping**: The HTTP method is converted to lowercase to become the action (e.g., ` GET` → ` get`)
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
- ` GET` → ` get`, ` POST` → ` post`, ` PATCH` → ` patch`, ` DELETE` → ` delete`, ` HEAD` → ` head`
### 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:
` ``json
{
"error": "Authorization required",
"message": "This endpoint requires authentication. Please obtain a valid JWT token.",
"login_url": "/login"
}
` ``
**HTTP 403 Forbidden** - Insufficient permissions:
` ``json
{
"error": "Insufficient permissions",
"message": "Access denied by authorization service",
"user": "<cognito-subject-id>",
"resource": "<resource-name>",
"action": "<action-name>"
}
` ``
---
2025-06-24 19:56:56 +00:00
## 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
2025-11-26 19:23:42 +00:00
- Parameter binding with type safety