How to Use picgo-server for REST API Image Uploads in PicList-Core

The picgo-server is a built-in HTTP service in PicList-Core that exposes REST endpoints for programmatic image uploads, allowing external tools to leverage the core PicGo upload engine without invoking the CLI directly.

The picgo-server provides a lightweight HTTP interface to PicList-Core's upload capabilities. By running this built-in server, you can integrate image hosting workflows into any application or automation script using standard HTTP requests. This guide explains how to start the server, authenticate requests, and interact with its API endpoints based on the source implementation in kuingsmile/piclist-core.

Starting the picgo-server

The server entry point is located at bin/picgo-server. When executed, it parses command-line arguments, initializes a PicGo instance via await PicGo.create(configPath), and launches an HTTP server that routes requests through a dedicated Router class.

Command-Line Options

Launch the server with the following optional flags:


# Default startup (looks for ~/.piclist/config.json)

picgo-server

# Custom configuration file

picgo-server -c /path/to/config.json

# Enable authentication with a secret key

picgo-server -k 123456

# Custom port and host (default is port 36677)

picgo-server -p 4000 -h 127.0.0.1

The argument parsing and server initialization logic resides in lines 74–84 of bin/picgo-server.

API Endpoints and Request Flow

The server implements a minimal router (defined in lines 1–34 of bin/picgo-server) that handles three primary endpoints:

  • GET / or GET /upload: Returns an HTML help page.
  • POST /upload: Accepts image uploads via multipart/form-data or JSON payloads.
  • GET /heartbeat or POST /heartbeat: Health-check endpoint returning { "success": true, "result": "alive" }.

Request Handling Pipeline

When a POST /upload request arrives, the server executes the following flow:

  1. Route Matching: The Router class dispatches the request to the handler defined at lines 79–89.
  2. Content Type Detection: The server distinguishes between multipart file uploads and JSON bodies (lines 12–14).
  3. Authentication: If a key was configured via -k, the server validates the key query parameter (lines 81–92).
  4. Dynamic Configuration: Optional picbed and configName query parameters trigger temporary uploader switching (lines 98–124).
  5. Upload Execution: The handler calls picgo.uploadReturnCtx() (defined in src/core/PicGo.ts at lines 58–88), which executes the core upload pipeline.
  6. Response Assembly: Results are wrapped in JSON ({ success: true, result: [...] }) at lines 33–49.
  7. Cleanup: Temporary files in ~/.piclist/serverTemp are removed and original configurations are restored (lines 75–84 and lines 176–184).

Authenticating Requests

Security is enforced through a simple token-based system. If you start the server with the -k (or --key) flag, every request must include the matching secret as a query parameter:

curl -F "file=@image.png" "http://127.0.0.1:36677/upload?key=123456"

The authorization check at lines 81–92 automatically exempts requests from the loopback interface (127.0.0.1), allowing local scripts to omit the key while requiring it for remote connections.

Selecting Uploaders Dynamically

You can override the default uploader for a specific request without modifying the configuration file. Two query parameters control this behavior:

  • picbed: Specifies the uploader plugin name (e.g., aws-s3, smms, github).
  • configName: Selects a named configuration profile for that uploader.

Example request targeting a specific configuration:

curl -F "file=@photo.jpg" \
  "http://127.0.0.1:36677/upload?key=123456&picbed=aws-s3&configName=prod"

As implemented in lines 98–124, the server temporarily switches the active uploader using picgo.saveConfig and changeCurrentUploader, performs the upload, then restores the previous settings (lines 176–184).

Client Integration Examples

Node.js with Axios

const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');

(async () => {
  const form = new FormData();
  form.append('file', fs.createReadStream('screenshot.png'));

  const resp = await axios.post(
    'http://127.0.0.1:36677/upload?key=123456',
    form,
    { headers: form.getHeaders() }
  );

  console.log('Uploaded URLs:', resp.data.result);
})();

cURL File Upload

curl -F "file=@/tmp/photo.jpg" \
     "http://127.0.0.1:36677/upload?key=123456"

Python with JSON Payload

import requests, json

payload = {
    "list": ["/home/user/Pictures/clipboard.png"]
}
resp = requests.post(
    "http://127.0.0.1:36677/upload?key=123456",
    data=json.dumps(payload),
    headers={"Content-Type": "application/json"}
)
print(resp.json())

If you omit the list parameter, the server invokes picgo.uploadReturnCtx() without arguments, which automatically captures and uploads the current clipboard image using the logic in src/utils/getClipboardImage.ts.

Summary

  • Launch the server using picgo-server with optional -c (config), -k (key), and -p (port) flags.
  • Send images to POST /upload using either multipart form data or JSON with a list of file paths.
  • Authenticate by appending the key query parameter when the server is started with -k.
  • Target specific uploaders dynamically using picbed and configName query parameters.
  • Receive standardized JSON responses containing the array of uploaded URLs or error messages.

Frequently Asked Questions

How do I secure the picgo-server API from unauthorized access?

Start the server with the -k flag followed by a secret token. According to the source code in bin/picgo-server (lines 81–92), every incoming request must then include ?key=YOUR_SECRET in the URL. Requests from localhost (127.0.0.1) are automatically trusted and may omit the key.

Can I upload images directly from the clipboard using the API?

Yes. Send a POST /upload request with a JSON body omitting the list parameter, or include an empty list. The server calls picgo.uploadReturnCtx() without arguments, which triggers the clipboard reading mechanism implemented in src/utils/getClipboardImage.ts and uploads the captured image.

How does the server handle temporary configuration changes?

When you provide picbed and configName query parameters, the server temporarily overwrites the active uploader configuration using picgo.saveConfig (lines 98–124). After the upload completes—whether successful or not—the cleanup routine at lines 176–184 restores the original configuration to prevent side effects on subsequent requests.

What is the default port and host for picgo-server?

By default, the server binds to port 36677 on all interfaces. You can customize this using the -p flag for the port and -h flag for the host (e.g., -h 127.0.0.1 to restrict to localhost only). The default configuration lookup path is ~/.piclist/config.json.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →