Will Transfer API
API reference for will management, liveness checks, and transfer initiation in Burning Ash Protocol.
Will Transfer API
Will transfer endpoints manage will documents, liveness checks, and the transfer process.
Base: /api/will, /api/liveness, /api/transfer, /api/survivor-auth
Will Endpoints
GET /api/will/status
Get current will status and metadata.
Headers
Authorization: Bearer <access_token>Response (200 OK)
{
"will_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "active",
"documents_count": 3,
"total_size_bytes": 5242880,
"sss_threshold": 3,
"sss_total": 5,
"storage_id": "550e8400-e29b-41d4-a716-446655440001",
"storage_name": "My S3 Bucket",
"created_at": "2026-02-21T01:00:00Z",
"last_encrypted_at": "2026-02-21T02:00:00Z"
}Status Values
| Status | Description |
|---|---|
| draft | Will created, documents uploaded, not yet sealed |
| active | Will sealed, liveness checks active |
| pending_transfer | Triggered, awaiting confirmation |
| transfer_initiated | Transfer officially started |
| awaiting_authentication | Survivors authenticating |
| accessible | Documents accessible |
| transfer_stalled | Insufficient survivors authenticated |
| transfer_failed | Transfer failed |
POST /api/will/upload
Upload will documents.
Headers
Authorization: Bearer <access_token>
Content-Type: multipart/form-dataRequest
Form field: files[] — one or more files
Response (201 Created)
{
"will_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "draft",
"documents": [
{
"id": "550e8400-e29b-41d4-a716-446655440010",
"filename": "last_will.pdf",
"mime_type": "application/pdf",
"size_bytes": 1048576,
"sha256_hash": "a1b2c3d4e5f6..."
}
]
}Constraints
- Max file size: 50MB
- Max total will size: 500MB
- Supported: PDF, DOCX, TXT, images
POST /api/will/encrypt
Encrypt will documents and distribute SSS shares.
Headers
Authorization: Bearer <access_token>
Content-Type: application/jsonRequest
{
"storage_id": "550e8400-e29b-41d4-a716-446655440001"
}Response (200 OK)
{
"will_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "active",
"documents_encrypted": 3,
"shares_distributed": 5,
"threshold": 3,
"storage_path": "/wills/550e8400-e29b-41d4-a716-446655440000"
}Preconditions
- At least 1 storage connected
- At least 2 survivors registered
- Threshold ≤ survivor count
- Documents uploaded (draft status)
Liveness Endpoints
POST /api/liveness/alive
Host confirms they are alive.
Headers
Authorization: Bearer <access_token>
Content-Type: application/jsonRequest
{
"check_id": "550e8400-e29b-41d4-a716-446655440020"
}check_id is optional — if omitted, confirms most recent pending check.
Response (200 OK)
{
"confirmed": true,
"next_check_due": "2026-03-23T00:00:00Z",
"message": "You're confirmed alive. Next check in 30 days."
}GET /api/liveness/history
Get liveness check history.
Headers
Authorization: Bearer <access_token>Query Parameters
| Parameter | Default | Description |
|---|---|---|
| limit | 20 | Items per page |
| offset | 0 | Offset from start |
Response (200 OK)
{
"checks": [
{
"id": "550e8400-e29b-41d4-a716-446655440020",
"check_number": 1,
"status": "confirmed",
"channel": "email",
"sent_at": "2026-02-21T00:00:00Z",
"responded_at": "2026-02-21T02:30:00Z"
}
],
"total": 42,
"next_check_due": "2026-03-23T00:00:00Z"
}Transfer Endpoints
POST /api/transfer/initiate
Survivor initiates will transfer (public endpoint).
Request
{
"will_id": "550e8400-e29b-41d4-a716-446655440000",
"survivor_name": "Jane Doe"
}Response (200 OK)
{
"transfer_id": "550e8400-e29b-41d4-a716-446655440030",
"status": "initiated",
"message": "Transfer initiated. The Host has been notified and has 48 hours to respond.",
"host_cancel_deadline": "2026-02-23T00:00:00Z"
}Errors
404— Will/survivor not found409— Transfer already in progress
POST /api/transfer/cancel
Host cancels an active transfer.
Headers
Authorization: Bearer <access_token>
Content-Type: application/jsonRequest
{
"transfer_id": "550e8400-e29b-41d4-a716-446655440030"
}Response (200 OK)
{
"transfer_id": "550e8400-e29b-41d4-a716-446655440030",
"status": "cancelled",
"message": "Transfer cancelled. All survivors have been notified."
}GET /api/transfer/status
Get current transfer status (public endpoint).
Query Parameters
| Parameter | Required | Description |
|---|---|---|
| transfer_id | Yes | Transfer ID |
Response (200 OK)
{
"transfer_id": "550e8400-e29b-41d4-a716-446655440030",
"status": "awaiting_authentication",
"survivors_authenticated": 2,
"threshold": 3,
"total_survivors": 5,
"authenticated_names": ["Jane Doe", "Bob Smith"],
"initiated_at": "2026-02-21T00:00:00Z",
"host_cancel_deadline": "2026-02-23T00:00:00Z"
}Survivor Authentication Endpoints
POST /api/survivor-auth/select
Survivor selects themselves and requests OTP.
Request
{
"transfer_id": "550e8400-e29b-41d4-a716-446655440030",
"survivor_id": "550e8400-e29b-41d4-a716-446655440001"
}Response (200 OK)
{
"otp_session_id": "550e8400-e29b-41d4-a716-446655440040",
"channel": "email",
"masked_destination": "j***@example.com",
"expires_in_seconds": 600,
"message": "A 6-digit code has been sent to your email."
}POST /api/survivor-auth/verify-otp
Verify OTP or backup code.
OTP Verification
{
"otp_session_id": "550e8400-e29b-41d4-a716-446655440040",
"code": "123456"
}Backup Code Verification
{
"transfer_id": "550e8400-e29b-41d4-a716-446655440030",
"survivor_id": "550e8400-e29b-41d4-a716-446655440001",
"backup_code": "A3F7-K9M2"
}Response (200 OK — Success)
{
"verified": true,
"survivor_name": "Jane Doe",
"threshold_progress": {
"authenticated": 3,
"required": 3,
"threshold_met": true
}
}Response (200 OK — Failure)
{
"verified": false,
"attempts_remaining": 2,
"message": "Invalid code. 2 attempts remaining."
}GET /api/survivor-auth/will-access
Access decrypted documents after threshold met.
Query Parameters
| Parameter | Required | Description |
|---|---|---|
| transfer_id | Yes | Transfer ID |
| survivor_id | Yes | Survivor ID |
Response (200 OK)
{
"personal_message": "Dear Jane, if you're reading this...",
"documents": [
{
"filename": "last_will.pdf",
"mime_type": "application/pdf",
"size_bytes": 1048576,
"download_url": "https://presigned-url...",
"download_expires_at": "2026-02-22T00:00:00Z",
"integrity_verified": true
}
],
"access_expires_at": "2026-02-28T00:00:00Z"
}Errors
403— Not authenticated / threshold not met410— Access window expired
Rate Limits
All transfer and survivor-auth endpoints are rate limited per client IP per minute. Exceeding the limit returns 429 with {"error": "too many requests; try again later"}.
| Endpoint | Limit (per IP) | Window |
|---|---|---|
| POST /api/transfer/lookup | 10 requests | 1 minute |
| POST /api/transfer/send-otp, POST /api/survivor-auth/select | 10 requests | 1 minute |
| POST /api/transfer/verify-and-initiate, POST /api/survivor-auth/verify-otp | 15 requests | 1 minute |
| POST /api/transfer/initiate, GET /api/transfer/status, GET /api/transfer/completed/{id} | 30 requests | 1 minute |
| GET /api/survivor-auth/will-access, GET /api/survivor-auth/download | 30 requests | 1 minute |
OTP send is also limited to 5 requests per hour per survivor (database-backed). OTP verification allows 3 attempts per OTP session.
Related Endpoints
- Authentication — Login
- Survivors API — Survivor management
- Connectors API — Notification channels