2026-09-08 21:41:29 -05:00

Palette

Fast, self-hosted pastebin with paste cans, password lock, expiry, custom URLs, and an API-first design.

Quick start

go build -o palette .
./palette
# UI at http://localhost:8080

Docker

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

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

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

curl http://localhost:8080/raw/{id}

Soft delete

curl -X DELETE http://localhost:8080/api/pastes/{id}

Hard delete (requires deletion token)

curl -X DELETE "http://localhost:8080/api/pastes/{id}/redeem?token=TOKEN"

Public history

curl "http://localhost:8080/api/public?limit=25&offset=0"

Create can (bundle of items)

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

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
S
Description
Fast self-hosted pastebin with small file support
Readme AGPL-3.0
106 MiB
v0.5.1
Latest
2026-09-18 18:50:51 +00:00
Languages
Go 61.1%
HTML 14.4%
JavaScript 13.3%
CSS 11%
Dockerfile 0.2%