# Palette Fast, self-hosted pastebin with paste cans, password lock, expiry, custom URLs, and an API-first design. ## Quick start ```bash go build -o palette . ./palette # UI at http://localhost:8080 ``` ## Docker ```bash docker build -t palette . docker run -p 8080:8080 -v palette-data:/data palette ``` ## Configuration | Env var | Default | Description | |---|---|---| | `PALETTE_ADDR` | `:8080` | Listen address | | `PALETTE_DB` | `palette.db` | SQLite database path | | `PALETTE_MAX_TEXT` | `5242880` | Max paste size in bytes (5 MB) | | `PALETTE_MAX_ITEM` | `26214400` | Max can item size in bytes (25 MB) | ## API ### Create paste ```bash curl -X POST http://localhost:8080/api/pastes \ -H "Content-Type: application/json" \ -d '{ "content": "print(hello)", "title": "my snippet", "language": "python", "expires_in": "168h", "password": "optional", "custom_slug": "optional", "burn_after_read": false, "visibility": "public" }' ``` Response includes `id`, `url`, `raw_url`, `api_url`, and a one-time `deletion_token`. ### Get paste ```bash curl http://localhost:8080/api/pastes/{id} # password-protected pastes: curl "http://localhost:8080/api/pastes/{id}?password=secret" # or via header: X-Paste-Password: secret ``` ### Raw content ```bash curl http://localhost:8080/raw/{id} ``` ### Soft delete ```bash curl -X DELETE http://localhost:8080/api/pastes/{id} ``` ### Hard delete (requires deletion token) ```bash curl -X DELETE "http://localhost:8080/api/pastes/{id}/redeem?token=TOKEN" ``` ### Public history ```bash curl "http://localhost:8080/api/public?limit=25&offset=0" ``` ### Create can (bundle of items) ```bash curl -X POST http://localhost:8080/api/pastes/can \ -F "title=My bundle" \ -F "expires_in=48h" \ -F 'json_items=[{"title":"notes.txt","content":"some notes"}]' \ -F "files=@screenshot.png" \ -F "files=@log.txt" ``` ### Get can + items ```bash curl http://localhost:8080/api/cans/{id} curl http://localhost:8080/api/cans/{id}/items/{item_id} ``` ## Expiry and deletion - Expired pastes are soft-deleted by a background sweeper (runs every minute). - Soft-deleted pastes are hard-deleted after a 7-day grace period. - Deletion tokens allow immediate hard delete. - Burn-after-read pastes are soft-deleted on first read. ## Web pages - `/new` — create a paste - `/history` — public paste history - `/{id}` — view a paste - `/unlock/{id}` — password gate for protected pastes - `/raw/{id}` — raw content with original content type ## CI Gitea Actions workflow at `.gitea/workflows/ci.yml`: - On push to main: `go vet` + `go test` - On tags: build and push Docker image to `git.archfox.org/poslop/palette`