API Reference
CyberPaste provides a RESTful API for creating and managing pastes, as well as administrative functions. All API endpoints return JSON responses.
Base URL
All API endpoints are relative to your CyberPaste instance base URL. For example, if your instance is hosted at https://paste.example.com, the API base URL would be https://paste.example.com/api.
Authentication
Most API endpoints require authentication via Discord OAuth2. Admin endpoints require owner permissions (Discord User ID matching the OwnerID in config.yml).
Authentication Flow
- User visits
/auth/discord - Redirected to Discord OAuth
- User authorizes the application
- Redirected to
/auth/discord/callback - Session is established
- User can access protected endpoints
Rate Limiting
All endpoints are rate-limited to prevent abuse. Default limits:
- Web Endpoints: 100 requests per 60 minutes
- API Endpoints: 100 requests per 60 minutes
Rate limits are configurable via the admin panel. When rate limit is exceeded, the API returns a 429 Too Many Requests status code.
Error Responses
All error responses follow this format:
{
"error": "Error message description"
}
Public Endpoints
Get CSRF Token
Get a CSRF token for form submissions.
Endpoint: GET /api/csrf-token
Authentication: Not required
Response:
{
"csrfToken": "csrf-token-string"
}
Example:
curl -X GET https://paste.example.com/api/csrf-token
Create Paste
Create a new paste.
Endpoint: POST /api/paste
Authentication: Not required
Rate Limit: Web rate limit applies
Request Body:
{
"content": "Your paste content here",
"maxViews": 10,
"password": "optional-password"
}
Parameters:
content(string, required): The paste contentmaxViews(number, optional): Maximum number of views before expirationpassword(string, optional): Password to protect the paste
Response (Success):
{
"success": true,
"slug": "aBc123Xy",
"url": "/paste/aBc123Xy"
}
Response (Error):
{
"error": "Content cannot be empty"
}
Status Codes:
200: Paste created successfully400: Invalid request (empty content, content too long)429: Rate limit exceeded500: Internal server error
Example:
curl -X POST https://paste.example.com/api/paste \
-H "Content-Type: application/json" \
-d '{
"content": "console.log(\"Hello, World!\");",
"maxViews": 10,
"password": "mypassword"
}'
Constraints:
- Maximum paste size: Configurable (default: 1MB)
- Content cannot be empty
- Slug is auto-generated (8 characters, alphanumeric)
View Paste
View a paste by its slug.
Endpoint: GET /paste/:slug
Authentication: Not required (unless password protected)
Rate Limit: Web rate limit applies
URL Parameters:
slug(string, required): The paste slug/identifier
Response: HTML page (not JSON)
Status Codes:
200: Paste found and displayed404: Paste not found410: Paste expired (reached max views)429: Rate limit exceeded
Example:
curl -X GET https://paste.example.com/paste/aBc123Xy
Notes:
- If paste is password-protected, a password form is displayed
- View count is incremented on each successful view
- Pastes expire when
viewsCount >= maxViews
Verify Paste Password
Verify password for a password-protected paste.
Endpoint: POST /paste/:slug/verify
Authentication: Not required
Rate Limit: Web rate limit applies
URL Parameters:
slug(string, required): The paste slug/identifier
Request Body:
{
"password": "paste-password"
}
Response (Success):
{
"success": true
}
Response (Error):
{
"error": "Incorrect password"
}
Status Codes:
200: Password correct400: Password required401: Incorrect password404: Paste not found429: Rate limit exceeded500: Internal server error
Example:
curl -X POST https://paste.example.com/paste/aBc123Xy/verify \
-H "Content-Type: application/json" \
-d '{
"password": "mypassword"
}'
Notes:
- Password is validated using bcrypt
- Successful verification stores authorization in session
- Authorization persists for the session duration
Authentication Endpoints
Discord OAuth
Endpoint: GET /auth/discord
Authentication: Not required
Description: Initiates Discord OAuth2 authentication flow.
Response: Redirects to Discord OAuth authorization page.
Discord OAuth Callback
Endpoint: GET /auth/discord/callback
Authentication: Not required
Description: Handles Discord OAuth2 callback.
Response: Redirects to homepage after successful authentication.
Error Handling:
- Redirects to
/?error=auth_failedon authentication failure - Redirects to
/?error=rate_limitedon Discord rate limiting - Redirects to
/?error=no_userif no user returned
Logout
Endpoint: GET /auth/logout
Authentication: Not required
Description: Logs out the current user and destroys the session.
Response: Redirects to homepage.
Auth Status
Endpoint: GET /auth/status
Authentication: Not required
Description: Check current authentication status.
Response:
{
"authenticated": true,
"user": {
"id": "123456789012345678",
"username": "username#1234"
},
"session": {
"passport": {
"user": "user-id"
}
}
}
Admin Endpoints
All admin endpoints require:
- Authentication (Discord OAuth)
- Owner permissions (Discord User ID must match
OwnerIDin config)
Get Settings
Get current application settings.
Endpoint: GET /api/settings
Authentication: Required (Owner only)
Rate Limit: API rate limit applies
Response:
{
"siteName": "CyberPaste",
"favIcon": "/images/favicon.ico",
"logo": "/images/logo.png",
"siteDescription": "A modern, secure paste service",
"primaryColor": "#0d1117",
"secondaryColor": "#ffd000",
"webRateLimit": 100,
"webRateLimitWindow": 60,
"maxPasteSize": 1,
"apiAccess": true,
"apiRateLimit": 100,
"apiRateLimitWindow": 60,
"apiKeyProtection": false,
"autoDeleteInactive": "never",
"syntaxHighlighting": true,
"slugLength": 8,
"slugCharacterSet": "alphanumeric"
}
Status Codes:
200: Settings retrieved successfully403: Access denied (not owner)429: Rate limit exceeded500: Internal server error
Example:
curl -X GET https://paste.example.com/api/settings \
-H "Cookie: connect.sid=your-session-cookie"
Update General Settings
Update general application settings.
Endpoint: POST /api/settings/general
Authentication: Required (Owner only)
Rate Limit: API rate limit applies
Request Body:
{
"siteName": "My CyberPaste",
"secondaryColor": "#00ff00",
"siteDescription": "My custom paste service"
}
Parameters:
siteName(string, optional): Site namesecondaryColor(string, optional): Secondary color (hex format)siteDescription(string, optional): Site description
Response (Success):
{
"success": true,
"message": "General settings updated successfully"
}
Status Codes:
200: Settings updated successfully403: Access denied (not owner)429: Rate limit exceeded500: Internal server error
Example:
curl -X POST https://paste.example.com/api/settings/general \
-H "Content-Type: application/json" \
-H "Cookie: connect.sid=your-session-cookie" \
-d '{
"siteName": "My CyberPaste",
"secondaryColor": "#00ff00"
}'
Update Security Settings
Update security-related settings.
Endpoint: POST /api/settings/security
Authentication: Required (Owner only)
Rate Limit: API rate limit applies
Request Body:
{
"webRateLimit": 200,
"webRateLimitWindow": 30,
"maxPasteSize": 2,
"apiAccess": true,
"apiRateLimit": 200,
"apiRateLimitWindow": 30,
"apiKeyProtection": false
}
Parameters:
webRateLimit(number, optional): Web rate limit (requests per window)webRateLimitWindow(number, optional): Web rate limit window (minutes)maxPasteSize(number, optional): Maximum paste size (MB)apiAccess(boolean, optional): Enable/disable API accessapiRateLimit(number, optional): API rate limit (requests per window)apiRateLimitWindow(number, optional): API rate limit window (minutes)apiKeyProtection(boolean, optional): Enable/disable API key protection
Response (Success):
{
"success": true,
"message": "Security settings updated successfully"
}
Status Codes:
200: Settings updated successfully403: Access denied (not owner)429: Rate limit exceeded500: Internal server error
Notes:
- Rate limiters are updated immediately after saving
- Changes take effect immediately
Update Advanced Settings
Update advanced application settings.
Endpoint: POST /api/settings/advanced
Authentication: Required (Owner only)
Rate Limit: API rate limit applies
Request Body:
{
"autoDeleteInactive": "30",
"syntaxHighlighting": true,
"slugLength": 10,
"slugCharacterSet": "lowercase"
}
Parameters:
autoDeleteInactive(string, optional): Auto-delete inactive pastes ("never", "7", "30", "90", "180", "365")syntaxHighlighting(boolean, optional): Enable/disable syntax highlightingslugLength(number, optional): Length of paste slugsslugCharacterSet(string, optional): Character set for slugs ("alphanumeric", "lowercase", "numbers", "letters")
Response (Success):
{
"success": true,
"message": "Advanced settings updated successfully"
}
Status Codes:
200: Settings updated successfully403: Access denied (not owner)429: Rate limit exceeded500: Internal server error
Get Statistics
Get application statistics.
Endpoint: GET /api/stats
Authentication: Required (Owner only)
Rate Limit: API rate limit applies
Response:
{
"totalPastes": 1250,
"totalViews": 5432,
"last30Days": 45,
"apiUsage": 0,
"avgPasteSize": "1250 characters",
"mostViewed": 150,
"avgViews": 4.3,
"storageUsed": "1.5MB"
}
Status Codes:
200: Statistics retrieved successfully403: Access denied (not owner)429: Rate limit exceeded500: Internal server error
Example:
curl -X GET https://paste.example.com/api/stats \
-H "Cookie: connect.sid=your-session-cookie"
Clear All Pastes
Delete all pastes from the database.
Endpoint: POST /api/admin/clear-pastes
Authentication: Required (Owner only)
Rate Limit: API rate limit applies
Request Body: None
Response (Success):
{
"success": true,
"message": "Successfully cleared 1250 pastes",
"deletedCount": 1250
}
Status Codes:
200: Pastes cleared successfully403: Access denied (not owner)429: Rate limit exceeded500: Internal server error
Warning: This action is irreversible!
Example:
curl -X POST https://paste.example.com/api/admin/clear-pastes \
-H "Cookie: connect.sid=your-session-cookie"
Upload Logo
Upload a new logo for the site.
Endpoint: POST /api/upload/logo
Authentication: Required (Owner only)
Rate Limit: API rate limit applies
Content-Type: multipart/form-data
Request Body:
logo(file, required): Logo image file (JPEG, PNG, GIF, SVG, ICO)- Maximum file size: 2MB
Response (Success):
{
"success": true,
"message": "Logo uploaded successfully",
"logoPath": "/uploads/images/logo-1234567890-123456789.png"
}
Status Codes:
200: Logo uploaded successfully400: No file uploaded or invalid file type403: Access denied (not owner)429: Rate limit exceeded500: Internal server error
Example:
curl -X POST https://paste.example.com/api/upload/logo \
-H "Cookie: connect.sid=your-session-cookie" \
-F "logo=@/path/to/logo.png"
Notes:
- Old logo is automatically deleted (if not default)
- Supported formats: JPEG, PNG, GIF, SVG, ICO
- File is stored in
public/uploads/images/
Upload Favicon
Upload a new favicon for the site.
Endpoint: POST /api/upload/favicon
Authentication: Required (Owner only)
Rate Limit: API rate limit applies
Content-Type: multipart/form-data
Request Body:
favicon(file, required): Favicon image file (JPEG, PNG, GIF, SVG, ICO)- Maximum file size: 2MB
Response (Success):
{
"success": true,
"message": "Favicon uploaded successfully",
"faviconPath": "/uploads/images/favicon-1234567890-123456789.ico"
}
Status Codes:
200: Favicon uploaded successfully400: No file uploaded or invalid file type403: Access denied (not owner)429: Rate limit exceeded500: Internal server error
Example:
curl -X POST https://paste.example.com/api/upload/favicon \
-H "Cookie: connect.sid=your-session-cookie" \
-F "favicon=@/path/to/favicon.ico"
Notes:
- Old favicon is automatically deleted (if not default)
- Supported formats: JPEG, PNG, GIF, SVG, ICO
- File is stored in
public/uploads/images/
Error Codes
| Status Code | Description |
|---|---|
200 | Success |
400 | Bad Request (invalid parameters) |
401 | Unauthorized (authentication required) |
403 | Forbidden (insufficient permissions) |
404 | Not Found (resource doesn't exist) |
410 | Gone (paste expired) |
429 | Too Many Requests (rate limit exceeded) |
500 | Internal Server Error |
Rate Limiting Headers
When rate limiting is active, the following headers are included in responses:
X-RateLimit-Limit: Maximum number of requests allowedX-RateLimit-Remaining: Number of requests remainingX-RateLimit-Reset: Timestamp when the rate limit resets
Best Practices
- Handle Errors Gracefully: Always check for error responses and handle them appropriately
- Respect Rate Limits: Implement exponential backoff when hitting rate limits
- Use HTTPS: Always use HTTPS in production to protect sensitive data
- Validate Input: Validate all input on the client side before sending requests
- Store Sessions Securely: Use secure, httpOnly cookies for session management
- Monitor API Usage: Track your API usage to avoid hitting rate limits
Next Steps: Check out the FAQ for common questions or see Features for more information.