A lightweight, anonymous JSON storage API with real-time updates. Create ephemeral databases, define schemas, and store JSON documents with automatic quota management and expiration.
- Anonymous Database Creation - No authentication required to create a database
- Two-Tier Authentication - Each database gets separate read and write keys
- Schema Validation - Define schemas with string, number, and boolean types
- CRUD Operations - Full create, read, update, delete support for documents
- Real-Time Events - Server-Sent Events (SSE) for live data updates
- Quota Management - Per-database storage limits with automatic tracking
- Auto-Expiry - Databases automatically deleted after 30 days of inactivity
- Filtering & Pagination - Query documents with filters and limit/offset
- Zero Configuration - Works out of the box with sensible defaults
# Clone the repository
git clone <repository-url>
cd jsondrop
# Start the server
docker-compose up -d
# Server is now running on http://localhost:8080docker build -t jsondrop .
docker run -d -p 8080:8080 -v jsondrop-data:/app/data jsondrop# Install dependencies
go mod download
# Run the server
go run cmd/server/main.gocurl -X POST http://localhost:8080/api/databasesResponse:
{
"database_id": "db_abc123xyz",
"write_key": "wk_secretwritekey123",
"read_key": "rk_secretreadkey456"
}Important: Save these keys! They cannot be recovered.
curl -X POST http://localhost:8080/api/databases/db_abc123xyz/schemas/users \
-H "Authorization: Bearer wk_secretwritekey123" \
-H "Content-Type: application/json" \
-d '{
"fields": {
"name": "string",
"age": "number",
"active": "bool"
}
}'curl -X POST http://localhost:8080/api/databases/db_abc123xyz/users/ \
-H "Authorization: Bearer wk_secretwritekey123" \
-H "Content-Type: application/json" \
-d '{
"data": {
"name": "Alice",
"age": 25,
"active": true
}
}'Response:
{
"id": "doc_xyz789",
"collection": "users",
"data": {
"name": "Alice",
"age": 25,
"active": true
},
"created_at": "2025-10-20T20:00:00Z",
"updated_at": "2025-10-20T20:00:00Z"
}# Get all documents
curl -H "Authorization: Bearer rk_secretreadkey456" \
"http://localhost:8080/api/databases/db_abc123xyz/users/"
# With pagination
curl -H "Authorization: Bearer rk_secretreadkey456" \
"http://localhost:8080/api/databases/db_abc123xyz/users/?limit=10&offset=0"
# With filters (exact match)
curl -H "Authorization: Bearer rk_secretreadkey456" \
"http://localhost:8080/api/databases/db_abc123xyz/users/?active=true"
# With IN list (OR logic)
curl -H "Authorization: Bearer rk_secretreadkey456" \
"http://localhost:8080/api/databases/db_abc123xyz/users/?name=Alice&name=Bob"curl -X PUT http://localhost:8080/api/databases/db_abc123xyz/users/doc_xyz789 \
-H "Authorization: Bearer wk_secretwritekey123" \
-H "Content-Type: application/json" \
-d '{
"data": {
"name": "Alice Smith",
"age": 26,
"active": false
}
}'curl -X DELETE http://localhost:8080/api/databases/db_abc123xyz/users/doc_xyz789 \
-H "Authorization: Bearer wk_secretwritekey123"# Listen to all database events
curl -N -H "Authorization: Bearer rk_secretreadkey456" \
http://localhost:8080/api/databases/db_abc123xyz/events
# Listen to collection-specific events
curl -N -H "Authorization: Bearer rk_secretreadkey456" \
http://localhost:8080/api/databases/db_abc123xyz/users/eventsEvent Types:
schema_created- New collection createdschema_deleted- Collection deletedinsert- Document createdupdate- Document updateddelete- Document deleted
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/databases |
None | Create a new database |
| DELETE | /api/databases/{id} |
Write | Delete database |
| GET | /api/databases/{id}/events |
Read/Write | SSE stream (all events) |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/databases/{id}/schemas/{name} |
Write | Create schema |
| DELETE | /api/databases/{id}/schemas/{name} |
Write | Delete schema |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/databases/{id}/{collection}/ |
Read/Write | Query documents |
| POST | /api/databases/{id}/{collection}/ |
Write | Insert document |
| PUT | /api/databases/{id}/{collection}/{docId} |
Write | Update document |
| DELETE | /api/databases/{id}/{collection}/{docId} |
Write | Delete document |
| GET | /api/databases/{id}/{collection}/events |
Read/Write | SSE stream (collection) |
Configure via environment variables:
| Variable | Default | Description |
|---|---|---|
PORT |
8080 |
HTTP server port |
DB_BASE_DIR |
./data |
Base directory for database files |
CATALOG_DB_PATH |
./data/catalog.db |
Catalog database path |
CORS_ORIGINS |
* |
Allowed CORS origins (comma-separated) |
DEFAULT_QUOTA_MB |
100 |
Default quota per database (MB) |
EXPIRY_DAYS |
30 |
Days before inactive database expires |
EXPIRY_CHECK_INTERVAL |
24h |
How often to check for expired databases |
Example:
PORT=3000 \
CORS_ORIGINS="https://example.com,https://app.example.com" \
DEFAULT_QUOTA_MB=250 \
go run cmd/server/main.go- Language: Go 1.24
- Router: Chi v5
- Database: SQLite (one file per database + catalog)
- Authentication: API keys (read-only and read-write)
- Real-Time: Server-Sent Events (SSE)
jsondrop/
├── cmd/server/ # Main entry point
├── internal/
│ ├── api/ # HTTP handlers and routing
│ ├── config/ # Configuration management
│ ├── database/ # SQLite operations
│ ├── events/ # SSE broadcasting
│ └── models/ # Data structures
├── Dockerfile # Multi-stage Docker build
├── docker-compose.yml # Docker Compose configuration
└── CLAUDE.md # Development guidelines
- Go 1.24 or later
- SQLite3
- Docker (optional)
go test ./...go build -o bin/jsondrop cmd/server/main.go
./bin/jsondrop- API Keys: Treat write keys as secrets. They provide full database access.
- Read Keys: Can query data and listen to events, but cannot modify.
- CORS: Configure
CORS_ORIGINSproperly for production (don't use*). - Rate Limiting: Handle externally (e.g., via reverse proxy like Traefik).
- Quota Enforcement: Prevents abuse through storage limits.
- Auto-Expiry: Automatically cleans up inactive databases.
- Update
CORS_ORIGINSindocker-compose.yml - Configure quotas and expiry as needed
- Run:
docker-compose up -d
Use Traefik, Nginx, or Caddy for:
- SSL/TLS termination
- Rate limiting
- Load balancing
- Access logs
upstream jsondrop {
server localhost:8080;
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://jsondrop;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# For SSE support
proxy_buffering off;
proxy_cache off;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
}
}- Prototyping: Quick backend for frontend development
- Temporary Data Storage: Forms, surveys, event registration
- Real-Time Dashboards: Live data updates via SSE
- Testing: Mock data for integration tests
- Webhooks: Store webhook payloads temporarily
- IoT Data Collection: Sensor data with automatic cleanup
- Storage: Limited by quota (default 100MB per database)
- Filtering: In-memory filtering (not optimized for large datasets)
- No Indexes: No custom indexes on JSON fields
- Single Server: No built-in clustering or replication
- Temporary: Databases expire after inactivity
- Custom indexes on JSON fields
- Advanced query operators ($gt, $lt, $regex)
- Webhooks for change notifications
- Database backup/restore API
- Multi-region support
- GraphQL endpoint
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
MIT
- Issues: GitHub Issues
- Documentation: See
CLAUDE.mdfor development guidelines - Questions: Open a discussion or issue