API Guide
This document provides an overview of all available endpoints in the Attachment Management Module (AMM) API.
Authentication
All endpoints (except /health
) require Bearer token authentication (JWT) in the Authorization
header, please refer to Authentication for more details.
Health Check
GET /health/livez
Description: Returns liveness status of the service.
Request
- Headers: None
- Body: None
Response Body
Name | Type | Description |
---|---|---|
status | string | Liveness status (e.g., OK) |
... | ... | ... (implementation detail) |
GET /health/readyz
Description: Returns readiness status of the service.
Request
- Headers: None
- Body: None
Response Body
Name | Type | Description |
---|---|---|
status | string | Readiness status (e.g., OK) |
... | ... | ... (implementation detail) |
Attachments
POST /attachments
Description: Upload one or more attachments.
- Functional Access Level:
- Resource: amm.attachment
- Scope: edit
- Data Access level: none
Request
- Headers:
Authorization: Bearer <token>
Content-Type: multipart/form-data
- Body:
Name Type Required Description files file[] Yes File(s) to upload description string No Description of the file(s) tags string No Comma-separated tag UUIDs module string Yes Module name entity_type string No Entity type entity_id UUID No Entity ID checksum string Yes File checksum (see Checksum Generation below)
Response
Response code
Code | Description |
---|---|
201 | Upload successful |
400 | Invalid request |
401 | Unauthorized |
500 | Internal server error |
Response body
Name | Type | Description |
---|---|---|
attachments | array | List of uploaded attachments |
└─ id | UUID | Attachment ID |
└─ file_name | string | File name |
└─ file_size | int64 | File size in bytes |
└─ mime_type | string | MIME type |
└─ description | string | Description |
└─ entity_id | UUID | Entity ID |
└─ entity_type | string | Entity type |
└─ tenant_id | string | Tenant ID |
GET /attachments/{id}
Description: Get metadata for a specific attachment.
- Functional Access Level:
- Resource: amm.attachment
- Scope: view
- Data Access level: based on resource_name value in Data Access entity with the view scope.
Request
- Headers:
Authorization: Bearer <token>
- Body: None
Response
Response code
Code | Description |
---|---|
200 | Success |
401 | Unauthorized |
404 | Not found |
500 | Internal server error |
Response body
Name | Type | Description |
---|---|---|
id | UUID | Attachment ID |
file_name | string | File name |
file_size | int64 | File size in bytes |
mime_type | string | MIME type |
description | string | Description |
entity_id | UUID | Entity ID |
entity_type | string | Entity type |
tenant_id | string | Tenant ID |
created_at | string | Creation timestamp (RFC3339) |
updated_at | string | Last update timestamp |
created_by | string | Creator user ID |
updated_by | string | Last updater user ID |
data_access | array | Data access list (only user has edit scope) |
└─ attachment_id | UUID | Attachment ID |
└─ resource_name | string | Resource name |
└─ scope | string | Access scope |
tags | array | List of tags |
└─ attachment_id | UUID | Attachment ID |
└─ tag_id | UUID | Tag ID |
PUT /attachments/{id}
Description: Update attachment metadata (description, tags, data access).
- Functional Access Level:
- Resource: amm.attachment
- Scope: edit
- Data Access level: based on resource_name value in Data Access entity with the edit scope.
Request
- Headers:
Authorization: Bearer <token>
Content-Type: application/json
- Body:
Name Type Required Description description string No Description tag_ids UUID[] No List of tag IDs data_access object[] No Data access list └─ resource_name string Yes Resource name └─ scope string Yes Access scope
Response
Response code
Code | Description |
---|---|
200 | Success |
401 | Unauthorized |
404 | Not found |
500 | Internal server error |
Response body
Name | Type | Description |
---|---|---|
id | UUID | Attachment ID |
description | string | Description |
tags | array | List of tags |
data_access | array | Data access list |
GET /attachments/{id}/download-id
Description: Generate a secure download ID for an attachment.
- Functional Access Level:
- Resource: amm.attachment
- Scope: view
- Data Access level: based on resource_name value in Data Access entity with the view scope.
Request
- Headers:
Authorization: Bearer <token>
- Body: None
Response
Response code
Code | Description |
---|---|
200 | Success |
401 | Unauthorized |
404 | Not found |
500 | Internal server error |
Response body
Name | Type | Description |
---|---|---|
download_id | UUID | Download ID |
expires_at | string | Expiry timestamp (RFC3339) |
download_path | string | Download path |
GET /downloads/{id}
Description: Download the attachment file using a secure download ID.
- Functional Access Level:
- Resource: amm.attachment
- Scope: view
- Data Access level: based on resource_name value in Data Access entity with the view scope.
Request
- Headers:
Authorization: Bearer <token>
- Body: None
Response
Response code
Code | Description |
---|---|
200 | Success |
401 | Unauthorized |
404 | Not found |
500 | Internal server error |
Response body
- File stream with appropriate headers:
Content-Type
: MIME type of the fileContent-Disposition
: Attachment with filenameContent-Length
: File size
GET /attachments/modules/{module_id}
Description: List attachments by module, only attachments that user has access to will be returned.
- Functional Access Level:
- Resource: amm.attachment
- Scope: view
- Data Access level: based on resource_name value in Data Access entity with the view scope.
Request
- Headers:
Authorization: Bearer <token>
- Query Parameters:
Name Type Required Description entity_type string No Entity type filter page int No Page number size int No Page size sort string No Sort order - Body: None
Response
Response code
Code | Description |
---|---|
200 | Success |
400 | Invalid request |
401 | Unauthorized |
500 | Internal server error |
Response body
Name | Type | Description |
---|---|---|
attachments | array | List of attachments |
└─ id | UUID | Attachment ID |
└─ file_name | string | File name |
└─ file_size | int64 | File size in bytes |
└─ mime_type | string | MIME type |
└─ description | string | Description |
└─ entity_id | UUID | Entity ID |
└─ entity_type | string | Entity type |
└─ tenant_id | string | Tenant ID |
pagination | object | Pagination info |
└─ total_records | int | Total records |
└─ number | int | Current page number |
└─ size | int | Page size |
└─ count | int | Number of records in page |
└─ sort | string | Sort order |
GET /attachments/modules/{module_id}/entities/{entity_id}
Description: List attachments by entity, only attachments that user has access to will be returned.
- Functional Access Level:
- Resource: amm.attachment
- Scope: view
- Data Access level: based on resource_name value in Data Access entity with the view scope.
Request
- Headers:
Authorization: Bearer <token>
- Query Parameters: Same as above
- Body: None
Response
Response code
Code | Description |
---|---|
200 | Success |
400 | Invalid request |
401 | Unauthorized |
500 | Internal server error |
Response body
Name | Type | Description |
---|---|---|
attachments | array | List of attachments |
└─ id | UUID | Attachment ID |
└─ file_name | string | File name |
└─ file_size | int64 | File size in bytes |
└─ mime_type | string | MIME type |
└─ description | string | Description |
└─ entity_id | UUID | Entity ID |
└─ entity_type | string | Entity type |
└─ tenant_id | string | Tenant ID |
pagination | object | Pagination info |
└─ total_records | int | Total records |
└─ number | int | Current page number |
└─ size | int | Page size |
└─ count | int | Number of records in page |
└─ sort | string | Sort order |
DELETE /attachments/{id}/logical-delete
Description: Soft-delete (logical delete) an attachment.
- Functional Access Level:
- Resource: amm.attachment
- Scope: edit
- Data Access level: based on resource_name value in Data Access entity with the edit scope.
Request
- Headers:
Authorization: Bearer <token>
- Body: None
Response
Response code
Code | Description |
---|---|
204 | Success |
401 | Unauthorized |
404 | Not found |
500 | Internal server error |
DELETE /attachments/{id}/physical-delete
Description: Hard-delete (permanent delete) an attachment.
- Functional Access Level:
- Resource: amm.attachment
- Scope: edit
- Data Access level: based on resource_name value in Data Access entity with the edit scope.
Request
- Headers:
Authorization: Bearer <token>
- Body: None
Response
Response code
Code | Description |
---|---|
204 | Success |
401 | Unauthorized |
404 | Not found |
500 | Internal server error |
POST /attachments/{id}/restore
Description: Restore a logically deleted attachment.
- Functional Access Level:
- Resource: amm.admin
- Scope: edit
- Data Access level: none
Request
- Headers:
Authorization: Bearer <token>
- Body: None
Response
Response code
Code | Description |
---|---|
200 | Success |
401 | Unauthorized |
404 | Not found |
500 | Internal server error |
Checksum Generation
The AMM module uses SHA256 checksums to validate request integrity. Checksums are generated from request metadata to ensure data consistency and prevent tampering.
How Checksums Work
-
Metadata Collection: The checksum is generated from the following request fields:
description
(string)tags
(array of UUIDs)module
(string)entity_type
(string)entity_id
(UUID, optional)
-
Data Processing:
- Empty values are excluded from the checksum calculation
- Keys are sorted alphabetically for consistent ordering
- The data is formatted as:
key_1=value_1;key_2=value_2
-
Checksum Generation:
- The formatted string is converted to bytes
- SHA256 hash is applied to the bytes
- The result is encoded as a hexadecimal string
Example Checksum Generation
Given the following request metadata:
{
"description": "Sample document",
"tags": ["550e8400-e29b-41d4-a716-446655440000"],
"module": "documents",
"entity_type": "invoice",
"entity_id": "123e4567-e89b-12d3-a456-426614174000"
}
The checksum generation process:
- Format data:
description=Sample document;entity_id=123e4567-e89b-12d3-a456-426614174000;entity_type=invoice;module=documents;tags=["550e8400-e29b-41d4-a716-446655440000"]
- Apply SHA256:
sha256(formatted_string)
- Hex encode:
a1b2c3d4e5f6...
Configuration
Checksum validation can be controlled via the CHECKSUM_ENABLED
environment variable:
CHECKSUM_ENABLED=true
: Checksums are required and validatedCHECKSUM_ENABLED=false
: Checksums are optional (default)
Error Handling
If checksum validation fails, the API returns a 400 Bad Request error with details about the checksum mismatch.
All error responses follow this format:
Name | Type | Description |
---|---|---|
error | string | Error message |
details | string[] | Error details array |