开放平台总览
Disk.Top 开放平台
用 OAuth 2.0 + REST API 把 Disk.Top 云存储能力接入你的应用。
#快速导航
- OAuth 2.0 概览
- 授权码模式 — Web / Wap
- 设备码模式 — CLI / TV / 扫码
- 权限范围 Scopes — 沙盒 vs 全盘
- 用户 API
- 文件 API
- 分享 API
#4 步接入
- 创建应用 在 /console — 拿
client_id+client_secret - 跳转用户授权:
GET https://openapi.disk.top/oauth/authorize?client_id=YOUR_ID&redirect_uri=YOUR_CALLBACK&response_type=code&scope=user.read+files.app_data&state=xyz - 用 code 兑 access_token:
POST https://openapi.disk.top/oauth/token grant_type=authorization_code&code=...&client_id=...&client_secret=...&redirect_uri=... - 带 Bearer 调 API:
curl -H "Authorization: Bearer ACCESS_TOKEN" https://openapi.disk.top/v1/user/info
#沙盒模型
默认 (files.app_data scope) 应用拿到用户网盘下的专属目录:/我的应用数据/<你的应用名>/。所有文件操作限制在沙盒内。
需要全盘访问请申请 files.read_all / files.write_all —— 用户授权时会看到敏感权限警告。
OAuth 2.0 概述
OAuth 2.0 Overview
Disk.Top supports three OAuth 2.0 grant types.
#1. Authorization Code Grant (Web)
Standard server-side flow with redirect_uri. Use for web/wap apps.
See Authorization Code Flow for details.
#2. Device Code Grant (CLI / TV)
For devices without a browser (CLI tools, Android TV, IoT). The device shows a user_code and verification_uri; user visits the URL on their phone, enters the code, and approves.
See Device Code Flow.
#3. Refresh Token
Standard grant_type=refresh_token — exchange a refresh_token for a new access_token. Refresh tokens rotate on each use.
POST https://openapi.disk.top/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=...&client_id=...&client_secret=...
#PKCE Support
All grants support PKCE (code_challenge / code_verifier). Recommended for mobile apps and SPAs where client_secret cannot be stored securely.
# Generate
code_verifier = base64url(random(32))
code_challenge = base64url(SHA256(code_verifier))
# In /oauth/authorize URL
&code_challenge=...&code_challenge_method=S256
# In /oauth/token request
&code_verifier=...设备码模式(CLI / TV)
Device Code Flow
For headless devices (CLI tools, Android TV, IoT) where a full browser-based OAuth flow is impractical.
#Step 1: Request a device code
POST https://openapi.disk.top/oauth/device-code
Content-Type: application/x-www-form-urlencoded
client_id=YOUR_CLIENT_ID&scope=user.read+files.app_data
Response:
{
"device_code": "sHxGyZ9rEd73E6PYg2yEdWWps9evt_oTDOqzFcxQJRxsZEUk",
"user_code": "8KXH-Y8R",
"verification_uri": "https://openapi.disk.top/oauth/device",
"verification_uri_complete": "https://openapi.disk.top/oauth/device?user_code=8KXH-Y8R",
"qr_url": "https://api.qrserver.com/v1/create-qr-code/?size=240x240&data=...",
"expires_in": 600,
"interval": 5
}
#Step 2: Display to user
Show the user_code AND/OR QR code on your device. User visits verification_uri on their phone, enters the code, and approves.
#Step 3: Poll for token
POST https://openapi.disk.top/oauth/device-token
Content-Type: application/x-www-form-urlencoded
device_code=sHxG...&client_id=YOUR_CLIENT_ID
Possible responses:
{"error":"authorization_pending"}— keep polling (respectinterval){"error":"access_denied"}— user denied; stop polling{"error":"expired_token"}— device_code expired; restart{"access_token": "...", "refresh_token": "...", ...}— success!
权限范围 (Scopes)
Scopes
Permissions your app requests at authorization time. Users see the exact list on the consent page.
#Default (Sandbox Model)
user.read— Read user profile (uid, username, email, avatar, VIP status)files.app_data— Default sandbox. Read/write files within a dedicated directory/我的应用数据/<YourAppName>/in the user's cloud. Cannot access user's other files.
#Sensitive (Explicit Consent Required)
These scopes give your app broader access. Users see warnings on the consent page.
files.read_all— Read all user files (across all directories)files.write_all— Write/delete any user fileshare.read— List all the user's sharesshare.create— Create new shares on behalf of the user
#Best Practices
- Request the minimum scopes you need. Users abandon apps that ask too much.
- Use sandbox (
files.app_data) unless you really need full-disk access. - New apps default to sandbox-only — broader scopes require admin review.
- Users can revoke any time at disk.top/user/apps.
用户信息接口
用户信息接口
获取当前 OAuth 授权用户的账号信息 / 容量 / 分享开关。
#用户基础信息
返回授权用户的 profile(含 uid、昵称、头像、VIP 状态、绑定的 OAuth client、本次授权 scope)。
#接口地址
https://openapi.disk.top/v1/user/info
#请求方式
GET
#请求参数
| 参数 | 位置 | 必填 | 类型 | 说明 |
|---|---|---|---|---|
Authorization |
header | 是 | string | Bearer {access_token},scope 含 user.read |
#请求示例
curl "https://openapi.disk.top/v1/user/info" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
#响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
data.uid |
int | 用户 id |
data.username |
string | 登录名 |
data.nickname |
string | 昵称 |
data.email |
string | 邮箱(脱敏) |
data.avatar_url |
string | 头像 URL |
data.is_vip |
bool | 是否 VIP |
data.vip_group |
int | VIP 等级(1-10) |
data.vip_expire_ts |
int | VIP 过期 unix ts,0=永久或非 VIP |
data.storage_quota_bytes |
int | 总存储配额(字节) |
data.created_at_ts |
int | 账号注册 unix ts |
data.oauth.client_id |
string | 当前授权的 app client_id |
data.oauth.scopes |
string[] | 本次授权实际生效的 scope 列表 |
#响应示例
{
"errno": 0,
"errmsg": "ok",
"data": {
"uid": 17,
"username": "dwtonline",
"nickname": "jam",
"email": "[email protected]",
"avatar_url": "https://disk.top/uploads/upload/avatar/17_xxx.jpg",
"is_vip": false,
"vip_group": 3,
"vip_expire_ts": 0,
"storage_quota_bytes": 1610612736000,
"created_at_ts": 1636115986,
"oauth": {
"client_id": "your_client_id",
"scopes": ["user.read","files.app_data"]
}
}
}
#容量相关
返回当前用户的总配额 / 已用 / 剩余 / 使用百分比。常用在「我的空间」页面展示进度条。
#接口地址
https://openapi.disk.top/v1/user/quota
#请求方式
GET
#请求参数
| 参数 | 位置 | 必填 | 类型 | 说明 |
|---|---|---|---|---|
Authorization |
header | 是 | string | Bearer {access_token},scope 含 user.read |
#请求示例
curl "https://openapi.disk.top/v1/user/quota" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
#响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
data.total_bytes |
int | 总配额(字节) |
data.used_bytes |
int | 已用 |
data.free_bytes |
int | 剩余 |
data.used_pct |
float | 使用百分比(0-100) |
#响应示例
{
"errno": 0,
"errmsg": "ok",
"data": {
"total_bytes": 1610612736000,
"used_bytes": 33691310918,
"free_bytes": 1576921425082,
"used_pct": 2.09
}
}
#开启分享能力
激活当前用户的「创建分享」功能(每个新接入的 OAuth app 调用一次即可)。开启后才能调 /v1/share/* create 类接口。
#接口地址
https://openapi.disk.top/v1/user/share-enable
#请求方式
POST
#请求参数
| 参数 | 位置 | 必填 | 类型 | 说明 |
|---|---|---|---|---|
Authorization |
header | 是 | string | Bearer {access_token},scope 含 share.create |
#请求示例
curl -X POST "https://openapi.disk.top/v1/user/share-enable" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
#响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
data.enabled |
bool | true=已开启 |
data.note |
string | 说明文本 |
#响应示例
{
"errno": 0,
"errmsg": "ok",
"data": {
"enabled": true,
"note": "Share endpoints are now active."
}
}文件管理接口
文件管理接口
OAuth 应用读写用户网盘文件。默认 scope files.app_data 只能读写沙盒目录 /我的应用数据/{AppName}/,files.write_all 可写全盘(需用户授权)。
上传协议:
precreate(拿 upload_id + endpoint)→ 分块上传 →complete。Client 无需关心存储后端实现细节。
#列目录
列出沙盒(或全盘)某路径下的文件 + 子目录。
#接口地址
https://openapi.disk.top/v1/files
#请求方式
GET
#请求参数
| 参数 | 位置 | 必填 | 类型 | 说明 |
|---|---|---|---|---|
Authorization |
header | 是 | string | Bearer {access_token} |
path |
query | 否 | string | 相对路径,默认 /。files.app_data scope 下 / 指沙盒根 |
page |
query | 否 | int | 页码,默认 1 |
limit |
query | 否 | int | 每页数量,默认 50,最大 200 |
#请求示例
curl -G "https://openapi.disk.top/v1/files" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
--data-urlencode "path=/" --data-urlencode "limit=20"
#响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
data.folders[].id |
int | 文件夹 id |
data.folders[].name |
string | 文件夹名 |
data.files[].id |
int | 文件 id |
data.files[].name |
string | 原始名 |
data.files[].size |
int | 字节数 |
data.files[].md5 |
string | 文件 md5 |
data.total |
int | 当前路径下总数 |
#响应示例
{
"errno":0,"errmsg":"ok",
"data":{
"path":"/","folders":[{"id":5911,"name":"GPTGet"}],
"files":[{"id":7280,"name":"chat-1.md","size":1024,"md5":"abc..."}],
"total":2
}
}
#搜索文件
按文件名 / 扩展名搜索。仅搜索沙盒(或全盘 if files.read_all)。
#接口地址
https://openapi.disk.top/v1/files/search
#请求方式
GET
#请求参数
| 参数 | 位置 | 必填 | 类型 | 说明 |
|---|---|---|---|---|
Authorization |
header | 是 | string | Bearer {access_token} |
q |
query | 是 | string | 搜索关键词(匹配 origin_name) |
ext |
query | 否 | string | 扩展名过滤(如 mp4) |
limit |
query | 否 | int | 最多返回,默认 50 |
#请求示例
curl -G "https://openapi.disk.top/v1/files/search" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
--data-urlencode "q=chat"
#响应示例
{"errno":0,"data":{"files":[{"id":7280,"name":"chat-573.md","size":1024,"md5":"abc..."}],"total":1}}
#文件元信息
按 file_id 查文件详情(路径 / md5 / 大小 / 上传时间 / mime 等)。
#接口地址
https://openapi.disk.top/v1/files/{id}
#请求方式
GET
#请求参数
| 参数 | 位置 | 必填 | 说明 |
|---|---|---|---|
Authorization |
header | 是 | Bearer |
id |
path | 是 | file_id |
#响应示例
{
"errno":0,
"data":{
"id":7280,"name":"chat-573.md","size":1024,
"md5":"abc...","ext":"md","mime":"text/markdown",
"path":"/我的应用数据/GPTGet/chat-573.md",
"parent_folder":5911,
"create_time":1779051234
}
}
#文件下载
获取文件直链下载 URL(10 分钟内有效,已签名,可 Range 续传)。
#接口地址
https://openapi.disk.top/v1/files/{id}/download
#请求方式
GET
#请求参数
| 参数 | 位置 | 必填 | 说明 |
|---|---|---|---|
Authorization |
header | 是 | Bearer |
id |
path | 是 | file_id |
#响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
data.url |
string | 临时直链 URL(已签名) |
data.expires_in |
int | 直链有效秒数(默认 600) |
data.name, data.size, data.md5 |
- | 文件信息 |
#响应示例
{
"errno":0,
"data":{
"url":"https://dl.disk-api.com/abc/file.mp4?sig=...&exp=...",
"expires_in":600,
"name":"demo.mp4","size":8388608,"md5":"abc..."
}
}
#视频在线播放
返回视频 HLS / DASH 播放列表 URL(在线播放器用)。
#接口地址
https://openapi.disk.top/v1/files/{id}/stream
#请求方式
GET
#响应示例
{
"errno":0,
"data":{
"stream_url":"https://dl.disk-api.com/hls/abc/master.m3u8?sig=...",
"duration":1800,
"qualities":[{"name":"1080p","url":"..."}],
"expires_in":600
}
}
#新建文件夹
在指定父目录下创建新文件夹。
#接口地址
https://openapi.disk.top/v1/files/folder
#请求方式
POST
#请求参数
| 参数 | 位置 | 必填 | 说明 |
|---|---|---|---|
Authorization |
header | 是 | Bearer,scope 含 files.app_data 或 files.write_all |
parent_path |
body | 否 | 父路径,默认 /(沙盒根) |
name |
body | 是 | 新文件夹名 |
#请求示例
curl -X POST "https://openapi.disk.top/v1/files/folder" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d "parent_path=/&name=Photos"
#响应示例
{"errno":0,"data":{"folder_id":5920,"name":"Photos","path":"/我的应用数据/GPTGet/Photos"}}
#重命名 / 移动 / 删除
批量操作(一次请求改多文件 / 多目录)。
#接口地址
https://openapi.disk.top/v1/files/manage
#请求方式
POST
#请求参数
| 参数 | 位置 | 必填 | 说明 |
|---|---|---|---|
Authorization |
header | 是 | Bearer,scope files.app_data / files.write_all |
action |
body | 是 | rename / move / copy / delete |
file_ids |
body array | 否 | 要操作的 file_id 列表 |
folder_ids |
body array | 否 | 要操作的 folder_id 列表 |
dest_path |
body | move/copy 时 | 目标父路径 |
new_name |
body | rename 时 | 新名 |
#请求示例
# 删除
curl -X POST "https://openapi.disk.top/v1/files/manage" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d "action=delete&file_ids[]=7280&file_ids[]=7281"
# 重命名
curl -X POST "https://openapi.disk.top/v1/files/manage" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d "action=rename&file_ids[]=7280&new_name=updated.md"
#响应示例
{"errno":0,"data":{"affected":2}}
#上传:precreate(秒传检测 + 拿 upload session)
上传第一步。提交 md5 + size,命中秒传直接返 file_id;否则返 upload_id 走分块上传。
#接口地址
https://openapi.disk.top/v1/files/upload/precreate
#请求方式
POST
#请求参数
| 参数 | 位置 | 必填 | 说明 |
|---|---|---|---|
Authorization |
header | 是 | Bearer,scope 含 files.app_data / files.write_all |
parent_path |
body | 否 | 父路径,默认 /(沙盒根) |
name |
body | 是 | 文件名 |
size |
body | 是 | 字节数 |
md5 |
body | 是 | 整文件 md5(小写 32 位 hex) |
content_type |
body | 否 | MIME,默认 application/octet-stream |
#请求示例
curl -X POST "https://openapi.disk.top/v1/files/upload/precreate" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d "parent_path=/&name=movie.mp4&size=104857600&md5=5eb63bbbe01eeed093cb22bb8f5acdc3"
#响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
data.instant_upload |
bool | true=秒传命中,直接拿 file_id;false=走分块上传 |
data.file_id |
int | 秒传命中时返此字段 |
data.upload_id |
string | 非秒传时返,client 用此 ID 上传分块 |
data.endpoint |
string | 分块上传服务公网 URL(如 https://openapi-upload.disk.top) |
data.chunk_size |
int | 分块字节数(client 切片用) |
data.total_parts |
int | 应传分块数 |
data.expires_in |
int | upload session 有效秒数(默认 86400) |
#响应示例
{
"errno":0,
"data":{
"instant_upload":false,
"upload_id":"a747204b5517044b304fe07b649c6bdc",
"endpoint":"https://openapi-upload.disk.top",
"chunk_size":5242880,
"total_parts":20,
"expires_in":86400
}
}
秒传命中:
{"errno":0,"data":{"instant_upload":true,"file_id":7266,"path":"/我的应用数据/GPTGet/movie.mp4","size":104857600}}
#上传:chunk(上传单个分块)
按 precreate 返的 chunk_size 切片,每片调用一次此接口(直接 POST 给 precreate 返的 endpoint)。
#接口地址
{endpoint}/u?upload_id={upload_id}&part_seq={N}
{endpoint} 取 precreate 返的值;{N} 从 1 开始递增。
#请求方式
POST
#请求参数
| 参数 | 位置 | 必填 | 说明 |
|---|---|---|---|
upload_id |
query | 是 | precreate 返的值 |
part_seq |
query | 是 | 当前分块序号(1-based) |
| body | raw | 是 | 当前分块字节(Content-Type: application/octet-stream) |
#请求示例
# 第 1 片
dd if=movie.mp4 bs=5242880 count=1 skip=0 | \
curl -X POST "https://openapi-upload.disk.top/u?upload_id=a747...&part_seq=1" \
-H "Content-Type: application/octet-stream" --data-binary @-
# 第 N 片同理
#响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
data.part_seq |
int | 已收到的分块序号 |
data.etag |
string | 该分块的 ETag(可选,部分场景为空) |
data.received_parts |
int | 累计已收数 |
data.total_parts |
int | 总数 |
#响应示例
{"errno":0,"data":{"part_seq":1,"etag":"abc123...","size":5242880,"received_parts":1,"total_parts":20}}
#上传:查进度 / 已传分块(断点续传用)
查询已传分块,client 跳过已传的部分续传。
#接口地址
{endpoint}/u/{upload_id}/parts
#请求方式
GET
#响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
data.upload_id |
string | upload_id |
data.total_parts |
int | 总应传 |
data.received_parts |
int[] | 已收 part_seq 列表(升序) |
data.progress |
float | 进度百分比 |
data.parts |
object | 详细 part_seq → {part_number, etag, size} 映射 |
#响应示例
{
"errno":0,
"data":{
"upload_id":"a747...",
"total_parts":20,
"received_parts":[1,2,3,5,6,7],
"progress":35.0,
"parts":{"1":{"part_number":1,"etag":"abc","size":5242880},"...":{}}
}
}
#上传:complete(合并 + 写表)
所有分块上传完成后调此接口,服务端合并分块并入库,返 file_id。
#接口地址
{endpoint}/u/{upload_id}/complete
#请求方式
POST
#响应参数
| 字段 | 类型 | 说明 |
|---|---|---|
data.file_id |
int | 新文件 id |
data.path |
string | 文件完整路径 |
data.size |
int | 字节数 |
data.md5 |
string | 文件 md5 |
#响应示例
{
"errno":0,
"data":{
"file_id":7280,
"path":"/我的应用数据/GPTGet/movie.mp4",
"size":104857600,
"md5":"5eb63bbbe01eeed093cb22bb8f5acdc3"
}
}
错误:
425 incomplete: N/M— 还缺片,调/parts查缺哪些续传502 complete failed— 服务端错,重试或检查日志
#上传:abort(取消上传 + 清理)
主动取消上传,服务端释放对应分块资源。
#接口地址
{endpoint}/u/{upload_id}/abort
#请求方式
POST
#响应示例
{"errno":0,"data":{"ok":true}}