stupa-pdf-api/docs/API_REFERENCE.md

469 lines
8.8 KiB
Markdown

# API Reference
This document provides a comprehensive reference for all API endpoints in the STUPA PDF API system.
## Base URL
- **Development**: `http://localhost:8000`
- **Production**: `https://your-domain.com/api`
## Authentication
The API uses two types of authentication:
### Application Key Authentication
- **Header**: `X-PA-KEY`
- **Purpose**: Access specific application data
- **Scope**: Read/write access to single application
### Master Key Authentication
- **Header**: `X-MASTER-KEY`
- **Purpose**: Administrative access
- **Scope**: Full access to all resources
### Query Parameter Authentication
For endpoints that need to work with direct browser access (like PDF downloads), you can use:
- **Parameter**: `key`
- **Example**: `/applications/25-0001?format=pdf&key=your-app-key`
## Response Format
All API responses follow this general structure:
```json
{
"data": { ... }, // For successful responses
"detail": "...", // For error messages
"status": "success" // Optional status indicator
}
```
## Error Responses
```json
{
"detail": "Error message here"
}
```
Common HTTP status codes:
- `200 OK` - Success
- `201 Created` - Resource created
- `400 Bad Request` - Invalid request data
- `401 Unauthorized` - Missing or invalid authentication
- `403 Forbidden` - Insufficient permissions
- `404 Not Found` - Resource not found
- `429 Too Many Requests` - Rate limit exceeded
- `500 Internal Server Error` - Server error
## Endpoints
### Health Check
#### GET /
Check if the API is running.
**Response:**
```json
{
"message": "STUPA PDF API"
}
```
---
### PDF Upload and Processing
#### POST /upload
Upload a PDF form and create a new application.
**Request:**
- **Content-Type**: `multipart/form-data`
- **Body**:
- `file` (required): PDF file to upload
- `form_type` (required): Type of form (`"pa_form"` or `"vsm_form"`)
**Response:**
```json
{
"pa_id": "25-0001",
"pa_key": "generated-secure-key",
"data": {
"projectBeginn": "2025-01-01",
"name": "Student Project",
// ... other parsed data
}
}
```
**Example:**
```bash
curl -X POST "http://localhost:8000/upload" \
-F "file=@application.pdf" \
-F "form_type=pa_form"
```
---
### Application Management
#### GET /applications/{pa_id}
Retrieve application data.
**Parameters:**
- `pa_id` (path): Application ID (e.g., "25-0001")
- `format` (query): Response format (`"json"` or `"pdf"`)
- `key` (query): Application key (alternative to header)
**Headers:**
- `X-PA-KEY` or `X-MASTER-KEY`
**Response (JSON):**
```json
{
"pa_id": "25-0001",
"created_at": "2024-01-01T00:00:00",
"updated_at": "2024-01-01T00:00:00",
"data": {
"projectBeginn": "2025-01-01",
"name": "Student Project",
// ... full application data
}
}
```
**Response (PDF):**
Binary PDF file with filled form.
---
#### PUT /applications/{pa_id}
Update application data.
**Parameters:**
- `pa_id` (path): Application ID
**Headers:**
- `X-PA-KEY` or `X-MASTER-KEY`
**Request Body:**
```json
{
"projectBeginn": "2025-01-01",
"name": "Updated Project Name",
// ... fields to update
}
```
**Response:**
```json
{
"pa_id": "25-0001",
"data": {
// ... updated application data
}
}
```
---
#### DELETE /applications/{pa_id}
Delete an application (admin only).
**Parameters:**
- `pa_id` (path): Application ID
**Headers:**
- `X-MASTER-KEY` (required)
**Response:**
```json
{
"detail": "Application deleted successfully"
}
```
---
### Attachment Management
#### GET /applications/{pa_id}/attachments
List all attachments for an application.
**Parameters:**
- `pa_id` (path): Application ID
**Headers:**
- `X-PA-KEY` or `X-MASTER-KEY`
**Response:**
```json
{
"attachments": [
{
"id": 1,
"filename": "receipt.pdf",
"content_type": "application/pdf",
"size": 102400,
"created_at": "2024-01-01T00:00:00"
}
],
"total_count": 1,
"total_size": 102400
}
```
---
#### POST /applications/{pa_id}/attachments
Upload a new attachment.
**Parameters:**
- `pa_id` (path): Application ID
**Headers:**
- `X-PA-KEY` or `X-MASTER-KEY`
**Request:**
- **Content-Type**: `multipart/form-data`
- **Body**:
- `file` (required): File to upload
**Response:**
```json
{
"id": 1,
"filename": "receipt.pdf",
"content_type": "application/pdf",
"size": 102400,
"created_at": "2024-01-01T00:00:00"
}
```
**Limits:**
- Maximum 30 attachments per application
- Maximum 100MB total size per application
- Maximum 50MB per file
---
#### GET /applications/{pa_id}/attachments/{attachment_id}
Download a specific attachment.
**Parameters:**
- `pa_id` (path): Application ID
- `attachment_id` (path): Attachment ID
**Headers:**
- `X-PA-KEY` or `X-MASTER-KEY`
**Response:**
Binary file data
---
#### DELETE /applications/{pa_id}/attachments/{attachment_id}
Delete an attachment.
**Parameters:**
- `pa_id` (path): Application ID
- `attachment_id` (path): Attachment ID
**Headers:**
- `X-PA-KEY` or `X-MASTER-KEY`
**Response:**
```json
{
"detail": "Attachment deleted successfully"
}
```
---
### Comparison Offers
#### GET /applications/{pa_id}/costs/{cost_position_index}/offers
Get comparison offers for a cost position.
**Parameters:**
- `pa_id` (path): Application ID
- `cost_position_index` (path): Cost position index (0-based)
**Headers:**
- `X-PA-KEY` or `X-MASTER-KEY`
**Response:**
```json
{
"cost_position_index": 0,
"offers": [
{
"id": 1,
"supplier_name": "Supplier A",
"amount": 1000.00,
"description": "Standard package",
"url": "https://supplier-a.com/quote",
"attachment_id": null,
"is_preferred": false,
"created_at": "2024-01-01T00:00:00"
}
],
"no_offers_required": false,
"justification": null
}
```
---
#### POST /applications/{pa_id}/costs/{cost_position_index}/offers
Create a new comparison offer.
**Parameters:**
- `pa_id` (path): Application ID
- `cost_position_index` (path): Cost position index
**Headers:**
- `X-PA-KEY` or `X-MASTER-KEY`
**Request Body:**
```json
{
"supplier_name": "Supplier A",
"amount": 1000.00,
"description": "Standard package",
"url": "https://supplier-a.com/quote",
"attachment_id": null,
"is_preferred": false
}
```
**Response:**
```json
{
"id": 1,
"supplier_name": "Supplier A",
"amount": 1000.00,
"description": "Standard package",
"url": "https://supplier-a.com/quote",
"attachment_id": null,
"is_preferred": false,
"created_at": "2024-01-01T00:00:00"
}
```
---
#### PUT /applications/{pa_id}/costs/{cost_position_index}/offers/{offer_id}/preferred
Set an offer as preferred.
**Parameters:**
- `pa_id` (path): Application ID
- `cost_position_index` (path): Cost position index
- `offer_id` (path): Offer ID
**Headers:**
- `X-PA-KEY` or `X-MASTER-KEY`
**Response:**
```json
{
"detail": "Preferred offer updated successfully"
}
```
---
#### DELETE /applications/{pa_id}/costs/{cost_position_index}/offers/{offer_id}
Delete a comparison offer.
**Parameters:**
- `pa_id` (path): Application ID
- `cost_position_index` (path): Cost position index
- `offer_id` (path): Offer ID
**Headers:**
- `X-PA-KEY` or `X-MASTER-KEY`
**Response:**
```json
{
"detail": "Offer deleted successfully"
}
```
---
#### PUT /applications/{pa_id}/costs/{cost_position_index}/justification
Update justification for not requiring comparison offers.
**Parameters:**
- `pa_id` (path): Application ID
- `cost_position_index` (path): Cost position index
**Headers:**
- `X-PA-KEY` or `X-MASTER-KEY`
**Request Body:**
```json
{
"no_offers_required": true,
"justification": "This is a unique service provider with no alternatives..."
}
```
**Response:**
```json
{
"detail": "Justification updated successfully"
}
```
---
## Rate Limiting
The API implements rate limiting to prevent abuse:
- **Per IP**: 60 requests per minute (configurable)
- **Per Key**: 30 requests per minute (configurable)
- **Excluded**: localhost and Docker internal IPs
Rate limit headers in responses:
- `X-RateLimit-Limit`: Maximum requests allowed
- `X-RateLimit-Remaining`: Requests remaining
- `X-RateLimit-Reset`: Unix timestamp when limit resets
---
## WebSocket Endpoints
Currently, the API does not provide WebSocket endpoints. All communication is via REST HTTP.
---
## Pagination
For endpoints that return lists, pagination may be implemented in future versions using:
- `limit`: Number of items per page
- `offset`: Starting position
- `page`: Page number (alternative to offset)
---
## Versioning
The API currently does not use versioning. Future versions may implement versioning via:
- URL path: `/v1/applications`
- Header: `Accept: application/vnd.stupa.v1+json`
---
## OpenAPI Documentation
Complete OpenAPI 3.0 documentation is available at:
- **Swagger UI**: `/docs`
- **ReDoc**: `/redoc`
- **OpenAPI JSON**: `/openapi.json`
These provide interactive documentation with the ability to test endpoints directly.