Skip to content

Commit 136e401

Browse files
committed
correct FluxDrive API reference against the implementation
The cat/get/rm/thumb examples used ?arg=<HASH>, but all four read the hash from the request body, so every documented command returned 400. Rewritten to send the hash in the body. Also corrected: /status and /ls response shapes (no status/result wrapper; /ls returns files, files_per_page, total_files and takes four undocumented pagination params), /put is single-file rather than multi, /putfolder returns per-file outcomes inside a 200, the 401 error strings, the undocumented 403 IP allow-list, and HTTP 429 which is plain text rather than JSON. Documents the self-service API key flow that now exists in the web UI.
1 parent 405f447 commit 136e401

1 file changed

Lines changed: 146 additions & 67 deletions

File tree

docs/fluxcloud/fluxdrive/api-reference.md

Lines changed: 146 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,33 @@ Sign in at [cloud.runonflux.com/flux-drive](https://cloud.runonflux.com/flux-dri
3333

3434
#### 3. Generate an API Key
3535

36-
* In the FluxDrive web UI, generate an **API\_KEY\_SECRET** mapped to your FluxID
37-
* Custom (PRO) plans can be arranged by contacting the Flux team — fill out the [PRO Plan Request Form](https://runonflux.bitrix24.com/pub/form/33_fluxdrive_pro_request_/2xp87g/?view=preview\&preview=inline) for a custom storage allocation
36+
In the FluxDrive web UI, open the **API Keys** panel below your storage usage, then:
37+
38+
1. Click **Create key**
39+
2. Give the key a name you'll recognise later (for example `production backup`)
40+
3. Click **Generate**
41+
4. Copy the key — or the ready-made `curl` command — from the dialog that appears
42+
43+
> ⚠️ **The key is shown only once.** FluxDrive stores only a hash of it, so it cannot be displayed or recovered again after you close that dialog. If you lose a key, revoke it and create a new one.
44+
45+
Custom (PRO) plans can be arranged by contacting the Flux team — fill out the [PRO Plan Request Form](https://runonflux.bitrix24.com/pub/form/33_fluxdrive_pro_request_/2xp87g/?view=preview\&preview=inline) for a custom storage allocation.
46+
47+
#### 4. Managing Your Keys
48+
49+
The same panel lists every key on your account, showing its name, first 8 characters, when it was created, and when it was last used — so you can tell which key an integration is actually using before you touch it.
50+
51+
| Action | How | Effect |
52+
| ------ | --- | ------ |
53+
| **Revoke a key** | Trash icon next to the key | Immediate. Any application using it starts receiving `401`. |
54+
| **Create another** | **Create key** | Up to 10 keys per subscription. |
55+
56+
Some practical notes:
57+
58+
* Keys do not expire — they stay valid until you revoke them or the subscription lapses
59+
* A key only works while the subscription is **active**; an unpaid or expired subscription returns `402` on every request
60+
* Keys carry full access to your FluxDrive storage, so treat one like a password: keep it out of client-side code and out of version control
61+
* Use a separate named key per application, so revoking one never takes down the others
62+
* Keys cannot be used to create or revoke other keys — key management always requires a Zelcore signature from the web UI
3863

3964
***
4065

@@ -57,45 +82,64 @@ All endpoints are accessed via **POST** requests with HTTP Basic authentication:
5782
| Limit | Value | Notes |
5883
| ----- | ----- | ----- |
5984
| Maximum file size | 5 GB per file | Larger uploads return HTTP 413 |
60-
| PUT rate limit | 150 requests / second | Per ZELID + IP |
61-
| Read rate limit | 1500 requests / second | Per ZELID + IP, applies to `/cat`, `/get`, `/ls`, `/status`, `/thumb` |
85+
| PUT rate limit | 150 requests / second | Per ZELID + IP, applies to `/put` and `/putfolder` |
86+
| Read rate limit | 1500 requests / second | Per ZELID + IP, applies to every `/api/v0` endpoint |
6287
| Storage capacity | Plan-dependent | See plans on the [overview page](README.md) |
88+
| API keys | 10 per subscription | Revoke one to create another |
6389

64-
Exceeding a rate limit returns HTTP 429 with `Retry-After` headers.
90+
Exceeding a rate limit returns HTTP 429. The rate-limit budget is keyed on your ZELID combined with your client IP, so separate machines using the same key each get their own allowance.
6591

6692
***
6793

6894
### Authentication & Errors
6995

70-
Every request must include valid Basic auth. Failed requests return JSON with an `error` field.
96+
Every request must include valid Basic auth (`-u "<ZELID>:<API_KEY_SECRET>"`). Failed requests return JSON with an `error` field, except for rate limiting — see below.
7197

72-
**Common error responses:**
98+
**Authentication failures**
99+
100+
| Status | `error` | Cause |
101+
| ------ | ------- | ----- |
102+
| `401` | `Missing or invalid Authorization header` | No `Authorization: Basic ...` header, or it could not be decoded |
103+
| `401` | `Subscription not found` | No FluxDrive subscription exists for that ZELID |
104+
| `401` | `Invalid API key` | The key is wrong, or it was revoked |
105+
| `402` | `Subscription payment is not active` | Subscription is unpaid, expired, or cancelled |
106+
| `403` | `IP address is not whitelisted` | Your account has an IP allow-list set and the request came from another address |
107+
108+
> ℹ️ **IP allow-listing is optional and off by default.** If you want your keys usable only from specific addresses, contact the Flux team to have an allow-list applied to your subscription.
109+
110+
**Request failures**
73111

74112
```json
75-
// 401 — invalid or missing API key
76-
{ "error": "Invalid credentials" }
113+
// 400 — hash missing or malformed
114+
{ "error": "Invalid or missing hash" }
115+
116+
// 400 — upload request carried no file
117+
{ "error": "No file provided" }
77118

78-
// 402 — subscription not active (e.g., expired or unpaid)
119+
// 402 — subscription lapsed between auth and upload
79120
{ "error": "Subscription not active" }
80121

81-
// 413 — file exceeds 5 GB or storage capacity exceeded
122+
// 413 — file exceeds the 5 GB per-file limit
82123
{ "error": "File size exceeds 5120Mb" }
124+
125+
// 413 — upload would exceed your plan's storage capacity
83126
{ "error": "Storage capacity exceeded" }
84127

85-
// 404 — hash not found in your account
128+
// 404 — hash is not present in your account
86129
{ "error": "File not found" }
87-
88-
// 429 — rate limited
89-
{ "error": "Too many requests" }
90130
```
91131

132+
> ⚠️ **HTTP 429 is not JSON.** Rate-limited requests return the plain-text body `Too many requests, please try again later.` — parse defensively rather than assuming an `error` field.
133+
92134
***
93135

94136
### Supported API Endpoints
95137

138+
All endpoints are **POST**. Parameters are sent in the **request body** (form-encoded or JSON), *not* as query-string arguments.
139+
96140
#### 1. `/api/v0/status`
97141

98-
**Description:** Get current storage usage and remaining capacity.
142+
**Description:** Get current storage usage, capacity, and subscription state.
99143

100144
```bash
101145
curl "https://api.fluxdrive.runonflux.io/api/v0/status" \
@@ -107,158 +151,193 @@ curl "https://api.fluxdrive.runonflux.io/api/v0/status" \
107151

108152
```json
109153
{
110-
"status": "success",
111-
"result": {
112-
"active": true,
113-
"capacity_gb": 10,
114-
"storage_used": 2412017,
115-
"remaining": 10733328063
116-
}
154+
"zelid": "1abc...",
155+
"plan_name": "standard",
156+
"active": true,
157+
"capacity_bytes": 53687091200,
158+
"capacity_gb": 50,
159+
"storage_used": 2412017,
160+
"remaining": 53684679183,
161+
"data_transfer_bytes": 91847362,
162+
"period_end": 1767225600
117163
}
118164
```
119165

120166
***
121167

122168
#### 2. `/api/v0/ls`
123169

124-
**Description:** List all files in your FluxDrive storage.
170+
**Description:** List files in your FluxDrive storage, newest first. Results are paginated.
171+
172+
**Arguments** (all optional):
173+
174+
| Field | Type | Default | Notes |
175+
| ----- | ---- | ------- | ----- |
176+
| `page` | number | `1` | 1-based page number, capped at 10000 |
177+
| `size` | number | `50` | Results per page, capped at 500 |
178+
| `currentFolder` | string | `/` | Folder path, or a folder UUID |
179+
| `includeFolders` | boolean | `false` | Include folder entries alongside files |
125180

126181
```bash
127182
curl "https://api.fluxdrive.runonflux.io/api/v0/ls" \
128183
-X POST \
129-
-u "<ZELID>:<API_KEY_SECRET>"
184+
-u "<ZELID>:<API_KEY_SECRET>" \
185+
-d "page=1" \
186+
-d "size=50"
130187
```
131188

132189
**Example Response (shortened):**
133190

134191
```json
135192
{
136-
"status": "success",
137193
"files": [
138194
{
139-
"hash": "QmdMfrUsh8tvAj5MuWEFxYR7VjpmXvihxSZZZWoJYE3LMR",
140195
"name": "21045.png",
196+
"hash": "QmdMfrUsh8tvAj5MuWEFxYR7VjpmXvihxSZZZWoJYE3LMR",
141197
"size": 37161,
142198
"mimetype": "image/png",
143-
"timestamp": 1699457573592
199+
"type": "image",
200+
"timestamp": 1699457573592,
201+
"added_time": 1699457573
144202
}
145-
]
203+
],
204+
"files_per_page": 50,
205+
"total_files": 1
146206
}
147207
```
148208

149209
***
150210

151211
#### 3. `/api/v0/put`
152212

153-
**Description:** Upload one or more files. Subject to the 5 GB per-file limit and your plan's storage capacity.
213+
**Description:** Upload a **single file**. Subject to the 5 GB per-file limit and your plan's remaining capacity. To upload several files in one request, use `/putfolder`.
214+
215+
The form field name is not significant — the first uploaded file in the request is used.
154216

155217
```bash
156218
curl "https://api.fluxdrive.runonflux.io/api/v0/put" \
157219
-X POST \
158220
-u "<ZELID>:<API_KEY_SECRET>" \
159-
-H "Content-Type: multipart/form-data" \
160-
-F file=@"<file1>" \
161-
-F file=@"<file2>"
221+
-F file=@"./21045.png"
162222
```
163223

164-
**Example Response (single file):**
224+
**Example Response:**
165225

166226
```json
167227
{
168-
"status": "success",
169-
"files": [
170-
{
171-
"name": "21045.png",
172-
"hash": "QmdMfrUsh8tvAj5MuWEFxYR7VjpmXvihxSZZZWoJYE3LMR",
173-
"mimetype": "image/png",
174-
"size": 37161
175-
}
176-
]
228+
"hash": "QmdMfrUsh8tvAj5MuWEFxYR7VjpmXvihxSZZZWoJYE3LMR",
229+
"name": "21045.png",
230+
"size": 37161,
231+
"mimetype": "image/png",
232+
"thumbnail": "QmXo1x9pTgtvAj5MuWEFxYR7VjpmXvihxSZZZWoJYE3aBc"
177233
}
178234
```
179235

236+
`thumbnail` is the IPFS hash of a generated preview, or `null` when none was produced. Thumbnails are only generated for images under 50 MB.
237+
180238
***
181239

182240
#### 4. `/api/v0/putfolder`
183241

184-
**Description:** Upload multiple files as a folder.
242+
**Description:** Upload multiple files in a single request, optionally into a folder path.
243+
244+
**Arguments:**
245+
246+
* `path` _(string, optional)_ — folder path to place the files under; leading and trailing slashes are stripped
185247

186248
```bash
187249
curl "https://api.fluxdrive.runonflux.io/api/v0/putfolder" \
188250
-X POST \
189251
-u "<ZELID>:<API_KEY_SECRET>" \
190-
-H "Content-Type: multipart/form-data" \
252+
-F path="assets/icons" \
191253
-F file=@"image.png" \
192254
-F file=@"metadata.json"
193255
```
194256

195-
**Example Response (shortened):**
257+
**Example Response:**
196258

197259
```json
198260
{
199-
"status": "success",
200-
"folder": {
201-
"hash": "QmNaS1f8RDbQ9jz5FGkZWvzG5VA6jp4JJBEwQ2DLzhWN8V",
202-
"size": "1965233"
203-
}
261+
"path": "assets/icons",
262+
"files": [
263+
{ "name": "image.png", "hash": "QmNaS1f8RDbQ9jz5FGkZWvzG5VA6jp4JJBEwQ2DLzhWN8V", "size": 1965233 },
264+
{ "name": "metadata.json", "error": "Pinning failed" }
265+
]
204266
}
205267
```
206268

269+
> ℹ️ **`/putfolder` reports per-file outcomes.** The request can return `200` while individual entries carry an `error` field. Always inspect each entry rather than relying on the status code alone.
270+
207271
***
208272

209273
#### 5. `/api/v0/cat`
210274

211-
**Description:** Output the contents of a file from IPFS.
275+
**Description:** Stream the contents of a file inline.
276+
277+
**Arguments:**
278+
279+
* `hash` _(string, required)_ — IPFS hash of a file in your account
212280

213281
```bash
214-
curl "https://api.fluxdrive.runonflux.io/api/v0/cat?arg=<HASH>" \
282+
curl "https://api.fluxdrive.runonflux.io/api/v0/cat" \
215283
-X POST \
216-
-u "<ZELID>:<API_KEY_SECRET>"
284+
-u "<ZELID>:<API_KEY_SECRET>" \
285+
-d "hash=<HASH>"
217286
```
218287

219-
**Arguments:**
220-
221-
* `arg` _(string, required)_ — IPFS file hash
288+
Responses are served with `X-Content-Type-Options: nosniff`, and HTML/SVG/XML content types are downgraded to `application/octet-stream` so the API cannot be used to host executable web content.
222289

223290
***
224291

225292
#### 6. `/api/v0/get`
226293

227-
**Description:** Download a file from IPFS.
294+
**Description:** Download a file as an attachment. Identical to `/cat` except that a `Content-Disposition: attachment` header is set.
228295

229296
```bash
230-
curl "https://api.fluxdrive.runonflux.io/api/v0/get?arg=<HASH>" \
297+
curl "https://api.fluxdrive.runonflux.io/api/v0/get" \
231298
-X POST \
232-
-u "<ZELID>:<API_KEY_SECRET>"
299+
-u "<ZELID>:<API_KEY_SECRET>" \
300+
-d "hash=<HASH>" \
301+
-o downloaded-file
233302
```
234303

235304
***
236305

237306
#### 7. `/api/v0/rm`
238307

239-
**Description:** Remove a file from your FluxDrive account. The hash is unpinned from your subscription; if no other accounts pin it, the cluster will eventually garbage-collect the underlying blocks.
308+
**Description:** Remove a file from your FluxDrive account. The hash is unpinned from your subscription; if no other account references it, the cluster will eventually garbage-collect the underlying blocks.
240309

241310
```bash
242-
curl "https://api.fluxdrive.runonflux.io/api/v0/rm?arg=<HASH>" \
311+
curl "https://api.fluxdrive.runonflux.io/api/v0/rm" \
243312
-X POST \
244-
-u "<ZELID>:<API_KEY_SECRET>"
313+
-u "<ZELID>:<API_KEY_SECRET>" \
314+
-d "hash=<HASH>"
315+
```
316+
317+
**Example Response:**
318+
319+
```json
320+
{ "success": "File removed", "hash": "QmdMfrUsh8tvAj5MuWEFxYR7VjpmXvihxSZZZWoJYE3LMR" }
245321
```
246322

247323
***
248324

249325
#### 8. `/api/v0/thumb`
250326

251-
**Description:** Retrieve a thumbnail for a file.
327+
**Description:** Retrieve the generated thumbnail for a file, as `image/jpeg`. Returns `404` with `{ "error": "No thumbnail" }` when the file has none.
252328

253329
```bash
254-
curl "https://api.fluxdrive.runonflux.io/api/v0/thumb?arg=<HASH>" \
330+
curl "https://api.fluxdrive.runonflux.io/api/v0/thumb" \
255331
-X POST \
256-
-u "<ZELID>:<API_KEY_SECRET>"
332+
-u "<ZELID>:<API_KEY_SECRET>" \
333+
-d "hash=<HASH>" \
334+
-o thumbnail.jpg
257335
```
258336

259337
***
260338

261339
### Notes
262340

263341
* All commands must be executed from a terminal (e.g., **VSCode integrated terminal**, **Ubuntu**, or similar).
264-
* API access is protected via **ZELID** and **API\_KEY\_SECRET** — keep your key secret. If a key is leaked, rotate it immediately by generating a new one in the web UI.
342+
* Parameters go in the request body — `/api/v0` does not read query-string arguments.
343+
* API access is protected via **ZELID** and **API\_KEY\_SECRET** — keep your key secret. If a key is leaked, revoke it in the web UI and generate a replacement.

0 commit comments

Comments
 (0)