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