Skip to content

Commit 5968bfb

Browse files
authored
Merge pull request #12 from RunOnFlux/fluxdrive-api-reference-accuracy
Correct FluxDrive API reference against the implementation
2 parents 405f447 + be94829 commit 5968bfb

5 files changed

Lines changed: 155 additions & 67 deletions

File tree

docs/fluxcloud/fluxdrive/api-reference.md

Lines changed: 155 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,42 @@ 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+
Sign in at [cloud.runonflux.com/flux-drive](https://cloud.runonflux.com/flux-drive) and scroll to the **API Keys** panel, below your storage usage.
37+
38+
<img src="/.gitbook/assets/fluxdrive-apikeys-panel.png" alt="The API Keys panel in the FluxDrive web UI, with no keys created yet"/>
39+
40+
**1. Click Create key**, then give the key a name you'll recognise later — something that identifies the app or machine that will use it.
41+
42+
<img src="/.gitbook/assets/fluxdrive-apikeys-create.png" alt="The Create API key dialog with a key name entered"/>
43+
44+
**2. Click Generate.** Your new key is displayed along with a ready-to-run `curl` command that already has your FluxID filled in. Use the copy button to the right of either field.
45+
46+
<img src="/.gitbook/assets/fluxdrive-apikeys-reveal.png" alt="The new API key dialog showing the generated key, a ready-to-run curl command, and a warning that the key is shown only once"/>
47+
48+
> ⚠️ **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.
49+
50+
**3. Store the key somewhere safe** — a password manager, or your deployment's secret store — then click **I've saved it**.
51+
52+
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.
53+
54+
#### 4. Managing Your Keys
55+
56+
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. A key that has never been used shows **Never**.
57+
58+
<img src="/.gitbook/assets/fluxdrive-apikeys-manage.png" alt="The API Keys panel listing two keys with their name, key prefix, creation date, last-used date, and a revoke button"/>
59+
60+
| Action | How | Effect |
61+
| ------ | --- | ------ |
62+
| **Revoke a key** | Trash icon next to the key | Immediate. Any application using it starts receiving `401`. |
63+
| **Create another** | **Create key** | Up to 10 keys per subscription. |
64+
65+
Some practical notes:
66+
67+
* Keys do not expire — they stay valid until you revoke them or the subscription lapses
68+
* A key only works while the subscription is **active**; an unpaid or expired subscription returns `402` on every request
69+
* 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
70+
* Use a separate named key per application, so revoking one never takes down the others
71+
* Keys cannot be used to create or revoke other keys — key management always requires a Zelcore signature from the web UI
3872

3973
***
4074

@@ -57,45 +91,64 @@ All endpoints are accessed via **POST** requests with HTTP Basic authentication:
5791
| Limit | Value | Notes |
5892
| ----- | ----- | ----- |
5993
| 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` |
94+
| PUT rate limit | 150 requests / second | Per ZELID + IP, applies to `/put` and `/putfolder` |
95+
| Read rate limit | 1500 requests / second | Per ZELID + IP, applies to every `/api/v0` endpoint |
6296
| Storage capacity | Plan-dependent | See plans on the [overview page](README.md) |
97+
| API keys | 10 per subscription | Revoke one to create another |
6398

64-
Exceeding a rate limit returns HTTP 429 with `Retry-After` headers.
99+
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.
65100

66101
***
67102

68103
### Authentication & Errors
69104

70-
Every request must include valid Basic auth. Failed requests return JSON with an `error` field.
105+
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.
106+
107+
**Authentication failures**
108+
109+
| Status | `error` | Cause |
110+
| ------ | ------- | ----- |
111+
| `401` | `Missing or invalid Authorization header` | No `Authorization: Basic ...` header, or it could not be decoded |
112+
| `401` | `Subscription not found` | No FluxDrive subscription exists for that ZELID |
113+
| `401` | `Invalid API key` | The key is wrong, or it was revoked |
114+
| `402` | `Subscription payment is not active` | Subscription is unpaid, expired, or cancelled |
115+
| `403` | `IP address is not whitelisted` | Your account has an IP allow-list set and the request came from another address |
116+
117+
> ℹ️ **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.
71118
72-
**Common error responses:**
119+
**Request failures**
73120

74121
```json
75-
// 401invalid or missing API key
76-
{ "error": "Invalid credentials" }
122+
// 400hash missing or malformed
123+
{ "error": "Invalid or missing hash" }
77124

78-
// 402 — subscription not active (e.g., expired or unpaid)
125+
// 400 — upload request carried no file
126+
{ "error": "No file provided" }
127+
128+
// 402 — subscription lapsed between auth and upload
79129
{ "error": "Subscription not active" }
80130

81-
// 413 — file exceeds 5 GB or storage capacity exceeded
131+
// 413 — file exceeds the 5 GB per-file limit
82132
{ "error": "File size exceeds 5120Mb" }
133+
134+
// 413 — upload would exceed your plan's storage capacity
83135
{ "error": "Storage capacity exceeded" }
84136

85-
// 404 — hash not found in your account
137+
// 404 — hash is not present in your account
86138
{ "error": "File not found" }
87-
88-
// 429 — rate limited
89-
{ "error": "Too many requests" }
90139
```
91140

141+
> ⚠️ **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.
142+
92143
***
93144

94145
### Supported API Endpoints
95146

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

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

100153
```bash
101154
curl "https://api.fluxdrive.runonflux.io/api/v0/status" \
@@ -107,158 +160,193 @@ curl "https://api.fluxdrive.runonflux.io/api/v0/status" \
107160

108161
```json
109162
{
110-
"status": "success",
111-
"result": {
112-
"active": true,
113-
"capacity_gb": 10,
114-
"storage_used": 2412017,
115-
"remaining": 10733328063
116-
}
163+
"zelid": "1abc...",
164+
"plan_name": "standard",
165+
"active": true,
166+
"capacity_bytes": 53687091200,
167+
"capacity_gb": 50,
168+
"storage_used": 2412017,
169+
"remaining": 53684679183,
170+
"data_transfer_bytes": 91847362,
171+
"period_end": 1767225600
117172
}
118173
```
119174

120175
***
121176

122177
#### 2. `/api/v0/ls`
123178

124-
**Description:** List all files in your FluxDrive storage.
179+
**Description:** List files in your FluxDrive storage, newest first. Results are paginated.
180+
181+
**Arguments** (all optional):
182+
183+
| Field | Type | Default | Notes |
184+
| ----- | ---- | ------- | ----- |
185+
| `page` | number | `1` | 1-based page number, capped at 10000 |
186+
| `size` | number | `50` | Results per page, capped at 500 |
187+
| `currentFolder` | string | `/` | Folder path, or a folder UUID |
188+
| `includeFolders` | boolean | `false` | Include folder entries alongside files |
125189

126190
```bash
127191
curl "https://api.fluxdrive.runonflux.io/api/v0/ls" \
128192
-X POST \
129-
-u "<ZELID>:<API_KEY_SECRET>"
193+
-u "<ZELID>:<API_KEY_SECRET>" \
194+
-d "page=1" \
195+
-d "size=50"
130196
```
131197

132198
**Example Response (shortened):**
133199

134200
```json
135201
{
136-
"status": "success",
137202
"files": [
138203
{
139-
"hash": "QmdMfrUsh8tvAj5MuWEFxYR7VjpmXvihxSZZZWoJYE3LMR",
140204
"name": "21045.png",
205+
"hash": "QmdMfrUsh8tvAj5MuWEFxYR7VjpmXvihxSZZZWoJYE3LMR",
141206
"size": 37161,
142207
"mimetype": "image/png",
143-
"timestamp": 1699457573592
208+
"type": "image",
209+
"timestamp": 1699457573592,
210+
"added_time": 1699457573
144211
}
145-
]
212+
],
213+
"files_per_page": 50,
214+
"total_files": 1
146215
}
147216
```
148217

149218
***
150219

151220
#### 3. `/api/v0/put`
152221

153-
**Description:** Upload one or more files. Subject to the 5 GB per-file limit and your plan's storage capacity.
222+
**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`.
223+
224+
The form field name is not significant — the first uploaded file in the request is used.
154225

155226
```bash
156227
curl "https://api.fluxdrive.runonflux.io/api/v0/put" \
157228
-X POST \
158229
-u "<ZELID>:<API_KEY_SECRET>" \
159-
-H "Content-Type: multipart/form-data" \
160-
-F file=@"<file1>" \
161-
-F file=@"<file2>"
230+
-F file=@"./21045.png"
162231
```
163232

164-
**Example Response (single file):**
233+
**Example Response:**
165234

166235
```json
167236
{
168-
"status": "success",
169-
"files": [
170-
{
171-
"name": "21045.png",
172-
"hash": "QmdMfrUsh8tvAj5MuWEFxYR7VjpmXvihxSZZZWoJYE3LMR",
173-
"mimetype": "image/png",
174-
"size": 37161
175-
}
176-
]
237+
"hash": "QmdMfrUsh8tvAj5MuWEFxYR7VjpmXvihxSZZZWoJYE3LMR",
238+
"name": "21045.png",
239+
"size": 37161,
240+
"mimetype": "image/png",
241+
"thumbnail": "QmXo1x9pTgtvAj5MuWEFxYR7VjpmXvihxSZZZWoJYE3aBc"
177242
}
178243
```
179244

245+
`thumbnail` is the IPFS hash of a generated preview, or `null` when none was produced. Thumbnails are only generated for images under 50 MB.
246+
180247
***
181248

182249
#### 4. `/api/v0/putfolder`
183250

184-
**Description:** Upload multiple files as a folder.
251+
**Description:** Upload multiple files in a single request, optionally into a folder path.
252+
253+
**Arguments:**
254+
255+
* `path` _(string, optional)_ — folder path to place the files under; leading and trailing slashes are stripped
185256

186257
```bash
187258
curl "https://api.fluxdrive.runonflux.io/api/v0/putfolder" \
188259
-X POST \
189260
-u "<ZELID>:<API_KEY_SECRET>" \
190-
-H "Content-Type: multipart/form-data" \
261+
-F path="assets/icons" \
191262
-F file=@"image.png" \
192263
-F file=@"metadata.json"
193264
```
194265

195-
**Example Response (shortened):**
266+
**Example Response:**
196267

197268
```json
198269
{
199-
"status": "success",
200-
"folder": {
201-
"hash": "QmNaS1f8RDbQ9jz5FGkZWvzG5VA6jp4JJBEwQ2DLzhWN8V",
202-
"size": "1965233"
203-
}
270+
"path": "assets/icons",
271+
"files": [
272+
{ "name": "image.png", "hash": "QmNaS1f8RDbQ9jz5FGkZWvzG5VA6jp4JJBEwQ2DLzhWN8V", "size": 1965233 },
273+
{ "name": "metadata.json", "error": "Pinning failed" }
274+
]
204275
}
205276
```
206277

278+
> ℹ️ **`/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.
279+
207280
***
208281

209282
#### 5. `/api/v0/cat`
210283

211-
**Description:** Output the contents of a file from IPFS.
284+
**Description:** Stream the contents of a file inline.
285+
286+
**Arguments:**
287+
288+
* `hash` _(string, required)_ — IPFS hash of a file in your account
212289

213290
```bash
214-
curl "https://api.fluxdrive.runonflux.io/api/v0/cat?arg=<HASH>" \
291+
curl "https://api.fluxdrive.runonflux.io/api/v0/cat" \
215292
-X POST \
216-
-u "<ZELID>:<API_KEY_SECRET>"
293+
-u "<ZELID>:<API_KEY_SECRET>" \
294+
-d "hash=<HASH>"
217295
```
218296

219-
**Arguments:**
220-
221-
* `arg` _(string, required)_ — IPFS file hash
297+
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.
222298

223299
***
224300

225301
#### 6. `/api/v0/get`
226302

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

229305
```bash
230-
curl "https://api.fluxdrive.runonflux.io/api/v0/get?arg=<HASH>" \
306+
curl "https://api.fluxdrive.runonflux.io/api/v0/get" \
231307
-X POST \
232-
-u "<ZELID>:<API_KEY_SECRET>"
308+
-u "<ZELID>:<API_KEY_SECRET>" \
309+
-d "hash=<HASH>" \
310+
-o downloaded-file
233311
```
234312

235313
***
236314

237315
#### 7. `/api/v0/rm`
238316

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.
317+
**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.
240318

241319
```bash
242-
curl "https://api.fluxdrive.runonflux.io/api/v0/rm?arg=<HASH>" \
320+
curl "https://api.fluxdrive.runonflux.io/api/v0/rm" \
243321
-X POST \
244-
-u "<ZELID>:<API_KEY_SECRET>"
322+
-u "<ZELID>:<API_KEY_SECRET>" \
323+
-d "hash=<HASH>"
324+
```
325+
326+
**Example Response:**
327+
328+
```json
329+
{ "success": "File removed", "hash": "QmdMfrUsh8tvAj5MuWEFxYR7VjpmXvihxSZZZWoJYE3LMR" }
245330
```
246331

247332
***
248333

249334
#### 8. `/api/v0/thumb`
250335

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

253338
```bash
254-
curl "https://api.fluxdrive.runonflux.io/api/v0/thumb?arg=<HASH>" \
339+
curl "https://api.fluxdrive.runonflux.io/api/v0/thumb" \
255340
-X POST \
256-
-u "<ZELID>:<API_KEY_SECRET>"
341+
-u "<ZELID>:<API_KEY_SECRET>" \
342+
-d "hash=<HASH>" \
343+
-o thumbnail.jpg
257344
```
258345

259346
***
260347

261348
### Notes
262349

263350
* 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.
351+
* Parameters go in the request body — `/api/v0` does not read query-string arguments.
352+
* 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.
37.1 KB
Loading
79.8 KB
Loading
43.6 KB
Loading
100 KB
Loading

0 commit comments

Comments
 (0)