REST API documentation
REST API for VoidPaste. Production base: https://voidpaste.com — versioned routes under /api/v1.
Base URL
- Base:
https://voidpaste.com(web + API same origin) - Versioned routes:
/api/v1/… - Health:
GET /health,GET /ready - Raw alias:
GET /raw/{public_id}(same as/api/v1/pastes/{id}/raw) - Download alias:
GET /download/{public_id}
Authentication
- Session cookies — register/login set HttpOnly
vp_session; usecredentials: "include"from the web origin. Cookie-authenticated mutations also needX-CSRF-Tokenmatching thevp_csrfcookie (GET /api/v1/auth/csrf). Bearer API keys skip CSRF. - API keys —
Authorization: Bearer vp_live_…(orvp_test_…). Scopes are enforced:pastes:readfor reads,pastes:writefor mutations (*= all). Key management requires a session cookie. - Paste passwords: header
X-Paste-Password(preferred); query?password=also accepted for raw tooling. - Email verify: web page
/verify-email?token=…posts toPOST /api/v1/auth/verify-email. Mail From:[email protected].
Errors
{
"error": {
"code": "rate_limited",
"message": "Too many requests",
"request_id": "01JABC..."
}
}Limits
VoidPaste is free. Each paste is limited to 1 MB (1,048,576 bytes). Rate limits apply. There are no paid tiers. Optional Idempotency-Key on POST /api/v1/pastes replays the JSON response for 24h (Redis).
Privacy modes
public— anyone; may be discoverable laterunlisted— secret URL (default when omitted)private— owner only (requires auth)password— requirespasswordfield (otherwise 400 if a password is sent with another visibility)- Client-encrypted —
client_encrypted: true; server stores ciphertext only; fragment key stays in the share URL
Pastes
| Method | Path | Notes |
|---|---|---|
| POST | /api/v1/pastes | Create (anon or auth). Response: { paste, warnings } |
| GET | /api/v1/pastes/{id} | { paste, burned } |
| GET | /api/v1/pastes/{id}/raw | text/plain |
| GET | /api/v1/pastes/{id}/download | attachment |
| PATCH | /api/v1/pastes/{id} | Owner edit |
| DELETE | /api/v1/pastes/{id} | Owner soft-delete |
| GET | /api/v1/me/pastes | Authenticated list |
| GET | /api/v1/pastes/{id}/versions | Owner versions |
Expiration presets: never, 10m, 1h, 1d, 1w, 1M (~30 days). Also relative durations and RFC3339. Burn-after-reading and max views are race-safe: the first successful GET that burns returns { paste, burned: true }; later opens get gone/not found.
Auth
POST /api/v1/auth/registerPOST /api/v1/auth/verify-emailPOST /api/v1/auth/loginPOST /api/v1/auth/logoutPOST /api/v1/auth/logout-allPOST /api/v1/auth/password-reset/requestPOST /api/v1/auth/password-reset/confirmGET /api/v1/auth/meGET /api/v1/auth/providers
API keys & collections
POST /api/v1/api-keys— secret returned onceGET /api/v1/api-keysDELETE /api/v1/api-keys/{id}- Collections:
/api/v1/collections(auth) - Reports:
POST /api/v1/reports
Example
curl -X POST "https://voidpaste.com/api/v1/pastes" \
-H "Authorization: Bearer vp_live_..." \
-H "Content-Type: application/json" \
-d '{"content":"hello","visibility":"unlisted","expiration":"1d"}'Full OpenAPI: repo docs/api/openapi.yaml. Also see CLI.