通过同一地址上传图片(POST)或按 ID/文件名查询公开元数据(GET)。
本图床不会在上传的时候进行图片内容审查,但是会在之后的时间段中根据该图片访问次数来触发内容审查,毕竟内容审查也会产生成本。
一旦发现内容违法,会根据实际情况针对上传者特征删除该上传者所有图片。如果您想利用本API做成一个第三方图床,我们完全不介意,但是请务必注意内容审查。
本公益图床基本没怎么盈利,就不要为我们带来更多的麻烦了,感谢理解。
基础 URL 均为:
/api/v1.php
POST 上传图片
请求体使用 multipart/form-data,文件字段名为 image。详见下文「请求参数」。
GET 查询单张图片公开元数据
查询字符串参数 q:填写数字图片 ID或上传时的完整文件名(精确匹配)。响应格式见「图片元数据查询」一节。
GET /api/v1.php?q=图片ID或完整文件名
| 参数 | 必需 | 说明 |
|---|---|---|
q |
是 | 纯数字(图片主键 ID)或仅含英文字母、数字、下划线、点、连字符的完整文件名(与数据库一致)。不支持模糊搜索。 |
隐私:响应中不会返回上传者原始 IP,仅返回打码后的展示串(如 IPv4 为首段与末段可见);归属地由服务端根据原始 IP 推算,调用方无法据此还原完整 IP。
限流:GET 与 POST 使用不同限流桶;GET 为短窗口 5 秒 / 5 次、长窗口 60 秒 / 120 次(与上传相同数值,互不占用上传配额)。超额返回 429。
{
"success": true,
"data": {
"id": 12345,
"filename": "6640c49c7161b_1715519644.webp",
"original_filename": "screenshot.png",
"original_size_bytes": 102400,
"compressed_size_bytes": 20480,
"size_display": "100 KB → 20 KB",
"current_hash": "5317363b47c0d13925879da847c47f09da52ddf28fe7a016819c14b2732862b8",
"upload_date": "2026-04-30 17:53:59",
"last_accessed": "2026-04-30 18:15:06",
"uploader_masked": "202.*.*.165",
"location": "中国 山东 济南市",
"tags": "男生、文本",
"tags_array": ["男生", "文本"],
"image_url": "https://cdn.example.com/i/6640c49c7161b_1715519644.webp",
"cdn_domain": "cdn.example.com",
"password_protected": false
}
}
last_accessed 若从未记录则为 JSON null。image_url 为可直接用于 <img src> 或过浏览器打开的外链(与上传 API 返回规则一致,不含管理员免密参数)。cdn_domain 为该 URL 的主机名。password_protected 为 true 时表示加密图路径为 /p/,直连可能返回鉴权页而非图片二进制。
{
"success": false,
"error": "未找到与所给条件匹配的图片。",
"message": "未找到与所给条件匹配的图片。"
}
HTTP 状态码为 404。
本站前端「查询图片信息」弹窗与第三方调用相同,均使用 GET /api/v1.php?q=。
以下字段仅用于 POST multipart/form-data 上传。
| 参数名 | 类型 | 必需 | 描述 |
|---|---|---|---|
image |
File | 是 | 要上传的图片文件。支持的格式包括:jpg/jpeg、png、webp(静态/动态)、gif(静态/动态)、bmp、tiff。 服务端会通过文件真实内容(magic bytes)识别类型,上传的扩展名与内容不一致时将被自动修正为真实类型。其他格式(如 AVIF、HEIC 等)暂不支持。 |
outputFormat |
String | 否 | 输出格式(auto, jpg, jpeg, png, webp, gif, webp_animated),默认为 auto。auto:系统自动判断——静态图转 webp,动图转 webp_animated。webp:输出静态 WebP;若输入为动图,会自动升级为 webp_animated 保留全部帧,避免只保留第一帧。gif:输出优化后的 GIF。webp_animated:输出动态 WebP。为了获得更好的压缩率和显示效果,建议静态图用 webp、动图用 webp_animated。
|
password_enabled |
String | 否 | 设为 "true" 以启用密码保护。必须与 image_password 参数一同使用。 |
image_password |
String | 否 | 为图片设置的访问密码或答案。当 password_enabled 为 "true" 时此项为必需。 |
password_type |
String | 否 | 密码模式:plain(普通密码,默认)或 qa(问答式密码)。选 qa 时必须同时提供 password_question。 |
password_question |
String | 否 | 问答密码的问题文本,最多 150 个字符。仅在 password_type=qa 时生效;访问者会看到该问题,并需要填写与 image_password 一致的答案才能查看图片。 |
cdn_domain |
String | 否 | 指定图片外链使用的CDN域名。具体可用域名请参考下方的“可用 CDN 域名”列表。如果不指定或传入 default,将使用系统默认域名。 |
您可以在上传时通过 cdn_domain 参数指定以下任意一个域名。如果不指定,系统将自动选择。
| 名称 | 域名 |
|---|---|
| 失控的防御系统 | img.scdn.io |
| CloudFlare | cloudflareimg.cdn.sn |
| EdgeOne | edgeoneimg.cdn.sn |
| ESA | esaimg.cdn1.vip |
| CloudFlare(CN优选) | cloudflarecnimg.scdn.io |
| 失控的防御系统(Anycast) | anycastimg.scdn.io |
API 的响应统一为 JSON 格式,Content-Type: application/json; charset=utf-8。
所有响应字段说明:success 标识成败;成功响应中 url 和 data.url 都会返回可访问的图片链接,
data 对象还包含文件名和压缩统计;失败响应同时包含 error 与 message 两个字段
(内容一致,便于客户端任选其一读取)。
{
"success": true,
"url": "https://img.scdn.io/i/6640c49c7161b_1715519644.webp",
"data": {
"url": "https://img.scdn.io/i/6640c49c7161b_1715519644.webp",
"filename": "6640c49c7161b_1715519644.webp",
"original_size": 102400,
"compressed_size": 20480,
"compression_ratio": 80
}
}
{
"success": true,
"url": "https://img.scdn.io/p/unique_encrypted_id_string.webp",
"data": {
"url": "https://img.scdn.io/p/unique_encrypted_id_string.webp",
"filename": "unique_encrypted_id_string.webp",
"original_size": 102400,
"compressed_size": 20480,
"compression_ratio": 80
}
}
加密图 URL 以 /p/ 开头,访问时必须提供正确密码。返回的 URL 不会附带任何免密凭证。
{
"success": true,
"url": "https://img.scdn.io/i/existing_image_name.webp",
"message": "图片已存在,秒传成功!",
"data": {
"url": "https://img.scdn.io/i/existing_image_name.webp",
"message": "图片已存在,秒传成功!"
}
}
{
"success": false,
"error": "请求过于频繁,请稍后再试。",
"message": "请求过于频繁,请稍后再试。"
}
服务端以 SHA-256 哈希对上传文件做去重,命中以下任一条件会直接返回已有图片链接,不重复存储:
outputFormat 上传过。秒传命中时响应的 message 字段为 "图片已存在,秒传成功!",调用方可据此展示提示或统计。
password_enabled=true 的上传都会生成新的加密文件,避免命中别人的公共或加密版本导致密码语义失效。/p/ 链接返回给不知道密码的调用方。查询图片元数据(GET):
curl -sG --data-urlencode "q=6640c49c7161b_1715519644.webp" "https://img.scdn.io/api/v1.php"
上传公开图片:
curl -X POST -F "image=@/path/to/your/image.jpg" https://img.scdn.io/api/v1.php
将GIF动图转换为WebP动图:
curl -X POST \
-F "image=@/path/to/your/animation.gif" \
-F "outputFormat=webp_animated" \
https://img.scdn.io/api/v1.php
上传加密图片(普通密码):
curl -X POST \
-F "image=@/path/to/your/image.jpg" \
-F "password_enabled=true" \
-F "image_password=your_secret_password" \
https://img.scdn.io/api/v1.php
上传加密图片(问答式密码):
curl -X POST \
-F "image=@/path/to/your/image.jpg" \
-F "password_enabled=true" \
-F "password_type=qa" \
-F "password_question=我养的第一只宠物叫什么?" \
-F "image_password=Tom" \
https://img.scdn.io/api/v1.php
指定CDN域名上传 (需在后台配置):
curl -X POST \
-F "image=@/path/to/your/image.jpg" \
-F "cdn_domain=img.scdn.io" \
https://img.scdn.io/api/v1.php
// 查询元数据(GET)
fetch('https://img.scdn.io/api/v1.php?q=' + encodeURIComponent('6640c49c7161b_1715519644.webp'))
.then(r => r.json())
.then(data => console.log(data));
// 上传(POST)
const fileInput = document.querySelector('input[type="file"]');
const formData = new FormData();
formData.append('image', fileInput.files[0]);
formData.append('cdn_domain', 'img.scdn.io');
fetch('https://img.scdn.io/api/v1.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
import requests
# 查询元数据
r = requests.get('https://img.scdn.io/api/v1.php', params={'q': '6640c49c7161b_1715519644.webp'})
print(r.json())
# 上传
url = 'https://img.scdn.io/api/v1.php'
file_path = '/path/to/your/image.jpg'
with open(file_path, 'rb') as f:
files = {'image': f}
# 指定CDN域名 (可选)
data = {'cdn_domain': 'img.scdn.io'}
response = requests.post(url, files=files, data=data)
print(response.json())
<?php
$base = 'https://img.scdn.io/api/v1.php';
// 查询元数据(GET)
$q = '6640c49c7161b_1715519644.webp';
echo file_get_contents($base . '?q=' . rawurlencode($q));
// 上传(POST)
$filePath = '/path/to/your/image.jpg';
if (!file_exists($filePath)) {
die('错误: 文件不存在。');
}
$cfile = new CURLFile($filePath, mime_content_type($filePath), basename($filePath));
$postData = [
'image' => $cfile,
'cdn_domain' => 'img.scdn.io',
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $base);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'cURL 错误: ' . curl_error($ch);
} else {
header('Content-Type: application/json');
echo $response;
}
curl_close($ch);
?>
| 状态码 | 描述 |
|---|---|
400 Bad Request |
上传:没有上传文件、上传过程出错、或文件格式不支持。查询:缺少参数 q、或 q 格式非法(须为纯数字 ID 或允许的完整文件名字符集)。 |
404 Not Found |
仅 GET 查询:无与 q 精确匹配的图片记录。 |
405 Method Not Allowed |
上传接口仅支持 POST;整个 v1.php 仅支持 GET(查询)与 POST(上传)。 |
413 Payload Too Large |
上传文件超过了所选输出格式对应的最大限制(每种格式的上限由后台配置)。 |
415 Unsupported Media Type |
文件真实类型不在受支持的图片类型列表中(仅支持 jpg/png/webp/gif/bmp/tiff)。 |
429 Too Many Requests |
请求过于频繁,基于客户端 IP 做双层限流: · POST 上传使用桶名 long / short:短窗口 5 秒内最多 5 次,长窗口 60 秒内最多 120 次。· GET 查询使用桶名 info_long / info_short:数值与上传相同,但与上传互不占用配额。任一窗口超额都会返回 429,并附带 Retry-After 响应头。 |
500 Internal Server Error |
服务器内部发生错误,例如数据库连接失败、调用远端压缩服务失败等。 |