openapi: 3.1.0 info: title: dead-drop API v1 version: 1.0.0 description: Privacy-focused, ephemeral data-sharing API v1 contact: name: dead-drop.xyz url: https://dead-drop.xyz termsOfService: https://dead-drop.xyz/terms license: name: MIT url: https://github.com/davorinrusevljan/dead-drop/blob/main/LICENSE servers: - url: /api/v1 description: v1 API - url: https://api.dead-drop.xyz/api/v1 description: Production v1 API tags: - name: Drops description: Drop CRUD operations - name: History description: Drop version history - name: Health description: Health check endpoints components: schemas: {} parameters: {} paths: /health: get: tags: - Health summary: Health Check description: Returns the health status of the API responses: '200': description: API is healthy content: application/json: schema: type: object properties: status: type: string enum: - ok timestamp: type: string format: date-time description: ISO 8601 timestamp example: '2026-04-18T12:00:00.000Z' required: - status - timestamp /drops/generate-name: get: tags: - Drops summary: Generate a Random Unused Drop Name description: Generates a random 4-word drop name using the EFF Diceware wordlist and ensures it is not already in use. responses: '200': description: A unique random drop name content: application/json: schema: type: object properties: name: type: string description: Generated 4-word drop name (kebab-case, lowercase) example: abacus-abide-ablaze-able id: type: string format: hex pattern: ^[a-f0-9]{64}$ description: SHA-256 hash of the name example: 7c4e8d3a9f1b6e2c8d4a7f3b9e1c5d8a2f6b4e9d3c7a1f8b5e2d9c4a6f3b7e1d required: - name - id '500': description: Failed to generate unique name content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error /drops/check/{id}: get: tags: - Drops summary: Check if a Drop Name Is Available description: Check if a drop with the given ID exists. Returns 200 with availability status regardless of whether the drop exists. parameters: - name: id in: path required: true description: SHA-256 hash of the drop name schema: type: string responses: '200': description: Availability status content: application/json: schema: type: object properties: id: type: string format: hex pattern: ^[a-f0-9]{64}$ description: Drop ID (SHA-256 hash) example: 7c4e8d3a9f1b6e2c8d4a7f3b9e1c5d8a2f6b4e9d3c7a1f8b5e2d9c4a6f3b7e1d available: type: boolean description: Whether drop name is available required: - id - available /drops/{id}: get: tags: - Drops summary: Retrieve a Drop description: Get the current version of a drop by its ID. parameters: - name: id in: path required: true description: SHA-256 hash of the drop name schema: type: string - name: I_agree_with_terms_and_conditions in: query required: true description: Must be true to confirm agreement to terms and conditions schema: type: boolean responses: '200': description: Drop data content: application/json: schema: type: object properties: id: type: string format: hex pattern: ^[a-f0-9]{64}$ description: SHA-256 hash of drop name example: 7c4e8d3a9f1b6e2c8d4a7f3b9e1c5d8a2f6b4e9d3c7a1f8b5e2d9c4a6f3b7e1d tier: type: string enum: - free - deep description: 'Drop tier. Free: 10KB, 7 days. Deep: 4MB, 90 days.' example: free visibility: type: string enum: - private - public description: Drop visibility type. Private drops are encrypted, public drops are plaintext. example: private payload: type: string description: 'For private drops: hex-encoded AES-GCM ciphertext (opaque). For public drops: raw content string, interpreted by mimeType.' salt: type: string format: hex pattern: ^[a-f0-9]{32}$ description: Hex-encoded salt (16 bytes = 32 hex characters) example: a1b2c3d4e5f6789012345678abcdef01 iv: type: string nullable: true format: hex pattern: ^[a-f0-9]{24}$ description: Hex-encoded IV (12 bytes = 24 hex chars), null for public drops example: 00112233445566778899aabb encryptionAlgo: type: string nullable: true enum: - pbkdf2-aes256-gcm-v1 description: Encryption algorithm used, null for public drops example: pbkdf2-aes256-gcm-v1 encryptionParams: type: object nullable: true properties: rounds: type: integer description: Encryption parameters (JSON object) mimeType: type: string enum: - text/plain description: MIME type of the drop content example: text/plain hashAlgo: type: string enum: - sha-256 description: Hash algorithm used for admin authentication example: sha-256 expiresAt: type: string format: date-time description: ISO 8601 timestamp when drop expires example: '2026-04-25T12:00:00.000Z' required: - id - tier - visibility - payload - salt - iv - encryptionAlgo - mimeType - hashAlgo - expiresAt '403': description: Terms not agreed content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error '404': description: Drop not found or expired content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error put: tags: - Drops summary: Update a Drop description: Update an existing drop. Authentication is required. parameters: - name: id in: path required: true description: SHA-256 hash of the drop name schema: type: string requestBody: content: application/json: schema: type: object properties: payload: type: string description: 'For private drops: hex-encoded AES-GCM ciphertext. For public drops: raw content string, interpreted by mimeType.' example: Hello, world! iv: type: string format: hex pattern: ^[a-f0-9]{24}$ description: Hex-encoded IV (12 bytes = 24 hex chars), required for private drops example: 00112233445566778899aabb mimeType: type: string enum: - text/plain description: MIME type example: text/plain contentHash: type: string format: hex pattern: ^[a-f0-9]{64}$ description: SHA-256 hash of OLD content payload JSON, required for private drops example: 7c4e8d3a9f1b6e2c8d4a7f3b9e1c5d8a2f6b4e9d3c7a1f8b5e2d9c4a6f3b7e1d newContentHash: type: string format: hex pattern: ^[a-f0-9]{64}$ description: SHA-256 hash of NEW content payload JSON, required for private drops example: 7c4e8d3a9f1b6e2c8d4a7f3b9e1c5d8a2f6b4e9d3c7a1f8b5e2d9c4a6f3b7e1d adminPassword: type: string minLength: 1 description: Admin password for authentication, required for public drops example: my-secret-admin-password I_agree_with_terms_and_conditions: type: boolean description: Must be true to confirm agreement to terms and conditions. See https://dead-drop.xyz/terms example: true required: - payload - I_agree_with_terms_and_conditions responses: '200': description: Drop updated successfully content: application/json: schema: type: object properties: success: type: boolean enum: - true version: type: integer minimum: 0 exclusiveMinimum: true description: New version number required: - success - version '400': description: Invalid request content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error '401': description: Invalid credentials content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error '402': description: Payload exceeds tier limit content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error '403': description: Maximum versions reached content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error '404': description: Drop not found content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error delete: tags: - Drops summary: Delete a Drop description: Delete a drop permanently. Authentication is required. parameters: - name: id in: path required: true description: SHA-256 hash of the drop name schema: type: string requestBody: content: application/json: schema: type: object properties: contentHash: type: string format: hex pattern: ^[a-f0-9]{64}$ description: SHA-256 hash of content payload JSON, required for private drops example: 7c4e8d3a9f1b6e2c8d4a7f3b9e1c5d8a2f6b4e9d3c7a1f8b5e2d9c4a6f3b7e1d adminPassword: type: string minLength: 1 description: Admin password for authentication, required for public drops example: my-secret-admin-password I_agree_with_terms_and_conditions: type: boolean description: Must be true to confirm agreement to terms and conditions. See https://dead-drop.xyz/terms example: true required: - I_agree_with_terms_and_conditions responses: '200': description: Drop deleted content: application/json: schema: type: object properties: success: type: boolean enum: - true required: - success '400': description: Invalid request content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error '401': description: Invalid credentials content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error '404': description: Drop not found content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error /drops: post: tags: - Drops summary: Create a New Drop description: Create a new drop with the given parameters. The drop name must not already exist. For private drops, the payload must be encrypted. requestBody: content: application/json: schema: type: object properties: id: type: string format: hex pattern: ^[a-f0-9]{64}$ description: SHA-256 hash of normalized drop name example: 7c4e8d3a9f1b6e2c8d4a7f3b9e1c5d8a2f6b4e9d3c7a1f8b5e2d9c4a6f3b7e1d nameLength: type: integer minimum: 3 description: Length of normalized name for validation (min 3 for Deep, 12 for Free) example: 12 tier: type: string enum: - free - deep description: Drop tier, defaults to free example: free visibility: type: string enum: - private - public description: Drop visibility type example: private payload: type: string description: 'For private drops: hex-encoded AES-GCM ciphertext. For public drops: raw content string, interpreted by mimeType.' example: Hello, world! salt: type: string format: hex pattern: ^[a-f0-9]{32}$ description: Hex-encoded salt (16 bytes = 32 hex characters) example: a1b2c3d4e5f6789012345678abcdef01 iv: type: string format: hex pattern: ^[a-f0-9]{24}$ description: Hex-encoded IV (12 bytes = 24 hex chars), required for private drops example: 00112233445566778899aabb encryptionAlgo: type: string enum: - pbkdf2-aes256-gcm-v1 description: Encryption algorithm, defaults to pbkdf2-aes256-gcm-v1 for private drops example: pbkdf2-aes256-gcm-v1 encryptionParams: type: object properties: rounds: type: integer description: Encryption parameters (JSON object) mimeType: type: string enum: - text/plain description: MIME type, defaults to text/plain example: text/plain hashAlgo: type: string enum: - sha-256 description: Hash algorithm for admin authentication, defaults to sha-256 (v1.1+) example: sha-256 contentHash: type: string format: hex pattern: ^[a-f0-9]{64}$ description: SHA-256 hash of content payload JSON, required for private drops example: 7c4e8d3a9f1b6e2c8d4a7f3b9e1c5d8a2f6b4e9d3c7a1f8b5e2d9c4a6f3b7e1d adminHash: type: string format: hex pattern: ^[a-f0-9]{64}$ description: SHA-256(adminPassword + salt), required for public drops example: 7c4e8d3a9f1b6e2c8d4a7f3b9e1c5d8a2f6b4e9d3c7a1f8b5e2d9c4a6f3b7e1d I_agree_with_terms_and_conditions: type: boolean description: Must be true to confirm agreement to terms and conditions. See https://dead-drop.xyz/terms example: true required: - id - nameLength - visibility - payload - salt - I_agree_with_terms_and_conditions responses: '201': description: Drop created successfully content: application/json: schema: type: object properties: success: type: boolean enum: - true version: type: number enum: - 1 tier: type: string enum: - free - deep description: 'Drop tier. Free: 10KB, 7 days. Deep: 4MB, 90 days.' example: free required: - success - version - tier '400': description: Invalid request content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error '401': description: Invalid upgrade token content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error '402': description: Payload exceeds tier limit content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error '409': description: Drop name already taken content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error /drops/{id}/history: get: tags: - History summary: List Drop History description: Get a list of all versions of a drop. parameters: - name: id in: path required: true description: SHA-256 hash of the drop name schema: type: string - name: I_agree_with_terms_and_conditions in: query required: true description: Must be true to confirm agreement to terms and conditions schema: type: boolean responses: '200': description: List of versions content: application/json: schema: type: object properties: versions: type: array items: type: object properties: version: type: integer minimum: 0 exclusiveMinimum: true description: Version number example: 1 createdAt: type: string format: date-time description: ISO 8601 timestamp example: '2026-04-18T10:00:00.000Z' required: - version - createdAt description: List of drop versions current: type: integer minimum: 0 exclusiveMinimum: true description: Current version number example: 3 maxVersions: type: integer minimum: 0 exclusiveMinimum: true description: Maximum number of versions allowed example: 10 required: - versions - current - maxVersions '403': description: Terms not agreed content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error '404': description: Drop not found content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error /drops/{id}/history/{version}: get: tags: - History summary: Get Specific Drop Version description: Get a specific version of a drop. parameters: - name: id in: path required: true description: SHA-256 hash of the drop name schema: type: string - name: version in: path required: true description: Version number schema: type: integer minimum: 1 - name: I_agree_with_terms_and_conditions in: query required: true description: Must be true to confirm agreement to terms and conditions schema: type: boolean responses: '200': description: Drop version data content: application/json: schema: type: object properties: version: type: integer minimum: 0 exclusiveMinimum: true description: Version number example: 2 payload: type: string description: 'For private drops: hex-encoded AES-GCM ciphertext (opaque). For public drops: raw content string, interpreted by mimeType.' iv: type: string nullable: true format: hex pattern: ^[a-f0-9]{24}$ description: Hex-encoded IV (12 bytes = 24 hex chars), null for public drops example: 00112233445566778899aabb createdAt: type: string format: date-time description: ISO 8601 timestamp when this version was created example: '2026-04-18T10:30:00.000Z' required: - version - payload - iv - createdAt '403': description: Terms not agreed content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error '404': description: Drop or version not found content: application/json: schema: type: object properties: error: type: object properties: code: type: string description: Error code (machine-readable) example: NOT_FOUND message: type: string description: Error message (human-readable) example: Drop not found required: - code - message required: - error /docs/openapi.json: get: tags: - Documentation summary: OpenAPI Specification description: Returns the OpenAPI 3.1 specification for the v1 API responses: '200': description: OpenAPI specification content: application/json: schema: type: object additionalProperties: nullable: true /docs: get: tags: - Documentation summary: Swagger UI description: Interactive API documentation using Swagger UI responses: '200': description: Swagger UI HTML page content: text/html: schema: {} externalDocs: url: https://dead-drop.xyz description: dead-drop website