Table of Contents
Overview
Striae's backend consists of six Cloudflare Workers that provide specialized API services. All APIs use RESTful conventions and return JSON responses.
Authentication
Authentication Methods
All worker APIs use custom authentication headers:
X-Custom-Auth-Key: {api_key}
API keys are generated by the Keys Worker and should be obtained through the authentication flow.
Note: The Image Worker uses a different authentication method with Authorization: Bearer {token}
header.
Authentication Environment Variables:
-
User Worker: Uses
USER_DB_AUTH
environment variable -
Data Worker: Uses
R2_KEY_SECRET
environment variable -
Keys Worker: Uses
KEYS_AUTH
environment variable -
Image Worker: Uses
API_TOKEN
environment variable -
PDF Worker: No authentication required
-
Turnstile Worker: No authentication required
CORS Policy
All workers implement strict CORS policies:
-
Allowed Origin:
https://www.striae.org
-
Allowed Methods: Varies by worker
-
Allowed Headers:
Content-Type, X-Custom-Auth-Key, Authorization
User Worker API
Base URL: {USER_WORKER_URL}
Authentication: X-Custom-Auth-Key
header
Endpoints
Get User Data
GET /{userUid}
Description: Retrieve user profile data
Parameters:
userUid
(path): Firebase user UID
Response:
{
"uid": "string",
"email": "string",
"firstName": "string",
"lastName": "string",
"company": "string",
"permitted": boolean,
"cases": [
{
"caseNumber": "string",
"createdAt": "ISO 8601 date"
}
],
"createdAt": "ISO 8601 date",
"updatedAt": "ISO 8601 date"
}
Status Codes:
-
200
: Success -
404
: User not found -
401
: Unauthorized (invalid auth header) -
403
: Forbidden -
500
: Server error
Create/Update User
PUT /{userUid}
Description: Create new user or update existing user data
Parameters:
userUid
(path): Firebase user UID
Request Body:
{
"email": "string",
"firstName": "string",
"lastName": "string",
"company": "string",
"permitted": boolean
}
Response: User object (same as GET response)
Status Codes:
-
200
: User updated -
201
: User created -
401
: Unauthorized -
403
: Forbidden -
500
: Server error
Delete User
DELETE /{userUid}
Description: Delete user and all associated data
Parameters:
userUid
(path): Firebase user UID
Response:
"Successful delete"
Note: Response is returned as plain text, not JSON format.
Status Codes:
-
200
: Success -
401
: Unauthorized -
403
: Forbidden -
500
: Server error
Add Cases to User
PUT /{userUid}/cases
Description: Add case assignments to user
Parameters:
userUid
(path): Firebase user UID
Request Body:
{
"cases": [
{
"caseNumber": "string"
}
]
}
Response: Updated user object
Status Codes:
-
200
: Success -
404
: User not found -
401
: Unauthorized -
403
: Forbidden -
500
: Server error
Remove Cases from User
DELETE /{userUid}/cases
Description: Remove case assignments from user
Parameters:
userUid
(path): Firebase user UID
Request Body:
{
"casesToDelete": ["caseNumber1", "caseNumber2"]
}
Response: Updated user object
Status Codes:
-
200
: Success -
404
: User not found -
401
: Unauthorized -
403
: Forbidden -
500
: Server error
Image Worker API
Base URL: {IMAGE_WORKER_URL}
Authentication: Authorization: Bearer {API_TOKEN}
header
Endpoints
Upload Image
POST /
Description: Upload image to Cloudflare Images
Request: Multipart form data with image file
Response:
{
"result": {
"id": "string",
"filename": "string",
"uploaded": "ISO 8601 date",
"requireSignedURLs": true,
"variants": ["string"]
},
"success": boolean,
"errors": [],
"messages": []
}
Status Codes:
-
200
: Success -
403
: Forbidden (invalid token) -
400
: Invalid file or missing file -
500
: Server error
Get Signed URL
GET /{imageDeliveryPath}
Description: Generate signed URL for image access from imagedelivery.net URL
Parameters:
imageDeliveryPath
(path): Full imagedelivery.net URL path
Response: Signed URL as plain text
Status Codes:
-
200
: Success -
403
: Forbidden (invalid token) -
500
: Server error
Delete Image
DELETE /{imageId}
Description: Delete image from Cloudflare Images
Parameters:
imageId
(path): Cloudflare Images ID
Response:
{
"success": boolean,
"result": {},
"errors": [],
"messages": []
}
Status Codes:
-
200
: Success -
403
: Forbidden (invalid token) -
404
: Image not found -
500
: Server error
PDF Worker API
Base URL: {PDF_WORKER_URL}
Authentication: None required
Endpoints
Generate PDF
POST /
Description: Generate PDF report with annotations
Request Body:
{
"imageUrl": "string",
"caseNumber": "string",
"annotationData": {
"leftCase": "string",
"rightCase": "string",
"leftItem": "string",
"rightItem": "string",
"caseFontColor": "string",
"classType": "Bullet | Cartridge Case | Other",
"customClass": "string",
"classNote": "string",
"indexType": "number | color",
"indexNumber": "string",
"indexColor": "string",
"supportLevel": "ID | Exclusion | Inconclusive",
"hasSubclass": boolean,
"includeConfirmation": boolean,
"additionalNotes": "string"
},
"activeAnnotations": ["string"],
"currentDate": "string",
"notesUpdatedFormatted": "string"
}
Response: PDF file (binary data)
Headers:
Content-Type
:application/pdf
Status Codes:
-
200
: Success -
405
: Method not allowed -
500
: Server error
Data Worker API
Base URL: {DATA_WORKER_URL}
Authentication: X-Custom-Auth-Key
header
Endpoints
Get File Data
GET /{filename}.json
Description: Retrieve JSON file data from R2 storage
Parameters:
filename
(path): JSON filename (without .json extension in URL)
Response: JSON data from file or empty array if file doesn't exist
Status Codes:
-
200
: Success -
403
: Forbidden -
500
: Server error
Save File Data
PUT /{filename}.json
Description: Save JSON data to R2 storage file
Parameters:
filename
(path): JSON filename (without .json extension in URL)
Request Body: Any valid JSON data
Response:
{
"success": true
}
Status Codes:
-
200
: Success -
400
: Invalid file type (non-JSON) -
403
: Forbidden -
500
: Server error
Delete File
DELETE /{filename}.json
Description: Delete JSON file from R2 storage
Parameters:
filename
(path): JSON filename (without .json extension in URL)
Response:
{
"success": true
}
Status Codes:
-
200
: Success -
404
: File not found -
403
: Forbidden -
500
: Server error
Keys Worker API
Base URL: {KEYS_WORKER_URL}
Authentication: X-Custom-Auth-Key
header
Endpoints
Get Environment Key
GET /{keyName}
Description: Retrieve environment variable value
Parameters:
keyName
(path): Environment variable name
Response: Plain text value of the environment variable
Status Codes:
-
200
: Success -
400
: Key name required -
404
: Key not found -
403
: Forbidden -
500
: Server error
Turnstile Worker API
Base URL: {TURNSTILE_WORKER_URL}
Authentication: None required
Endpoints
Verify CAPTCHA
POST /
Description: Verify Cloudflare Turnstile token
Request Body:
{
"cf-turnstile-response": "string"
}
Response:
{
"success": boolean,
"error-codes": ["string"],
"challenge_ts": "ISO 8601 date",
"hostname": "string"
}
Status Codes:
-
200
: Verification completed (check success field) -
400
: Invalid request or token missing -
405
: Method not allowed -
500
: Server error
Error Handling
Standard Error Response Format
{
"error": "string",
"code": "string",
"message": "string",
"details": {}
}
Common Error Codes
-
UNAUTHORIZED
: Invalid or missing authentication -
FORBIDDEN
: Insufficient permissions -
NOT_FOUND
: Resource not found -
VALIDATION_ERROR
: Invalid request data -
SERVER_ERROR
: Internal server error
HTTP Status Codes
-
200
: Success -
201
: Created -
400
: Bad Request -
401
: Unauthorized -
403
: Forbidden -
404
: Not Found -
405
: Method Not Allowed -
500
: Internal Server Error
SDK Examples
JavaScript/TypeScript Client
class StriaeAPI {
constructor(private apiKey: string, private baseUrl: string) {}
async getUser(userUid: string): Promise<UserData> {
const response = await fetch(`${this.baseUrl}/${userUid}`, {
headers: {
'X-Custom-Auth-Key': this.apiKey,
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`API Error: ${response.status}`);
}
return response.json();
}
async uploadImage(file: File): Promise<UploadResult> {
const formData = new FormData();
formData.append('file', file);
const response = await fetch(`${this.baseUrl}`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`
},
body: formData
});
return response.json();
}
}
Error Handling Example
try {
const userData = await api.getUser(userUid);
console.log('User data:', userData);
} catch (error) {
if (error.status === 404) {
console.log('User not found');
} else if (error.status === 401) {
console.log('Authentication failed');
} else {
console.error('API error:', error);
}
}