Fuscorrespondence API Reference
DocumentationFuscorrespondence API Reference
Base URL
https://6nnj8no7u0.execute-api.us-east-1.amazonaws.com/dev/fuscorrespondence
Authentication
All endpoints require JWT authentication via the Authorization header:
Authorization: Bearer <jwt_token>
Token Source: Obtained from fuscauth authentication service integration.
Response Format
All API responses follow this consistent structure:
Success Response:
{
"success": true,
"data": { ... },
"message": "Operation completed successfully"
}
Error Response:
{
"success": false,
"error": "ERROR_CODE",
"message": "Human-readable error message",
"details": "Additional error context (optional)"
}
Data Models
Letter Model (Updated)
interface Letter {
pk: string // LETTER#{letterId}
senderUserId: string // ID of user who sent the letter
senderMailboxId: string // Sender's mailbox ID
recipientMailboxId: string // Recipient's mailbox ID
status: "Draft" | "Sent" // Simplified status system
isRead: boolean // Whether recipient has read the letter
content: string // Letter content
recipientName?: string // Optional recipient display name
senderName?: string // Optional sender display name
recipientFuscaddress?: string // Recipient's FuscAddress
senderFuscaddress?: string // Sender's FuscAddress
sentDate?: string // ISO string when letter was sent
createdAt: string // ISO string when draft was created
updatedAt: string // ISO string when last modified
}
Mailbox Model
interface Mailbox {
pk: string // USER#{userId}
sk: string // MAILBOX#{mailboxId}
fuscaddress: string // Unique address like "42 Quill Street, Lettertown"
location: {
latitude: number
longitude: number
}
createdAt: string // ISO string
updatedAt: string // ISO string
}
API Endpoints
Mailbox Management
Create or Update Mailbox
POST /mailbox
Creates a new mailbox or updates an existing one for the authenticated user.
Request Body:
{
"fuscaddress": "42 Quill Street, Lettertown",
"location": {
"latitude": 37.7749,
"longitude": -122.4194
}
}
Response (200):
{
"success": true,
"data": {
"pk": "USER#user123",
"sk": "MAILBOX#mailbox456",
"fuscaddress": "42 Quill Street, Lettertown",
"location": {
"latitude": 37.7749,
"longitude": -122.4194
},
"createdAt": "2025-01-01T12:00:00.000Z",
"updatedAt": "2025-01-01T12:00:00.000Z"
},
"message": "Mailbox created successfully"
}
Error Cases:
400
: Missing required fields (fuscaddress, location)401
: Invalid or missing JWT token
Get My Mailbox
GET /mailbox
Retrieves the current user's mailbox information.
Response (200):
{
"success": true,
"data": {
"pk": "USER#user123",
"sk": "MAILBOX#mailbox456",
"fuscaddress": "42 Quill Street, Lettertown",
"location": {
"latitude": 37.7749,
"longitude": -122.4194
},
"createdAt": "2025-01-01T12:00:00.000Z",
"updatedAt": "2025-01-01T12:00:00.000Z"
}
}
Error Cases:
404
: User has no mailbox configured401
: Invalid or missing JWT token
Letter Operations
Create Draft Letter
POST /letters
Creates a new draft letter for the authenticated user.
Request Body:
{
"content": "Dear friend,\n\nHope this letter finds you well...",
"status": "Draft",
"recipientName": "Jane Doe",
"senderName": "John Smith"
}
Response (201):
{
"success": true,
"data": {
"pk": "LETTER#letter789",
"senderUserId": "user123",
"senderMailboxId": "mailbox456",
"recipientMailboxId": "",
"status": "Draft",
"isRead": false,
"content": "Dear friend,\n\nHope this letter finds you well...",
"recipientName": "Jane Doe",
"senderName": "John Smith",
"senderFuscaddress": "42 Quill Street, Lettertown",
"createdAt": "2025-01-01T12:00:00.000Z",
"updatedAt": "2025-01-01T12:00:00.000Z"
},
"message": "Draft created successfully"
}
Error Cases:
400
: Missing required fields (content, status must be "Draft")400
: User has no mailbox configured401
: Invalid or missing JWT token
Update Draft Letter
PATCH /letters/{letterId}
Updates an existing draft letter. Only draft letters can be updated.
Request Body:
{
"content": "Updated letter content...",
"recipientName": "Jane Doe",
"senderName": "John Smith"
}
Response (200):
{
"success": true,
"data": {
"pk": "LETTER#letter789",
"senderUserId": "user123",
"senderMailboxId": "mailbox456",
"recipientMailboxId": "",
"status": "Draft",
"isRead": false,
"content": "Updated letter content...",
"recipientName": "Jane Doe",
"senderName": "John Smith",
"senderFuscaddress": "42 Quill Street, Lettertown",
"createdAt": "2025-01-01T12:00:00.000Z",
"updatedAt": "2025-01-01T12:05:00.000Z"
},
"message": "Draft updated successfully"
}
Error Cases:
404
: Letter not found or not owned by user400
: Letter is not in Draft status401
: Invalid or missing JWT token
Send Letter
POST /letters/{letterId}/send
Sends a draft letter to a recipient. Converts the letter from Draft to Sent status.
Request Body:
{
"recipientFuscaddress": "123 Oak Avenue, Mailford"
}
Response (200):
{
"success": true,
"data": {
"pk": "LETTER#letter789",
"senderUserId": "user123",
"senderMailboxId": "mailbox456",
"recipientMailboxId": "mailbox999",
"status": "Sent",
"isRead": false,
"content": "Dear friend,\n\nHope this letter finds you well...",
"recipientName": "Jane Doe",
"senderName": "John Smith",
"recipientFuscaddress": "123 Oak Avenue, Mailford",
"senderFuscaddress": "42 Quill Street, Lettertown",
"sentDate": "2025-01-01T12:10:00.000Z",
"createdAt": "2025-01-01T12:00:00.000Z",
"updatedAt": "2025-01-01T12:10:00.000Z"
},
"message": "Letter sent successfully"
}
Error Cases:
404
: Letter not found or not owned by user400
: Letter is not in Draft status422
: Invalid recipient FuscAddress (address does not exist)401
: Invalid or missing JWT token
Get My Letters
GET /letters
Retrieves letters for the authenticated user with optional filtering.
Query Parameters:
status
(optional):Draft
orSent
sent
(optional):true
for sent letters,false
for received letters
Examples:
/letters
- All letters (sent and received)/letters?status=Draft
- Only draft letters/letters?sent=true
- Only letters I've sent/letters?sent=false
- Only letters I've received/letters?status=Sent&sent=true
- Only letters I've sent that are in Sent status
Response (200):
{
"success": true,
"data": [
{
"pk": "LETTER#letter789",
"senderUserId": "user123",
"senderMailboxId": "mailbox456",
"recipientMailboxId": "mailbox999",
"status": "Sent",
"isRead": false,
"content": "Dear friend,\n\nHope this letter finds you well...",
"recipientName": "Jane Doe",
"senderName": "John Smith",
"recipientFuscaddress": "123 Oak Avenue, Mailford",
"senderFuscaddress": "42 Quill Street, Lettertown",
"sentDate": "2025-01-01T12:10:00.000Z",
"createdAt": "2025-01-01T12:00:00.000Z",
"updatedAt": "2025-01-01T12:10:00.000Z"
}
]
}
Get Letter by ID
GET /letters/{letterId}
Retrieves a specific letter by ID. User can only access their own letters (sent or received).
Response (200):
{
"success": true,
"data": {
"pk": "LETTER#letter789",
"senderUserId": "user123",
"senderMailboxId": "mailbox456",
"recipientMailboxId": "mailbox999",
"status": "Sent",
"isRead": false,
"content": "Dear friend,\n\nHope this letter finds you well...",
"recipientName": "Jane Doe",
"senderName": "John Smith",
"recipientFuscaddress": "123 Oak Avenue, Mailford",
"senderFuscaddress": "42 Quill Street, Lettertown",
"sentDate": "2025-01-01T12:10:00.000Z",
"createdAt": "2025-01-01T12:00:00.000Z",
"updatedAt": "2025-01-01T12:10:00.000Z"
}
}
Side Effect: If the user is the recipient and the letter status is "Sent", this endpoint automatically marks the letter as read (isRead: true
).
Error Cases:
404
: Letter not found or not accessible by user401
: Invalid or missing JWT token
Address Validation
Validate FuscAddress
POST /address/validate
Validates if a FuscAddress exists in the system (i.e., belongs to a user with a configured mailbox).
Request Body:
{
"fuscaddress": "123 Oak Avenue, Mailford"
}
Response (200) - Valid Address:
{
"success": true,
"data": {
"valid": true
}
}
Response (200) - Invalid Address:
{
"success": true,
"data": {
"valid": false
}
}
Error Cases:
400
: Missing fuscaddress field401
: Invalid or missing JWT token
HTTP Status Codes
Status Code | Description | When It Occurs |
---|---|---|
200 | OK | Successful GET, PATCH, or POST operations |
201 | Created | Successful resource creation (e.g., new draft letter) |
400 | Bad Request | Missing required fields, invalid input format, or business rule violations |
401 | Unauthorized | Invalid, missing, or expired JWT token |
403 | Forbidden | User attempting to access resources they don't own |
404 | Not Found | Letter, mailbox, or other resource not found |
422 | Unprocessable Entity | Valid request format but failed business validation (e.g., invalid FuscAddress) |
500 | Internal Server Error | Unexpected server error or database failure |
Error Response Examples
400 Bad Request:
{
"success": false,
"error": "MISSING_REQUIRED_FIELDS",
"message": "content is required and status must be 'Draft'"
}
401 Unauthorized:
{
"success": false,
"error": "UNAUTHORIZED",
"message": "Invalid or missing authentication token"
}
404 Not Found:
{
"success": false,
"error": "LETTER_NOT_FOUND",
"message": "Letter not found or not accessible"
}
422 Unprocessable Entity:
{
"success": false,
"error": "INVALID_ADDRESS",
"message": "Recipient FuscAddress does not exist",
"details": "The address '999 Nonexistent St' was not found in the system"
}
Letter Status System (Simplified)
The letter status system has been simplified for better user experience:
Status Flow
- Draft: Letter is being written and can be edited
- Sent: Letter has been sent to recipient (replaces InTransit/Delivered)
Read Tracking
- isRead: Boolean field indicating if recipient has viewed the letter
- Automatically set to
true
when recipient accesses the letter via GET/letters/{id}
Benefits of Simplified System
- Easier to understand: Clear draft vs sent distinction
- Better UX: No confusion about intermediate states
- Simpler implementation: Reduces backend complexity
- Still informative: Users can track if their sent letters have been read
Authentication Integration
JWT Token Management
- Tokens are obtained from the fuscauth authentication service
- Include in all requests:
Authorization: Bearer <token>
- Tokens should be stored securely (e.g., localStorage in web apps)
- Handle token expiration gracefully with re-authentication
User Context
- All operations are scoped to the authenticated user
- Users can only access their own letters and mailbox
- User ID is extracted from JWT token for authorization
Rate Limiting
Currently no rate limiting is implemented, but consider:
- Reasonable request limits per user per minute
- Protection against abuse of address validation endpoint
- Monitoring for unusual usage patterns
Database Design Notes
DynamoDB Monotable Pattern
- Table:
fuscapp-monotable-dev
- Mailbox Items:
PK = USER#{userId}
,SK = MAILBOX#{mailboxId}
- Letter Items:
PK = LETTER#{letterId}
,SK = LETTER#{letterId}
Query Patterns
- Get user mailbox: Query by PK = USER#{userId}
- Get user's letters: Filter by senderUserId or recipientMailboxId
- Address validation: Scan for fuscaddress (future: consider GSI optimization)
Considerations for Scale
- Current design works well for moderate usage
- For high scale, consider:
- Global Secondary Index for address lookups
- Separate tables for different entity types
- Read replicas for query optimization
Last Updated: July 2025
API Version: 1.0
Status: Production Ready