8.8 KiB
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:
{
"data": { ... }, // For successful responses
"detail": "...", // For error messages
"status": "success" // Optional status indicator
}
Error Responses
{
"detail": "Error message here"
}
Common HTTP status codes:
200 OK- Success201 Created- Resource created400 Bad Request- Invalid request data401 Unauthorized- Missing or invalid authentication403 Forbidden- Insufficient permissions404 Not Found- Resource not found429 Too Many Requests- Rate limit exceeded500 Internal Server Error- Server error
Endpoints
Health Check
GET /
Check if the API is running.
Response:
{
"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 uploadform_type(required): Type of form ("pa_form"or"vsm_form")
Response:
{
"pa_id": "25-0001",
"pa_key": "generated-secure-key",
"data": {
"projectBeginn": "2025-01-01",
"name": "Student Project",
// ... other parsed data
}
}
Example:
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-KEYorX-MASTER-KEY
Response (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-KEYorX-MASTER-KEY
Request Body:
{
"projectBeginn": "2025-01-01",
"name": "Updated Project Name",
// ... fields to update
}
Response:
{
"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:
{
"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-KEYorX-MASTER-KEY
Response:
{
"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-KEYorX-MASTER-KEY
Request:
- Content-Type:
multipart/form-data - Body:
file(required): File to upload
Response:
{
"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 IDattachment_id(path): Attachment ID
Headers:
X-PA-KEYorX-MASTER-KEY
Response: Binary file data
DELETE /applications/{pa_id}/attachments/{attachment_id}
Delete an attachment.
Parameters:
pa_id(path): Application IDattachment_id(path): Attachment ID
Headers:
X-PA-KEYorX-MASTER-KEY
Response:
{
"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 IDcost_position_index(path): Cost position index (0-based)
Headers:
X-PA-KEYorX-MASTER-KEY
Response:
{
"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 IDcost_position_index(path): Cost position index
Headers:
X-PA-KEYorX-MASTER-KEY
Request Body:
{
"supplier_name": "Supplier A",
"amount": 1000.00,
"description": "Standard package",
"url": "https://supplier-a.com/quote",
"attachment_id": null,
"is_preferred": false
}
Response:
{
"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 IDcost_position_index(path): Cost position indexoffer_id(path): Offer ID
Headers:
X-PA-KEYorX-MASTER-KEY
Response:
{
"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 IDcost_position_index(path): Cost position indexoffer_id(path): Offer ID
Headers:
X-PA-KEYorX-MASTER-KEY
Response:
{
"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 IDcost_position_index(path): Cost position index
Headers:
X-PA-KEYorX-MASTER-KEY
Request Body:
{
"no_offers_required": true,
"justification": "This is a unique service provider with no alternatives..."
}
Response:
{
"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 allowedX-RateLimit-Remaining: Requests remainingX-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 pageoffset: Starting positionpage: 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.