Skip to main content

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

  1. User visits /auth/discord
  2. Redirected to Discord OAuth
  3. User authorizes the application
  4. Redirected to /auth/discord/callback
  5. Session is established
  6. 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 content
  • maxViews (number, optional): Maximum number of views before expiration
  • password (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 successfully
  • 400: Invalid request (empty content, content too long)
  • 429: Rate limit exceeded
  • 500: 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 displayed
  • 404: Paste not found
  • 410: 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 correct
  • 400: Password required
  • 401: Incorrect password
  • 404: Paste not found
  • 429: Rate limit exceeded
  • 500: 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_failed on authentication failure
  • Redirects to /?error=rate_limited on Discord rate limiting
  • Redirects to /?error=no_user if 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:

  1. Authentication (Discord OAuth)
  2. Owner permissions (Discord User ID must match OwnerID in 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 successfully
  • 403: Access denied (not owner)
  • 429: Rate limit exceeded
  • 500: 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 name
  • secondaryColor (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 successfully
  • 403: Access denied (not owner)
  • 429: Rate limit exceeded
  • 500: 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 access
  • apiRateLimit (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 successfully
  • 403: Access denied (not owner)
  • 429: Rate limit exceeded
  • 500: 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 highlighting
  • slugLength (number, optional): Length of paste slugs
  • slugCharacterSet (string, optional): Character set for slugs ("alphanumeric", "lowercase", "numbers", "letters")

Response (Success):

{
"success": true,
"message": "Advanced settings updated successfully"
}

Status Codes:

  • 200: Settings updated successfully
  • 403: Access denied (not owner)
  • 429: Rate limit exceeded
  • 500: 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 successfully
  • 403: Access denied (not owner)
  • 429: Rate limit exceeded
  • 500: 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 successfully
  • 403: Access denied (not owner)
  • 429: Rate limit exceeded
  • 500: 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 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 successfully
  • 400: No file uploaded or invalid file type
  • 403: Access denied (not owner)
  • 429: Rate limit exceeded
  • 500: 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 successfully
  • 400: No file uploaded or invalid file type
  • 403: Access denied (not owner)
  • 429: Rate limit exceeded
  • 500: 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 CodeDescription
200Success
400Bad Request (invalid parameters)
401Unauthorized (authentication required)
403Forbidden (insufficient permissions)
404Not Found (resource doesn't exist)
410Gone (paste expired)
429Too Many Requests (rate limit exceeded)
500Internal Server Error

Rate Limiting Headers

When rate limiting is active, the following headers are included in responses:

  • X-RateLimit-Limit: Maximum number of requests allowed
  • X-RateLimit-Remaining: Number of requests remaining
  • X-RateLimit-Reset: Timestamp when the rate limit resets

Best Practices

  1. Handle Errors Gracefully: Always check for error responses and handle them appropriately
  2. Respect Rate Limits: Implement exponential backoff when hitting rate limits
  3. Use HTTPS: Always use HTTPS in production to protect sensitive data
  4. Validate Input: Validate all input on the client side before sending requests
  5. Store Sessions Securely: Use secure, httpOnly cookies for session management
  6. 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.