sugimoe

The hamster for developers

The HTTP API follows the same rules as the website: no account needed, up to 200 MB per file, images and short videos only (PNG, JPEG, WebP, GIF, AVIF, MP4, WebM, detected from the content).

Upload

# keep forever, prints the direct link
$ curl -F "file=@cat.png" https://sugi.moe/api/upload
https://files.sugi.moe/k3x9qa2m.png
# temporary: 1h / 12h / 72h
$ curl -F "file=@cat.png" -F "expire=1h" https://sugi.moe/api/upload
# import from a link
$ curl -F "url=https://example.com/a.png" https://sugi.moe/api/upload
# PUT the raw file
$ curl -T cat.png "https://sugi.moe/api/upload?expire=12h"

Want JSON?

Send Accept: application/json to also get the delete token and the expiry.

{
"url": "https://files.sugi.moe/k3x9qa2m.png",
"id": "k3x9qa2m",
"page": "https://sugi.moe/f/k3x9qa2m",
"size": 482113,
"type": "image/png",
"name": "cat.png",
"expires_at": null,
"delete_token": "d_7Yq2…"
}

Delete

$ curl -X DELETE -H "Sugi-Token: d_7Yq2…" https://sugi.moe/api/files/k3x9qa2m

All endpoints

POST /api/uploadUpload: multipart field file, or url to import a link; optional expire (1h, 12h, 72h; omit for forever), style (random or cute), name (display name). Up to 90 MB per request
PUT /api/uploadSame, with the raw file as the body and the options in the query string (?expire=1h&style=cute&name=a.png)
POST /api/uploads?size=…Chunked upload for files over 90 MB (up to 200 MB): the body is part 1 (5 to 90 MB); returns an upload session, the part size and the part count
PUT /api/uploads/:nUpload part n with the header Sugi-Upload: <session>; returns the part's etag
POST /api/uploads/completeFinish a chunked upload with the session header and JSON {"etags": [...]}; returns the same as /api/upload. DELETE /api/uploads aborts
PUT /api/upload/<link>Upload to a one-time link from the MCP tool create_upload: the body is the file (or a multipart "file" field), valid for 10 minutes and only once; returns the same JSON as /api/upload
GET /api/files/:idFile info (link, size, type, expiry)
DELETE /api/files/:idDelete a file; needs the header Sugi-Token: <delete_token>
POST /api/albumsMake one share link from files=id1,id2 (up to 100) and an optional title; returns the link and a delete token
GET /api/albums/:idList the files in an album
DELETE /api/albums/:idDelete an album (its files stay); needs Sugi-Token

Rate limits: each IP may start 10 uploads per 60 seconds (an upload, a link import and the start of a chunked upload each count once), and separately create 10 albums per 60 seconds. On top of that the firewall allows 5 requests per 10 seconds per IP to /upload, /api/upload and /api/uploads, and blocks for 10 seconds beyond that. Over a limit you get 429; wait a moment and try again.

The original POST /upload keeps working: PNG, JPEG, WebP and GIF only, up to 20 MB, links look like https://sugi.moe/<content hash>.png, the same content always gets the same link, and there is no delete token.