BAPBA Protocol
API Reference

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

StatusDescription
draftWill created, documents uploaded, not yet sealed
activeWill sealed, liveness checks active
pending_transferTriggered, awaiting confirmation
transfer_initiatedTransfer officially started
awaiting_authenticationSurvivors authenticating
accessibleDocuments accessible
transfer_stalledInsufficient survivors authenticated
transfer_failedTransfer failed

POST /api/will/upload

Upload will documents.

Headers

Authorization: Bearer <access_token>
Content-Type: multipart/form-data

Request

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/json

Request

{
  "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/json

Request

{
  "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

ParameterDefaultDescription
limit20Items per page
offset0Offset 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 found
  • 409 — Transfer already in progress

POST /api/transfer/cancel

Host cancels an active transfer.

Headers

Authorization: Bearer <access_token>
Content-Type: application/json

Request

{
  "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

ParameterRequiredDescription
transfer_idYesTransfer 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

ParameterRequiredDescription
transfer_idYesTransfer ID
survivor_idYesSurvivor 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 met
  • 410 — 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"}.

EndpointLimit (per IP)Window
POST /api/transfer/lookup10 requests1 minute
POST /api/transfer/send-otp, POST /api/survivor-auth/select10 requests1 minute
POST /api/transfer/verify-and-initiate, POST /api/survivor-auth/verify-otp15 requests1 minute
POST /api/transfer/initiate, GET /api/transfer/status, GET /api/transfer/completed/{id}30 requests1 minute
GET /api/survivor-auth/will-access, GET /api/survivor-auth/download30 requests1 minute

OTP send is also limited to 5 requests per hour per survivor (database-backed). OTP verification allows 3 attempts per OTP session.


On this page