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

> Learn to use picgo-server for REST API image uploads with PicList-Core. Programmatically upload images using the PicGo engine without the CLI.

- Repository: [Kuingsmile/piclist-core](https://github.com/kuingsmile/piclist-core)
- Tags: tutorial
- Published: 2026-03-05

---

**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:

```bash

# 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`](https://github.com/kuingsmile/piclist-core/blob/main/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:

```bash
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:

```bash
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

```javascript
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

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

```

### Python with JSON Payload

```python
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`](https://github.com/kuingsmile/piclist-core/blob/main/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`](https://github.com/kuingsmile/piclist-core/blob/main/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`.