--- url: 'https://docs.picgo.app/cloud/account.md' --- # Account & Plans ## Sign up and log in PicGo Cloud supports the following login methods: * **GitHub** OAuth * **Google** OAuth You can log in from: * **Web portal**: visit [cloud.picgo.app](https://cloud.picgo.app) and click Log in. * **GUI app**: on the PicGo Cloud page, click "Log in" — a browser window opens for OAuth, and you're redirected back once done. See [PicGo Cloud in the GUI app](/gui/guide/picgo-cloud) for details. ## Account overview After logging in to [cloud.picgo.app](https://cloud.picgo.app), the Overview page shows: * Storage usage (used / limit) * File count (used / limit) * Current plan name and expiration date * Quick action shortcuts ![overview](https://pics.molunerfinn.com/doc/20260614204447416.png) You can also check your plan and usage from the GUI app. See [PicGo Cloud in the GUI app](/gui/guide/picgo-cloud). ## Plan comparison PicGo Cloud offers four plans. For current pricing, visit [picgo.app/pricing](https://picgo.app/pricing/). ### Storage & Files | | Free | Starter | Pro | Max | |---|---|---|---|---| | Max file items | 200 | 10,000 | 100,000 | Unlimited | | Total storage | 500 MB | 10 GB | 100 GB | 1 TB | | Max file size | 10 MB | 32 MB | 100 MB | 1 GB | | Upload rate limit | 10/min and 30/hour | 120/min | 180/min | 300/min | ### Advanced Features | | Free | Starter | Pro | Max | |---|---|---|---|---| | Custom domain | — | ✓ | ✓ | ✓ | ### Configuration | | Free | Starter | Pro | Max | |---|---|---|---|---| | Config sync history versions | 3 | 10 | 50 | 100 | | Config sync | ✓ | ✓ | ✓ | ✓ | | End-to-end encryption (E2EE) | ✓ | ✓ | ✓ | ✓ | ### Support | | Free | Starter | Pro | Max | |---|---|---|---|---| | Community support | ✓ | ✓ | ✓ | ✓ | | Priority support | — | ✓ | ✓ | ✓ | --- --- url: 'https://docs.picgo.app/gui/guide/advance.md' --- # Advanced Usage ## Upload using Command Line PicGo started supporting to use command line to call to PicGo clients for uploading since version 2.1.0. You can use `upload` to upload the image on your clipboard and use `upload xxx.jpg` to upload the image in the specific path. ### Windows For Windows users, you can upload your image using `PATH\PicGo.exe upload`, where 'PATH' is your PicGo path. ### macOS For MacOS users, you can upload your image using `/Applications/PicGo.app/Contents/MacOS/PicGo upload`. ### Linux For Linux users, you can upload your image using `PATH/PicGo.AppImage upload`, where 'PATH' is your PicGo path. ## PicGo-Server Usage PicGo has a small built-in server that receives HTTP requests from other applications to upload images since `2.2.0`. Default listening address: `127.0.0.1`. Default listening port: `36677` ### Upload the image on clipboard by calling HTTP * method: `POST` * url: `http://127.0.0.1:36677/upload` (use the default setting as an example) Then, you can upload your image. Returned data: ```json { "success": true, // or false "result": ["url"] } ``` ![](https://pics.molunerfinn.com/doc/picgo-server-upload-clipboard-file.png) ### Upload the specific image by calling HTTP * method: `POST` * url: `http://127.0.0.1:36677/upload` (use the default setting as an example) * request body: `{list: ['xxx.jpg']}` must be JSON-formatted ![](https://pics.molunerfinn.com/doc/71626614-1b359880-2c29-11ea-8efe-330f15116268.png) ```json { "success": true, // or false "result": ["url"] } ``` ### Upload images with HTTP form data Starting from `2.4.0`, PicGo-Server also accepts multipart form-data uploads. Thanks to [@happy-game](https://github.com/happy-game) for the contribution! * method: `POST` * url: `http://127.0.0.1:36677/upload` (using the default settings as an example) * request body: form-data whose key is `files` and value is the image file. Multiple files are supported at once. ![](https://pics.molunerfinn.com/doc/20251124162453718.png) ## PicGo Mobile App Integration If you want to use PicGo on your phone, install [flutter-picgo](https://github.com/PicGo/flutter-picgo). Thanks to [@hackycy](https://github.com/hackycy) for building it! Click the information bar button in the lower-left corner of the main window and choose "Generate image host configuration QR code". ![](https://pics.molunerfinn.com/doc/202108282131459.png) Then use flutter-picgo to scan the QR code and import your image host configuration instantly. ## PicGo Repair Toolbox Starting in `2.4.0`, you can find a "PicGo Repair Toolbox" entry under the `i` button on the main interface. Use it to troubleshoot and fix issues yourself when PicGo behaves abnormally. ![](https://pics.molunerfinn.com/doc/20251121171753489.png) ![](https://pics.molunerfinn.com/doc/20251121170523831.png) --- --- url: 'https://docs.picgo.app/ai.md' --- # AI To help AI better use and understand PicGo — whether for everyday usage, troubleshooting, or plugin development — PicGo provides the following resources: * [Skills](/ai/skills) * [llms.txt](#llms-txt) * [Markdown Docs](#markdown-docs) ## Skills [Skills](/ai/skills) are AI Agent skill descriptors that tell AI assistants when to use PicGo, how to call it, and how to handle results. Once installed, AI assistants automatically detect upload needs and call PicGo when you're writing docs or editing Markdown. Available Skills: | Skill | Function | Use Cases | | --- | --- | --- | | [picgo-upload](/ai/skills) | Upload images or files and get a shareable link | Insert images in docs, share screenshots, host file download links | ## llms.txt [llms.txt](https://llmstxt.org/) is a standard that helps LLMs discover and use project documentation. PicGo follows this standard and publishes two files: * [llms.txt](https://docs.picgo.app/llms.txt) — A structured index containing titles, links, and brief descriptions of all doc pages. ``` https://docs.picgo.app/llms.txt ``` * [llms-full.txt](https://docs.picgo.app/llms-full.txt) — The full content of all doc pages merged into a single file. ``` https://docs.picgo.app/llms-full.txt ``` Choose the right file for your scenario: * `llms.txt` is smaller and uses fewer tokens — good for letting AI fetch specific pages on demand. * `llms-full.txt` contains all documentation content so AI doesn't need to follow links one by one — ideal when you need comprehensive PicGo knowledge, but it consumes more tokens. Best used with AI tools that support large context windows. ## Markdown Docs Every page in the PicGo documentation has a corresponding `.md` plain-text version that can be fed directly to AI as context. You can click the "Copy page" button below the title of any doc page to get the Markdown content, or click the download button next to it to download the `.md` file. ``` https://docs.picgo.app/core/guide/getting-started.md ``` Provide the Markdown link or content to AI for precise understanding of a specific section — useful for targeted troubleshooting or looking up specific features. --- --- url: 'https://docs.picgo.app/cloud/albums.md' --- # Albums Albums are how PicGo Cloud organizes your uploaded files. You can view and manage them from both the web portal and the GUI app. ## Managing albums on the web After logging in to [cloud.picgo.app](https://cloud.picgo.app), go to the Albums page to: * Browse all uploaded files (with thumbnail previews) * Filter by file type, extension, etc. * Upload new files * Copy file links * Delete files ![album](https://pics.molunerfinn.com/doc/20260614200637625.png) ## Viewing albums in the GUI app The GUI app's album view can display files uploaded via PicGo Cloud, and supports copying links, deleting, and more. See [PicGo Cloud in the GUI app](/gui/guide/picgo-cloud) for details. ## Auto-import to Cloud Album Files uploaded through the PicGo Cloud uploader **always appear in the cloud album**, regardless of whether this toggle is on. This feature is for upload records from **non-PicGo-Cloud uploaders** (e.g. GitHub, AWS S3, Aliyun OSS). When enabled (paid plans only), every file you upload through PicGo — no matter which uploader — has its record (URL, filename, and other metadata) synced to PicGo Cloud's album automatically. PicGo Cloud only stores these records (metadata), not the actual files from other uploaders. The first time you turn it on, PicGo will ask whether you'd like to do a one-time import of your existing upload history. For the toggle location, step-by-step instructions, and more details, see [PicGo Cloud in the GUI app](/gui/guide/picgo-cloud). --- --- url: 'https://docs.picgo.app/core/api.md' --- # API Reference PicGo is a workflow-based application. Besides uploading (the core feature), PicGo also supports configuration management, logging, plugins, CLI interactions, and more. ## ctx The `ctx` passed into plugins is essentially the PicGo instance itself. `ctx` contains all objects and methods exposed by PicGo, so anything PicGo can do, your plugin can do via `ctx` as well. First, let's initialize a PicGo instance. ```js // Common JS const { PicGo } = require('picgo') // ES Module import { PicGo } from 'picgo' const picgo = new PicGo() ``` Next, we'll go through the PicGo APIs. ## upload(\[input]) PicGo's upload function. * input: Array\ || `undefined` * return: Promise<[IImgInfo\[\]](https://github.com/PicGo/PicGo-Core/blob/f133d57562c413b0b6f9a9ca9a93bf19c1768f1f/src/types/index.d.ts#L169-L178) | Error> `upload` supports two cases: * An empty array or `undefined` When it is an empty array or `undefined`, PicGo uploads the first image in the clipboard (due to cross-platform limitations, only **`png`** is supported). If there is no image in the clipboard, it throws an error. ::: tip Tip On Linux, you need to install `xclip`. ::: Example: ```js picgo.upload() // or picgo.upload([]) ``` * A non-empty array When it is a non-empty array, it works with PicGo's two built-in transformers and supports an array of paths or an array of base64 image strings. See the [Transformer](/core/dev-guide/cli#transformer) section. Example: ```js picgo.upload(['/xxx/xxx.jpg', '/yyy/yyy.png']) ``` From `v1.4.21+`, you can get the upload result from the return value: ```js const main = async () => { const res = await picgo.upload(['/xxx/xxx.jpg', '/yyy/yyy.png']) console.log(res) // [https://xxx.com/xxxxx.jpg, https://xxx.com/yyyyy.jpg] } ``` ## getConfig(\[name]) Get PicGo configuration. * name: string The default config looks like this: ```json { "picBed": { "current": "picgo-cloud" } } ``` You can call `getConfig()` to get the full config: ```js picgo.getConfig() ``` Output: ```json { "picBed": { "current": "picgo-cloud" }, "plugins": {...} } ``` Or you can read a specific config value: ```js picgo.getConfig('picBed.current') // supports nested lookup ``` Output: `picgo-cloud`. ## setConfig(config) Set PicGo config in memory without writing to the config file (context-only). * config: object Pass a valid object to update PicGo config. **This method does not write to the config file**. It will not change the config file after the workflow finishes, but it allows subsequent modules in the current workflow to read the updated values. ::: warning Note For GUI plugins, even though `setConfig` does not write to the config file, it stays in the config context. If your plugin needs to reset it, call `unsetConfig` (see below) at an appropriate time. ::: Example: ```js picgo.setConfig({ 'picBed.current': 'gitlab' }) ``` ## saveConfig(config) Set PicGo config and write it to the config file (persistent). * config: object Pass a valid object to update PicGo config. **This method writes to the config file** and affects what PicGo reads in subsequent runs. Example: ```js picgo.saveConfig({ 'picgo-plugin-test': { xxx: 'xxx', yyy: 'yyy' } }) ``` ## unsetConfig(key, propName) Remove a config entry from PicGo in memory without writing to the config file (context-only). * key: string * propName: string Pass the field you want to remove. **This method does not write to the config file** and will not change the config file after the workflow finishes. Example: Original config: ```json { "picgoPlugin": { "picgo-plugin-xxx": { ... } } } ``` ```js picgo.unsetConfig('picgoPlugin', 'picgo-plugin-xxx') ``` Config after `unsetConfig`: ```json { "picgoPlugin": {} } ``` ## removeConfig(key, propName) Remove a config entry and write the change to the config file (persistent). * key: string * propName: string Pass the field you want to remove. **This method writes to the config file** and affects what PicGo reads in subsequent runs. Example: Original config file: ```json { "picgoPlugin": { "picgo-plugin-xxx": { ... } } } ``` ```js picgo.removeConfig('picgoPlugin', 'picgo-plugin-xxx') ``` Config file after `removeConfig`: ```json { "picgoPlugin": {} } ``` ## emit(event, \[message]) Dispatch an event. Inherited from `EventEmitter`. * event: string * message: any Use `emit` to dispatch events, and use `on` to listen. ::: tip Tip A special event name is `notification`. PicGo and some plugins use it. See [Notifications](/core/dev-guide/cli#notifications). ::: Example: ```js picgo.emit('xxx', { message: 'xxx' }) ``` ## on(event, \[callback]) Listen to an event. Inherited from `EventEmitter`. * event: string * callback: function Use `on` to listen to events dispatched via `emit`. For built-in events, see [Event listeners](/core/guide/use-in-node#event-listeners). ```js picgo.on('xxx', message => { console.log(message) // { message: 'xxx' } }) ``` ## input * type: Array\ PicGo input. This is an array. ```js console.log(picgo.input) ``` ## output * type: Array\ PicGo output. This is an array. Typically, after an upload succeeds, you add `imgUrl` and `url` to each item in this array. See the built-in [smms](https://github.com/PicGo/PicGo-Core/blob/dev/src/plugins/uploader/smms.ts#L25-L37) Uploader. ::: warning Note After input goes through the Transformer, it enters the `output` array. It does not wait until the Uploader step to become `output`. ::: ```js console.log(picgo.output) ``` ## configPath * type: string Path to the PicGo config file. ```js console.log(picgo.configPath) ``` ## baseDir * type: string Directory that contains the PicGo config file. ```js console.log(picgo.baseDir) ``` ## VERSION * type: string Get the current PicGo version. ```js console.log(picgo.VERSION) // x.x.x ``` ## GUI\_VERSION * type: string || undefined If running inside PicGo GUI, this returns the PicGo GUI version. Otherwise it is `undefined`. ```js console.log(picgo.GUI_VERSION) // x.x.x ``` ## helper `helper` is PicGo's plugin container manager. It contains 5 module containers with the same API, but they run at different lifecycle stages (see [Plugin Development](/core/dev-guide/cli)). So we only detail `helper.transformer` below. ### helper.transformer #### register(id, plugin) * id: string * plugin: object If you just want to develop a simple plugin (instead of publishing it as an npm package—see [Plugin Development](/core/dev-guide/cli)), you only need to call `helper[module].register`. The first argument is the plugin id (within the same module container, ids must be unique; different module containers can reuse the same id). The second argument should be an object that includes at least a `handle` method for PicGo to call. If you also want [Handling Config](/core/dev-guide/cli#handling-config), you can add a `config` method for PicGo to call. Example: ```js picgo.helper.transformer.register('test', { handle (ctx) { return ctx }, config (ctx) { return [...] } }) ``` ### helper.uploader Same as above. ### helper.beforeTransformPlugins Same as above, but does not support `config`. ### helper.beforeUploadPlugins Same as above, but does not support `config`. ### helper.afterUploadPlugins Same as above, but does not support `config`. ## uploaderConfig Uploader multi-config manager. It manages per-uploader named configs stored under `uploader.` and keeps `picBed.` synced as a mirror of the active config. Config names are matched case-insensitively (whitespace is trimmed). ::: warning Note `uploaderConfig` reads and writes the local config file. All changes are persistent and affect subsequent runs. If you only need context-only changes for the current workflow, use `setConfig` / `unsetConfig` instead. ::: ### uploaderConfig.listUploaderTypes() List installed/available uploader types. ### uploaderConfig.getConfigList(type) Get all configs for an uploader type. ### uploaderConfig.getActiveConfig(type) Get the active config for an uploader type (may be `undefined` if no configs exist). ### uploaderConfig.use(type, configName?) Activate a config (by name) for an uploader type, and set it as the current uploader (`picBed.current` / `picBed.uploader`). ### uploaderConfig.createOrUpdate(type, configName?, configPatch?) Create a config or update an existing config (by name), and **activate it on save**. ### uploaderConfig.copy(type, configName, newConfigName) Copy a config into a new config name (**does not** switch current uploader). ### uploaderConfig.rename(type, oldName, newName) Rename a config. ### uploaderConfig.remove(type, configName) Remove a config. If you remove the last config, PicGo clears `picBed.` to avoid credential residue. Example: ```js // Switch to a named uploader config picgo.uploaderConfig.use('github', 'Work') // Create/update a config and activate it picgo.uploaderConfig.createOrUpdate('github', 'Work', { repo: 'user/repo' }) ``` ## Request.request **Since v1.5.0 this property is deprecated. Use [`ctx.request`](#request) instead.** The following is the pre-1.5.0 documentation, which is deprecated and no longer maintained: `Request.request` is a [Request-Promise-Native](https://github.com/request/request-promise-native) instance exposed by PicGo internally. It supports the same API as [request](https://github.com/request/request) and returns native Promises. ::: tip Tip When you use this object to send requests, it automatically reads the user's `proxy` value from PicGo config. This is useful for the core logic of an Uploader. ::: Example: ```js picgo.Request.request({ method: 'post', uri: 'xxxx', body: fs.readFileSync('yyy') }) ``` ## request ::: tip Tip When you use this object to send requests, it automatically reads the user's `proxy` value from PicGo config. This is useful for the core logic of an Uploader. ::: Starting from `v1.4.16`, the default request API changed from `ctx.Request.request` to `ctx.request`. * Before `v1.5.0`, the underlying implementation is [Request-Promise-Native](https://github.com/request/request-promise-native) * Since `v1.5.0`, the underlying implementation is [axios](https://github.com/axios/axios) We will not cover the legacy implementation here; instead we focus on the new one. In general, request options follow the [axios request config docs](https://github.com/axios/axios#request-config). However, for compatibility with the old `request` API, PicGo behaves slightly differently: 1. If the request config does not include `resolveWithFullResponse: true`, the returned value is `response.data` instead of the full `response` (which includes `status`, etc). 2. If you want the return value to be a `Buffer`, set `responseType` to `arraybuffer`. PicGo provides some helpful types: 1. `IReqOptions`: request config type with `resolveWithFullResponse: true`. 2. `IReqOptionsWithArrayBufferRes`: request config type with `resolveWithFullResponse: true` and `responseType: 'arraybuffer'`. 3. `IReqOptionsWithBodyResOnly`: the raw axios request config type; return value is only `response.data`. ::: tip Note `request` still returns a Promise, so `async/await` is recommended. ::: Example: ```ts import { IReqOptions } from 'picgo' const opt: IReqOptions = { method: 'post', url: 'xxxx', data: {}, resolveWithFullResponse: true // <-- set to true to return status, etc } interface IRes { // ... } const res = await ctx.request(opt) // { status: number, data: IRes } // ------------------------------ import { IReqOptionsWithArrayBufferRes } from 'picgo' const opt: IReqOptionsWithArrayBufferRes = { method: 'post', url: 'xxxx', data: {}, resolveWithFullResponse: true, // <-- set to true to return status, etc responseType: 'arraybuffer' // <-- set to arraybuffer so data is a Buffer } const res = await ctx.request(opt) // { status: number, data: Buffer } // ------------------------------ import { IReqOptionsWithBodyResOnly } from 'picgo' const opt: IReqOptionsWithBodyResOnly = { method: 'post', url: 'xxxx', data: {}, } interface IRes { // ... } const res: IRes = await ctx.request(opt) // IRes ``` ## cmd Provides PicGo's CLI utilities. ### cmd.program Used to register CLI commands. This is a [commander.js](https://github.com/tj/commander.js/) instance and its usage is almost the same as commander. **Do not call `picgo.cmd.program.parse(process.argv)` manually, otherwise it will error.** See [Registering CLI Commands](/core/dev-guide/cli#registering-cli-commands). Example: ```js picgo.cmd.program .commands('test', 'This is a test commands') .action(() => { console.log(123) }) ``` ### cmd.inquirer Used to provide interactive CLI prompts. This is an [inquirer.js](https://github.com/SBoudrias/Inquirer.js/) instance and its usage is the same as inquirer. See [Handling Config](/core/dev-guide/cli#handling-config). PicGo typically uses this together with a plugin's `config` method. Example: ```js const handleConfig = async ctx => { const prompts = config(ctx) const answer = await ctx.cmd.inquirer.prompt(prompts) ctx.saveConfig({ // call saveConfig to persist config 'picBed.xxx': answer }) } ``` ::: tip Tip You can build your own CLI interactions with this tool. However, in most cases you should implement interactivity via the plugin `config` method, and PicGo will automatically persist the `config` results for you. ::: ## log Used to print user-friendly messages in the CLI. Screenshot: ![](https://pic.molunerfinn.com/picgo/docs/logs.png) ### log.info(message) * message: string Example: ```js picgo.log.info('Hello world') ``` ### log.warn(message) * message: string Example: ```js picgo.log.warn('Hello world') ``` ### log.success(message) * message: string Example: ```js picgo.log.success('Hello world') ``` ### log.error(message) * message: string | error Example: ```js picgo.log.error('Hello world') ``` ## cloud PicGo Cloud manager, used for authentication and user info (https://cloud.picgo.app). ### cloud.login(\[token]) * token?: string * return: Promise\ If `token` is provided, PicGo verifies it via Cloud API, then saves it to `settings.picgoCloud.token` on success. If no token is provided, PicGo tries the existing token first; if invalid, it starts a browser-based login flow (local callback server + https://cloud.picgo.app login URL). If the browser cannot be opened, PicGo prints the URL for manual login. ```js await picgo.cloud.login('YOUR_TOKEN') // or browser-based: await picgo.cloud.login() ``` ### cloud.getUserInfo() * return: Promise<{ user: string } | null> Returns `null` if no token is stored. If the token is invalid (`401`/`403`), PicGo clears it and returns `null`. Other errors are thrown. ```js const info = await picgo.cloud.getUserInfo() ``` ### cloud.logout() Clears `settings.picgoCloud.token`. ```js picgo.cloud.logout() ``` ### cloud.disposeLoginFlow() Disposes an in-progress browser login flow. This rejects the pending login promise, clears the stored state, and shuts down the temporary login server (if it was started by the login flow). No-op if no login is in progress. ```js picgo.cloud.disposeLoginFlow() ``` ## server Local server manager used by the CLI and programmatic callers. ### server.listen(port?, host?, ignoreExistingExternalServer?) * return: Promise\ Resolves `settings.server.port` and `settings.server.host` from config if present; otherwise defaults to `36677` and `127.0.0.1`. When the port is busy, PicGo checks for an existing PicGo server via `POST /heartbeat` and reuses the port unless `ignoreExistingExternalServer` is set; otherwise it increments and retries. If the server is already listening, it returns the current port (idempotent). ```js const port = await picgo.server.listen() ``` ### server.shutdown() Stops the server and releases the port. ### server.isListening() Returns whether the current process is listening. ### server.getServerInfo() Returns the current server URL (e.g. `http://127.0.0.1:36677/`) or an empty string. ### server route registration ```js picgo.server.registerPost('/hello', async c => c.json({ ok: true })) picgo.server.mount('/plugin/demo', router => { router.get('/ping', c => c.text('pong')) }) ``` Notes: * Built-in routes (`/upload`, `/heartbeat`, `/auth/callback`) cannot be overwritten by plugins. * When multiple handlers are registered for the same method+path within the same process, the last registered handler wins. ### server authentication (optional) If a non-empty secret is resolved (`--secret` → `PICGO_SERVER_SECRET` → `settings.server.secret`), PicGo enables authentication. * Protected routes: `POST /upload` and all plugin-registered routes. * Open routes: `POST /heartbeat`, `/auth/callback`, static routes, root pages, and `OPTIONS` preflight. * Credential priority: `Authorization: Bearer ` (case-insensitive) → `X-PicGo-Secret` → `?secret=`. * If `Authorization` is present, PicGo does **not** fall back to lower-priority sources. * Query secrets are supported but discouraged; PicGo logs a warning once per process. * Unauthorized response: HTTP `401` with `{ success: false, message: "Unauthorized" }`. * PicGo logs auth enabled/disabled at startup and logs unauthorized attempts with client IP (preferring `X-Forwarded-For`). ## PluginHandler Provides low-level APIs to install, update, and uninstall PicGo plugins. It also emits success/failure events for handling results. **It depends on the system `npm` command.** ### pluginHandler.install(\[...pluginName]) * return: Promise<[IPluginHandlerResult](https://github.com/PicGo/PicGo-Core/blob/f133d57562c413b0b6f9a9ca9a93bf19c1768f1f/src/types/index.d.ts#L339)> Installs plugins. Accepts an array argument. `pluginName` can be: 1. A full PicGo plugin name, e.g. `picgo-plugin-xxx`. 2. A shorthand name, e.g. `xxx`. 3. A scoped plugin, e.g. `@xxx/picgo-plugin-yyy`. 4. A local path, e.g. `./xxx/yyy/picgo-plugin-zzz`. ```js const res = picgo.pluginHandler.install(['xxx']) picgo.on('installSuccess', (res) => { console.log(res) // ['picgo-plugin-xxx'] }) picgo.on('installFailed', err => {}) // Since v1.4.19 it returns the result directly. Example: res.then((result) => { if (result.success) { console.log(result.body) // ['picgo-plugin-xxx'] } else { console.log(result.body) // error message } }) ``` ### pluginHandler.uninstall(\[...pluginName]) * return: Promise<[IPluginHandlerResult](https://github.com/PicGo/PicGo-Core/blob/f133d57562c413b0b6f9a9ca9a93bf19c1768f1f/src/types/index.d.ts#L339)> Uninstalls plugins. Accepts an array argument. `pluginName` can be: 1. A full PicGo plugin name, e.g. `picgo-plugin-xxx`. 2. A shorthand name, e.g. `xxx`. 3. A scoped plugin, e.g. `@xxx/picgo-plugin-yyy`. 4. A local path, e.g. `./xxx/yyy/picgo-plugin-zzz`. ```js const res = picgo.pluginHandler.uninstall(['xxx']) picgo.on('uninstallSuccess', (res) => { console.log(res) // ['picgo-plugin-xxx'] }) picgo.on('uninstallFailed', err => {}) // Since v1.4.19 it returns the result directly. Example: res.then((result) => { if (result.success) { console.log(result.body) // ['picgo-plugin-xxx'] } else { console.log(result.body) // error message } }) ``` ### pluginHandler.update(\[...pluginName]) * return: Promise<[IPluginHandlerResult](https://github.com/PicGo/PicGo-Core/blob/f133d57562c413b0b6f9a9ca9a93bf19c1768f1f/src/types/index.d.ts#L339)> Updates plugins. Accepts an array argument. `pluginName` can be: 1. A full PicGo plugin name, e.g. `picgo-plugin-xxx`. 2. A shorthand name, e.g. `xxx`. 3. A scoped plugin, e.g. `@xxx/picgo-plugin-yyy`. 4. A local path, e.g. `./xxx/yyy/picgo-plugin-zzz`. ```js const res = picgo.pluginHandler.update(['xxx']) picgo.on('updateSuccess', (res) => { console.log(res) // ['picgo-plugin-xxx'] }) picgo.on('updateFailed', err => {}) // Since v1.4.19 it returns the result directly. Example: res.then((result) => { if (result.success) { console.log(result.body) // ['picgo-plugin-xxx'] } else { console.log(result.body) // error message } }) ``` ## PluginLoader Provides methods to dynamically load/unload PicGo plugins. This is useful when using PicGo inside a Node.js project and you want to load plugins on demand. ### pluginLoader.registerPlugin(pluginName, plugin) * pluginName: string * plugin: [IPicGoPlugin](https://github.com/PicGo/PicGo-Core/blob/f133d57562c413b0b6f9a9ca9a93bf19c1768f1f/src/types/index.d.ts#L352) Registers and loads a plugin. Example: ```js const pluginXXX = require('picgo-plugin-xxx') // pluginName must be unique picgo.pluginLoader.registerPlugin('xxx', pluginXXX) ``` ### pluginLoader.unregisterPlugin(pluginName) Unloads a plugin. Example: ```js // pluginName must be unique picgo.pluginLoader.unregisterPlugin('xxx') ``` ### pluginLoader.getPlugin(pluginName) * return: plugin -> [IPicGoPlugin](https://github.com/PicGo/PicGo-Core/blob/f133d57562c413b0b6f9a9ca9a93bf19c1768f1f/src/types/index.d.ts#L352) Gets a plugin. Example: ```js const plugin = picgo.pluginLoader.getPlugin('xxx') ``` ### pluginLoader.hasPlugin(pluginName) Checks whether a plugin exists. * return: boolean Example: ```js const res = picgo.pluginLoader.hasPlugin('xxx') // true or false ``` ## use A simpler plugin loading approach than [PluginLoader](#pluginloader). Suitable for dynamically loading plugins when using PicGo in a Node.js project. * (plugin: IPicGoPlugin, name?: string): IPicGoPluginInterface 1. The first argument is the exported PicGo plugin object, typically provided as an npm package. 2. If the second argument `name` is omitted, PicGo will only instantiate the plugin but will not register it into PicGo's plugin list. This is useful when you need to dynamically load a plugin. Example: ```js const { PicGo } = require('picgo') const PluginMigrater = require('picgo-plugin-pic-migrater') const MinioUploader = require('picgo-plugin-minio') const picgo = new PicGo() const plugin = picgo.use(PluginMigrater) // will not register this plugin, just use it picgo.use(MinioUploader, 'minio') // will register this plugin picgo.setConfig({ 'picgo-plugin-pic-migrater': { newFileSuffix: '_new', include: '', exclude: '' }, picBed: { current: 'minio', // use minio config uploader: 'minio', minio: { endpoint: 'http://localhost:9000', accessKey: 'minioadmin', secretKey: 'minioadmin', bucket: 'picgo', path: '/', useSSL: false } } }) // will use minio for migrating plugin.migrateFiles(['/xxx/yyy.md']) // { total: number, success: number } ``` ## i18n Provides internationalization support. Currently supported languages: * `zh-CN` (default) * `zh-TW` * `en` If you want to contribute a default language pack to PicGo, refer to this [PR](https://github.com/PicGo/PicGo-Core/pull/135). ### i18n.addLocale(language: string, locales: ILocale) Adds locale entries to an existing language. * language: string * locales: `[key: string]: any` * return: boolean, whether the locale was added successfully ```js picgo.i18n.addLocale('zh-CN', { 'PICGO_CURRENT_PICBED': 'Current image host' }) const text = picgo.i18n.translate('PICGO_CURRENT_PICBED') // Current image host ``` ### i18n.translate(key: T, args?: {}) => string Translates text. * key: string | T (T is an enum type that contains all text keys) * args: object (optional). If the text has params, pass them here. * return: string ```js picgo.i18n.addLocale('zh-CN', { 'PICGO_CURRENT_PICBED': 'Current image host is ${current}' }) const text = picgo.i18n.translate('PICGO_CURRENT_PICBED', { current: 'picgo-cloud' }) // Current image host is picgo-cloud ``` ### i18n.setLanguage(language: string) Sets the current language. ```js picgo.i18n.setLanguage('zh-TW') ``` ### i18n.addLanguage(language: string, locales: ILocale) * language: string * locales: `[key: string]: any` Adds a new language. If you add a new language, it is recommended to implement [all default keys](https://github.com/PicGo/PicGo-Core/blob/dev/src/i18n/zh-CN.ts), otherwise you may run into unexpected issues. ```js picgo.i18n.addLanguage('jp', { // ... }) ``` ### i18n.getLanguageList() * return: string\[] Returns the list of supported languages. ```js const list = picgo.i18n.getLanguageList() // ['zh-CN', 'zh-TW', 'en'] ``` ## guiApi **`guiApi` is only available in the Electron version of PicGo. For details, see [GUI Development](/core/dev-guide/gui).** ### guiApi.showInputBox(\[option]) Opens an input dialog so you can get user input. * option: Object || `undefined` * return: Promise that resolves to the user's input. `option` is optional. You can pass `{ title, placeholder }` for the dialog title and input placeholder. ```js const guiMenu = ctx => { return [ { label: 'Open InputBox', async handle (ctx, guiApi) { const value = await guiApi.showInputBox({ title: 'Open dialog', placeholder: 'Please enter a file path' }) console.log(value) } } ] } ``` ### guiApi.showFileExplorer(\[option]) Opens a file explorer so you can get file/folder paths selected by the user. * option: Object || `undefined` * return: Promise that resolves to an array of selected paths. `option` is optional. You can pass a valid Electron dialog [options object](https://electronjs.org/docs/api/dialog#dialogshowopendialogbrowserwindow-options-callback) to control multi-select, file vs folder selection, etc. ```js const guiMenu = ctx => { return [ { label: 'Open file explorer', async handle (ctx, guiApi) { const files = await guiApi.showFileExplorer({ properties: ['openFile', 'multiSelections'] }) console.log(files) } } ] } ``` ### guiApi.upload(\[file]) Uses PicGo core to upload. It can automatically update the gallery and write the URL to the clipboard after upload succeeds. * file: Array || `undefined` * return: Promise that resolves to PicGo's output array after a successful upload. `async/await` is recommended. ::: tip Tip In practice, you can combine `showInputBox`/`showFileExplorer` with `upload` to implement a simple upload flow. However, for more robust integrations, it is still recommended to implement an Uploader or Transformer plugin to take control of PicGo's upload workflow. ::: Example: ```js const guiMenu = ctx => { return [ { label: 'Standalone upload', async handle (ctx, guiApi) { const files = await guiApi.showFileExplorer({ properties: ['openFile', 'multiSelections'] }) guiApi.upload(files) } } ] } ``` ### guiApi.showNotification(option) Shows a system notification. * option: Object || `undefined` * return: undefined `option` is required and should include `{ title, body }`. ![](https://pic.molunerfinn.com/picgo/docs/5c3db88042a0f.png) Example: ```js const guiMenu = ctx => { return [ { label: 'Show notification', async handle (ctx, guiApi) { guiApi.showNotification({ title: 'Tip', body: 'This notification is from a plugin' }) } } ] } ``` ### guiApi.showMessageBox(\[option]) Shows a system message box dialog. * option: Object || `{title: '', message: '', type: 'info', buttons: ['Yes', 'No']}` * return: Object -> `{result, checkboxChecked}` ![](https://pic.molunerfinn.com/picgo/docs/20190611110904.png) For the full `option` parameters, refer to Electron's [dialog.showMessageBox](https://electronjs.org/docs/api/dialog#dialogshowmessageboxbrowserwindow-options-callback). In the returned value, `result` is the index of the button you clicked. For example, if you clicked "Yes", you would get something like: ```js { result: 0, checkboxChecked: false // if you set checkboxLabel in options, a checkbox will appear } ``` Example: ```js const guiMenu = ctx => { return [ { label: 'Show MessageBox', async handle (ctx, guiApi) { const result = await guiApi.showMessageBox({ title: 'This is title', message: 'This is message', type: 'info', buttons: ['Yes', 'No'] }) console.log(result) // { result: 0, checkboxChecked: false } } } ] } ``` ### guiApi.galleryDB Starting from PicGo GUI 2.3.0, gallery data is managed via `galleryDB` instead of the `uploaded` field in config. For `galleryDB`, refer to the API provided by [PicGo/store](https://github.com/PicGo/store#get-getfilter-ifilter) as the source of truth. The docs below may not always be up to date. #### galleryDB.get(filter?) * filter: undefined || Object -> [IFilter](https://github.com/PicGo/store/blob/dev/src/types/index.ts) * return: Promise<[IImgInfo\[\]](https://github.com/PicGo/PicGo-Core/blob/f133d57562c413b0b6f9a9ca9a93bf19c1768f1f/src/types/index.d.ts#L169-L178)> Gets the gallery list. You can provide `filter` to filter results; if omitted, it returns all items. Example: ```js const guiMenu = ctx => { return [ { label: 'Get gallery data', async handle (ctx, guiApi) { const result = await guiApi.galleryDB.get({ orderBy: 'asc', // ascending limit: 10, // take 10 items offset: 5 // start after index 5 (slice(5)) }) console.log(result) // [{...}, {...}, {...}, ...] } } ] } ``` #### galleryDB.insert(value) * value: Object -> [IImgInfo](https://github.com/PicGo/PicGo-Core/blob/f133d57562c413b0b6f9a9ca9a93bf19c1768f1f/src/types/index.d.ts#L169-L178) * return: Promise<[IResult](https://github.com/PicGo/store/blob/dev/src/types/index.ts)> Inserts an item into the gallery. Note that the inserted data must match the required output format (see [Transformer](/core/dev-guide/cli#transformer)), otherwise it cannot be displayed in the gallery. #### galleryDB.insertMany(\[...value]) * input: Array -> [IImgInfo\[\]](https://github.com/PicGo/PicGo-Core/blob/f133d57562c413b0b6f9a9ca9a93bf19c1768f1f/src/types/index.d.ts#L169-L178) * return: Promise<[IResult\[\]](https://github.com/PicGo/store/blob/dev/src/types/index.ts)> Batch inserts items into the gallery. Note that the inserted data must match the required output array format (see [Transformer](/core/dev-guide/cli#transformer)), otherwise it cannot be displayed in the gallery. #### galleryDB.updateById(id, value) * id: string (the id of an image in the gallery) * value: [IImgInfo](https://github.com/PicGo/PicGo-Core/blob/f133d57562c413b0b6f9a9ca9a93bf19c1768f1f/src/types/index.d.ts#L169-L178) * return: Promise\ Updates an item by id. Returns a boolean: `true` if updated successfully, otherwise `false`. #### galleryDB.getById(id) * id: string (the id of an image in the gallery) * return: Promise<[IImgInfo](https://github.com/PicGo/PicGo-Core/blob/f133d57562c413b0b6f9a9ca9a93bf19c1768f1f/src/types/index.d.ts#L169-L178)> Gets an item by id. #### galleryDB.removeById(id) * id: string (the id of an image in the gallery) * return: void Removes an item by id. No return value. **Note: deleting images is a sensitive operation. The GUI version will prompt the user for confirmation.** #### galleryDB.overwrite(value) * value: [IImgInfo\[\]](https://github.com/PicGo/PicGo-Core/blob/f133d57562c413b0b6f9a9ca9a93bf19c1768f1f/src/types/index.d.ts#L169-L178) * return: Promise<[IResult\[\]](https://github.com/PicGo/store/blob/dev/src/types/index.ts)> Overwrites gallery data. **This clears existing data before overwriting.** **Note: overwriting the image list is a sensitive operation. The GUI version will prompt the user for confirmation.** --- --- url: 'https://docs.picgo.app/cloud/billing.md' --- # Billing & Subscription ## Plans PicGo Cloud offers **Free / Starter / Pro / Max** plans. For quotas and feature differences, see the [plan comparison](/cloud/account#plan-comparison). For current pricing, visit [picgo.app/pricing](https://picgo.app/pricing/). ## Subscription actions ### Upgrading Log in to [cloud.picgo.app](https://cloud.picgo.app), go to the Pricing page, pick a plan, and complete payment. ### Canceling You can cancel your subscription at any time. After cancellation: * **You don't lose access immediately** — your account enters the subscription lifecycle described below. * You keep paid features until the end of the current billing period. ### Switching plans To switch between paid plans (upgrade or downgrade), contact . ## Subscription lifecycle When your paid subscription expires or is canceled, your account goes through the following stages. You can renew at any point within the roughly 90-day retention window to get everything back. ``` Active ──[expires / canceled]──▸ Grace 30d ──▸ Frozen 60d ──▸ Permanent deletion CDN up CDN down renew OK renew OK ``` ### Grace period * Your uploaded files **stay online and accessible** — links in your blog or elsewhere keep working. * Features that require a paid quota (new uploads beyond the free limit, custom domain, auto-import, etc.) drop to free-tier levels. * The GUI app and cloud.picgo.app show a grace-period banner. * Renewing during this window restores full service immediately with no data impact. ### Frozen period * Public file delivery through PicGo Cloud is **suspended** — file links return a placeholder image labeled "Account Frozen — Renew to restore media access". * All active features are disabled (uploads, config sync push, domain management, etc.). * Your data is still fully preserved. **Renewing restores everything immediately**, and your file links start working again right away. ### Permanent deletion If you haven't renewed by the end of the retention window (Grace 30 days + Frozen 60 days ≈ 90 days): * Files, albums, and related data stored on PicGo Cloud are **permanently deleted and cannot be recovered**. * Custom domain binding is removed. * Auto-import settings are cleared. * **Your account itself is kept** and reverts to the Free plan — you can keep using Free features with the same account. * **Config sync history is trimmed to the most recent 3 versions**; older versions are purged. ### Renewal recovery | When you renew | Data recovery | Feature recovery | |---|---|---| | During Grace | 100% — CDN was never down | Restored to paid level immediately | | During Frozen | 100% — CDN restored immediately | Restored to paid level immediately | | After deletion | Cannot be recovered | Treated as a new subscription | Features that the system **automatically** disabled due to expiration (e.g. custom domain, auto-import) are re-enabled when you renew. Anything you **turned off yourself** during the grace or frozen period stays off. ### Email reminders PicGo sends multiple email reminders during the retention window to let you know what's coming. Make sure your registered email is up to date. ## Inactive free accounts To keep the service sustainable, PicGo Cloud may clean up data stored under free accounts that have been inactive for an extended period. You'll always receive an email notification before any cleanup, giving you a chance to log in and keep your account active. Accounts with an active paid subscription are not affected by this policy. ## More policies For more on subscriptions, payments, and related policies, see the [PicGo Terms of Service](https://picgo.app/terms/). --- --- url: 'https://docs.picgo.app/core/guide/commands.md' --- # CLI Commands PicGo can be used directly from the command line. After installing `picgo` globally, run `picgo -h` to see all available commands: ```bash $ picgo -h Usage: picgo [options] [command] Options: -v, --version output the version number -d, --debug debug mode -s, --silent silent mode -p, --proxy set proxy for uploading -c, --config set config path -h, --help output usage information Commands: install|add [options] install picgo plugin uninstall|rm uninstall picgo plugin update [options] update picgo plugin set [name] [configName] configure config of picgo modules config [command] manage picgo config upload|u [input...] upload, go go go use [module] [name] [configName] use modules of picgo uploader [command] manage uploader configurations get inspect current module config login [token] login to picgo cloud (cloud.picgo.app) logout logout from picgo cloud (cloud.picgo.app) cloud picgo cloud commands server [options] run PicGo as a standalone server i18n [lang] change picgo language help [command] display help for command ``` ::: warning Starting from PicGo-Core v1.7.0, PicGo no longer bundles the legacy `picgo init` command. Use the standalone [`picgo-init`](https://github.com/PicGo/PicGo-Init) command instead (see `picgo-init` section below). ::: ::: tip Tip Options wrapped in `<>` are required, and options wrapped in `[]` are optional. Some commands have aliases—for example, `picgo upload` can be shortened to `picgo u`. ::: The CLI is built with [commander.js](https://github.com/tj/commander.js/) and [inquirer.js](https://github.com/SBoudrias/Inquirer.js/). Below is a walkthrough of the commands and how to use them. ## use > Select a PicGo module. There are three kinds of modules: 1) transformer 2) uploader 3) plugins ```bash $ picgo use -h Usage: use [module] [name] [configName] use a module (uploader/transformer/plugin) of picgo ``` PicGo ships with the following built-ins: * transformer: * path * base64 * uploader: * smms -> SM.MS (S.EE) * tcyun -> Tencent Cloud COS * upyun -> UpYun * aliyun -> Alibaba Cloud OSS * qiniu -> Qiniu Cloud * imgur -> Imgur * github -> GitHub ::: tip Tip In most CLI workflows, you only need to select `path` as the PicGo `transformer`. ::: Use `picgo use` or `picgo use uploader|transformer|plugins` to pick the module you want. This opens an interactive prompt: ```bash $ picgo use ? Use an uploader (Use arrow keys) smms ❯ tcyun weibo github qiniu imgur aliyun (Move up and down to reveal more choices) ``` Starting from PicGo-Core `v1.8.0`, uploaders support multiple named configs. If an uploader has multiple configs, the interactive flow will ask you to choose one. You can also specify it directly: ```bash picgo use uploader ``` `configName` is matched case-insensitively. After you choose, PicGo will upload using the selected module. Some modules need configuration before you can use them (for example, tokens/keys for an image host). In that case, use `set` (described below) to configure the module. ## uploader Manage uploader configurations (multi-config). * `picgo uploader` opens an interactive prompt (list/rename/copy/delete). * `picgo uploader list [type]` lists configs (marks current uploader and default config). * `picgo uploader rename ` * `picgo uploader copy ` (does not switch current uploader) * `picgo uploader rm ` Config names are matched case-insensitively. Examples: ```bash picgo uploader list picgo uploader list github picgo uploader rename github Work Personal picgo uploader copy github Work Staging picgo uploader rm github Staging ``` ## set > Configure module settings. There are three kinds of modules: 1) transformer 2) uploader 3) plugins ```bash $ picgo set -h Usage: set [options] [name] [configName] configure config of picgo modules (uploader/transformer/plugin) Options: -h, --help output usage information ``` ::: tip Tip Most of the time you only need to configure an uploader. You can run `picgo set uploader` (or `picgo set uploader [configName]`) to jump straight into the interactive prompt. ::: Starting from PicGo-Core `v1.8.0`, `set uploader` works with uploader multi-config: you can choose an existing config (by name) or create a new one, and the saved config becomes the active config for that uploader. For the detailed configuration fields of built-in uploaders (image hosts), refer to PicGo’s configuration [wiki](https://github.com/Molunerfinn/PicGo/wiki/%E8%AF%A6%E7%BB%86%E7%AA%97%E5%8F%A3%E7%9A%84%E4%BD%BF%E7%94%A8)。 If an uploader/transformer/plugin has no configurable options, PicGo will still report success—this is expected. ```bash $ picgo set transformer path [PicGo SUCCESS]: Configure config successfully! ``` ## get Inspect the currently selected PicGo module configuration. Supports three sub-commands, all of which accept `--format pretty|json` (default `pretty`). ```bash picgo get uploader # currently selected uploader type picgo get transformer # currently selected transformer picgo get plugins # installed plugins and their enabled/disabled status ``` ### picgo get uploader Read the current uploader type. Resolution order: `picBed.uploader` → `picBed.current` → `picgo-cloud` (fallback). ```bash $ picgo get uploader github $ picgo get uploader --format json {"uploader":"github"} ``` ### picgo get transformer Read the current transformer. Defaults to `path`. ```bash $ picgo get transformer path $ picgo get transformer --format json {"transformer":"path"} ``` ### picgo get plugins List installed plugins and their enabled/disabled status. ```bash $ picgo get plugins picgo-plugin-xxx enabled picgo-plugin-yyy disabled $ picgo get plugins --format json {"plugins":[{"name":"picgo-plugin-xxx","enabled":true},{"name":"picgo-plugin-yyy","enabled":false}]} ``` If no plugins are installed: ```bash $ picgo get plugins No plugins installed. ``` :::tip In `--format json` mode, stdout contains a single `JSON.parse`-able line, making it easy to consume from scripts. ::: ## login Log in to PicGo Cloud (https://cloud.picgo.app) and persist the token to `settings.picgoCloud.token`. ```bash picgo login [token] ``` * If `token` is provided, PicGo verifies it via Cloud API and saves it on success. * If `token` is omitted, PicGo first tries the existing token; if invalid, it starts a browser-based login flow. * The browser flow starts a local callback server and opens the login URL at https://cloud.picgo.app. If the browser cannot be opened automatically, PicGo prints the URL so you can open it manually. ## logout Log out from PicGo Cloud (https://cloud.picgo.app) and clear the local token. ```bash picgo logout ``` * Clears `settings.picgoCloud.token` locally. ## cloud PicGo Cloud related commands, including auth status checks and cloud album management. All cloud subcommands require you to log in first via `picgo login`. :::tip `cloud login` / `cloud logout` are aliases for `picgo login` / `picgo logout`. `cloud config sync` is an alias for `picgo config sync`. ::: ### cloud auth status Check the current PicGo Cloud login status. **Non-blocking** — does not trigger an interactive login. Supports `--format pretty|json` (default `pretty`). ```bash picgo cloud auth status [--format pretty|json] ``` The result is communicated via **exit code**, making it easy to use in scripts: | status | meaning | exit code | |---|---|---| | `logged_in` | token is valid | `0` | | `logged_out` | no local token | `1` | | `invalid` | token exists but was rejected by the server (401) | `2` | | `error` | probe failed (network / server error) | `3` | * The `logged_out` path makes no network requests and returns instantly. * When `logged_in`, the JSON output includes `user` and `plan` info. ```bash $ picgo cloud auth status Logged in as someone $ picgo cloud auth status --format json {"status":"logged_in","loggedIn":true,"user":"someone","plan":1} ``` Script usage example: ```bash picgo cloud auth status --format json if [ $? -ne 0 ]; then echo "Not logged in, running picgo login..." picgo login fi ``` ### cloud album list List items in the cloud album. Supports `--format pretty|json` (default `pretty`). ```bash picgo cloud album list [options] ``` Options: * `--content-type ` — filter by content type * `--type ` — filter by uploader type (e.g. `picgo-cloud`, `github`, `imgur`) * `--ext ` — filter by file extension * `--search ` — filter by keyword * `--file-name ` — filter by file name * `--limit ` — page size * `--offset ` — page offset * `--sort ` — sort field (`newest` / `oldest` / `fileName`) * `--order ` — sort order (`asc` / `desc`) ```bash $ picgo cloud album list --limit 5 ┌────────────────────────┬──────────────────────────────┐ │ ID │ URL │ ├────────────────────────┼──────────────────────────────┤ │ abc123 │ https://picgocloud.com/m/... │ └────────────────────────┴──────────────────────────────┘ Total: 42 Limit: 5 Offset: 0 $ picgo cloud album list --type picgo-cloud --format json {"success":true,"data":{"items":[...],"total":10,"limit":20,"offset":0}} ``` :::tip `picgo cloud list` is a shortcut for `picgo cloud album list`. ::: ### cloud album get Get the details of a single cloud album item by ID. ```bash picgo cloud album get [--format pretty|json] ``` ```bash $ picgo cloud album get abc123 { "id": "abc123", "imgUrl": "https://picgocloud.com/m/xxx.jpg", "fileName": "test.jpg", ... } ``` ### cloud album delete Delete one or more cloud album items. ```bash picgo cloud album delete [--force] [--format pretty|json] ``` * `--force` — skip the confirmation prompt. ```bash $ picgo cloud album delete abc123 def456 ? Are you sure you want to delete 2 items? (y/N) $ picgo cloud album delete abc123 --force --format json {"success":true,"data":{"deleted":["abc123"]}} ``` ### cloud album update Update properties of a cloud album item. ```bash picgo cloud album update [options] [--format pretty|json] ``` Options: * `--fileName ` — update file name * `--imgUrl ` — update image URL * `--originImgUrl ` — update original image URL * `--contentType ` — update content type * `--width ` — update width * `--height ` — update height ```bash $ picgo cloud album update abc123 --fileName new-name.jpg ``` ### cloud album import Import local album data into PicGo Cloud's album. Three data sources are supported. ```bash picgo cloud album import [dbPath] [options] [--format pretty|json] ``` Options: * `[dbPath]` — local PicGo album database path (usually `picgo.db`); uses the default path if omitted * `--json-file ` — read import data from a JSON file * `--data ` — read import data from an inline JSON string * `--verbose` — print batch details instead of a progress bar * `--enable-auto-import` — enable auto-import if not already on Requires a paid plan and auto-import to be enabled (or use `--enable-auto-import`). ```bash $ picgo cloud album import Import Summary: Total: 100 Created: 95 Skipped: 3 Invalid: 1 Failed: 0 Pending: 1 $ picgo cloud album import --json-file ./my-data.json --verbose ``` :::tip `picgo cloud import` is a shortcut for `picgo cloud album import`. ::: ### cloud album retry Retry previously pending import items. ```bash picgo cloud album retry [--verbose] [--format pretty|json] ``` ```bash $ picgo cloud album retry Import Summary: Total: 5 Created: 4 Skipped: 0 Invalid: 0 Failed: 1 Pending: 0 ``` ## config Manage config-related operations. ### config sync ```bash picgo config sync [--encrypt ] ``` * Syncs local config with PicGo Cloud using a 3-way merge (snapshot + local + remote). * On the first sync (or when remote is missing), local config is pushed to cloud and a snapshot baseline is created. * On conflict, PicGo prints a diff tree and prompts `Use Local`, `Use Remote`, or `Abort`. Local config is not overwritten until you choose a resolution. * `settings.picgoCloud.token` and `settings.picgoCloud.encryptionMethod` are treated as local-only values and are not overwritten by cloud data. * Requires a valid Cloud token. Run `picgo login` (cloud.picgo.app) first. #### Encryption method flags * `--encrypt `: validate `` as one of `auto`, `sse`, `e2ee`, then persist `settings.picgoCloud.encryptionMethod = ` before sync starts. * Methods: `auto` follows the last encryption method stored in cloud config, `sse` uses server-side encryption, and `e2ee` enables end-to-end encryption with a PIN. * If `` is invalid or missing, PicGo fails with: `Invalid configuration: settings.picgoCloud.encryptionMethod must be one of 'auto', 'sse', 'e2ee'. Found: ""`. * Without flags, PicGo follows local preference (`settings.picgoCloud.encryptionMethod`); if missing, it defaults to `auto` without persisting it. * When E2EE is used, PicGo prompts for a PIN (enter twice; retry up to 3 times on mismatch). If the PIN is incorrect during decryption, PicGo retries up to 3 times before failing. * For a deeper explanation of the encryption modes, see [PicGo Blog](https://picgo.app/blog/2026/picgo-configuration-sync-release/). ## server Run PicGo as a standalone local server. ```bash picgo server [options] ``` Options: * `-p, --port `: server port (default `36677`). * `-h, --host `: server host (default `127.0.0.1`). * `-i, --ignore-existing-external-server`: ignore an existing PicGo server on the same address. * `--secret `: enable server authentication with a shared secret. When the port is already in use, PicGo checks whether an existing PicGo server is running on that address. If so, it reuses the port (unless `--ignore-existing-external-server` is set). Otherwise it increments the port and retries. #### Built-in endpoints * `POST /heartbeat` → `{ success: true, result: "alive" }` * `POST /upload` * Empty body, `{}`, or `{ "list": [] }` uploads from clipboard. * `{ "list": ["path1", "path2"] }` uploads the provided file paths. * Invalid JSON returns HTTP `400`. * `multipart/form-data` with field `files` uploads file(s) and cleans up temp files under `baseDir`. #### Authentication (optional) Authentication is enabled when a non-empty secret is resolved (priority: `--secret` → `PICGO_SERVER_SECRET` → `settings.server.secret`). The secret is trimmed; whitespace-only values disable authentication. * Protected routes: `POST /upload` and all plugin-registered routes (including mounted routers). * Credential priority: `Authorization: Bearer ` (case-insensitive) → `X-PicGo-Secret` → `?secret=`. * If `Authorization` is present, PicGo does **not** fall back to lower-priority sources. * Using `?secret=` is supported but discouraged; PicGo logs a warning once per process. * Unauthorized responses return HTTP `401` with `{ success: false, message: "Unauthorized" }`. * PicGo logs whether authentication is enabled at startup and logs unauthorized attempts with the client IP (preferring `X-Forwarded-For`). Example: ```bash picgo server --secret mytoken curl -H "Authorization: Bearer mytoken" -H "Content-Type: application/json" -d '{"list":[]}' http://127.0.0.1:36677/upload ``` ## upload|u > Upload images to an image host. Typically you upload local files (multiple files separated by spaces). You can also upload the first image from your clipboard. ::: tip Tip Before uploading, make sure you’ve selected the right module with `use` and configured the target image host with `set`. ::: ```bash $ picgo u ./Test-example.jpg ./test-qiniu.png [PicGo INFO]: Before transform [PicGo INFO]: Transforming... [PicGo INFO]: Before upload [PicGo INFO]: Uploading... [PicGo SUCCESS]: https://i.loli.net/2018/09/06/5b9134645b9df.jpg https://i.loli.net/2018/09/06/5b9134651af34.png ``` If you don’t provide any input files, PicGo uploads the first image from your clipboard (due to cross-platform limitations it will be converted to PNG). This is especially handy for uploading screenshots. ```bash $ picgo u [PicGo INFO]: Before transform [PicGo INFO]: Transforming... [PicGo INFO]: Before upload [PicGo INFO]: Uploading... [PicGo SUCCESS]: https://i.loli.net/2018/09/06/5b9134645b9df.jpg ``` ## install|add > Install PicGo plugins from npm. Plugin packages are named with the `picgo-plugin-` prefix. When installing/uninstalling/updating, you only need to provide the short name (without the `picgo-plugin-` prefix). You can install multiple plugins by separating them with spaces. ::: tip Tip PicGo installs plugins into the directory where your config file lives. With the default config under `~/.picgo/`, plugins will be installed into `~/.picgo/node_modules/`. ::: You can search for PicGo [plugins](https://www.npmjs.com/search?q=picgo-plugin-) on npm. Plugins follow the naming pattern `picgo-plugin-[name]`, and can be installed with: ```bash picgo install [name] ``` After installing, you can use `picgo ch plugins` to enable or disable the plugin. ## uninstall|rm > Uninstall a PicGo plugin. PicGo will throw an error if the plugin is not installed. ```bash picgo uninstall [name] ``` ## update > Update an installed PicGo plugin. PicGo will throw an error if the plugin is not installed. ```bash picgo update [name] ``` ## i18n > Switch PicGo’s UI language. Supported languages: * zh-CN (default) * zh-TW * en Example: ```bash picgo i18n en ``` ## -v, --version Run `picgo -v` or `picgo --version` to print the current PicGo version. ## -d, --debug Add `-d` or `--debug` to any valid command to enter debug mode. PicGo will print more detailed error information, including where the error occurred. ## -c, --config Add `-c ` to specify the PicGo config file path. The default config file is `~/.picgo/config.json`. ::: tip Tip PicGo loads plugins from the `node_modules` directory next to the config file. ::: ## -s, --silent Add `-s` or `--silent` to any valid command to enter silent mode. PicGo will output nothing except error messages. ## -p, --proxy Set a proxy URL for uploading. For example: ```bash picgo u -p http://127.0.0.1:1080 test.jpg ``` The proxy URL is saved to the `picBed.proxy` config field. ## picgo-init > Download and generate a PicGo plugin development template. Starting from PicGo-Core v1.7.0, this is provided by the standalone `picgo-init` command. See [`PicGo/PicGo-Init`](https://github.com/PicGo/PicGo-Init) for installation and usage. ```bash $ picgo-init -h Usage: picgo-init