輕湖文件快遞櫃 API 文件

輕湖文件快遞櫃(LiteFileShare,隸屬輕湖 Lite Lake)取件碼模式程式化呼叫文件。本頁面面向人,AI Agent 請直接抓取下方 Markdown 原文。

🤖 AI Agent / 爬蟲:請直接抓取 Markdown 原文與 Skill 安裝指引:Skill 安裝引導(分平台)/docs/api.md(EN)/docs/api.zhs.md(中文)/docs/skill.md

LiteFileShare API Docs (Pickup-Code Mode)

LiteFileShare (轻湖文件快递柜) is a no-signup file-sharing product by Lite Lake (轻湖): upload a batch of files → get a 6-digit pickup code → download by code. Files are kept for 48 hours.

  • 中文版:/docs/api.zhs.md
  • Web app: https://fileshare.litelake.com/ (upload / pickup)
  • This Markdown source: /docs/api.md (AI agents / crawlers should fetch this address)
  • Skill install guide: /docs/skill.md (no hand-written HTTP; upload/download in one command)

Base URL

https://fileshare.litelake.com

This is the single public entry of the current deployment (the BFF). All examples below use it. The service is unauthenticated (/api/public zone): no API key, no login. Binary traffic (upload/download) goes straight to SC object storage via presigned URLs and never passes through this service; the service only signs those URLs.

Conventions

  • Except for the presigned PUT/GET, every endpoint is POST with application/json.
  • Responses are always an APIResponse envelope: {"code": 200, "message": "ok", "data": {...}}.
  • HTTP status policy: success and business errors (400/4101/4102/4103/4104) always return HTTP 200 — use body.code to tell them apart. 429 and 503 use real HTTP status codes (429 includes a Retry-After header).
  • Send an X-Device-Id header (UUID, stable per client) on every request: wrong-code rate limiting counts per IP + device, so a stable device id avoids collateral blocking when several clients share one IP.
  • All timestamps are RFC3339 UTC (e.g. 2026-09-12T04:00:00Z).

Rate limits (per IP)

EndpointLimit
POST /api/public/shares/init12/hour + 30/day (plus the 30/min public-write baseline)
POST /api/public/shares/refresh30/minute
POST /api/public/shares/complete30/minute (public-write baseline)
POST /api/public/pickup/verify30/minute total; wrong-code failures 5 per 10 minutes (per IP + device)
POST /api/public/pickup/download60/minute; shares the wrong-code failure counter with verify
POST /api/public/pickup/claim30/minute; shares the wrong-code failure counter with verify (invalid-code claims count as failures)

Error codes

body.codeMeaningHTTP
200Success200
400Invalid parameters / over limits (see message)200
4101Pickup code invalid or expired (uniform wording, anti-enumeration)200
4102Files missing (complete: some files never arrived; data carries missingFileIds)200
4103Upload session deadline passed (complete later than init + 24h)200
4104Pickup code has been claimed and deleted (verify/download/claim hitting the claimed terminal state)200
429Rate limited (HTTP 429 + Retry-After seconds)429
503Storage (SC/Redis) unavailable, fail-closed503

Constraints (defaults)

ItemLimit
Files per batch20
Single file size256 MB
Total batch size2 GB
Upload URL (PUT) validity60 minutes (call refresh to re-sign after a 403)
Download URL (GET) validity5 minutes
complete deadlinewithin 24 hours after init
File retention48 hours after complete

Upload flow (3 steps)

init (get presigned URLs) → PUT each file straight to SC → complete (get the pickup code)

Step 1: POST /api/public/shares/init — create an upload session

curl -sS -X POST https://fileshare.litelake.com/api/public/shares/init \
  -H 'Content-Type: application/json' \
  -H "X-Device-Id: $(cat ~/.cache/litelake/fileshare/device_id 2>/dev/null || uuidgen)" \
  -d '{
    "files": [
      {"filename": "report.pdf", "size": 1048576, "contentType": "application/pdf"},
      {"filename": "data.csv", "size": 2048, "contentType": "text/csv"}
    ]
  }'

Response (data):

{
  "shareId": "b1c2d3e4f5a6",
  "completeDeadline": "2026-09-13T04:00:00Z",
  "files": [
    {"fileId": "f1e2d3c4b5a7", "uploadUrl": "https://sc.../20260912/b1c2.../f1e2...?X-Amz-..."},
    {"fileId": "a9b8c7d6e5f4", "uploadUrl": "https://sc.../20260912/b1c2.../a9b8...?X-Amz-..."}
  ]
}
FieldMeaning
shareIdUpload session ID (pass back to complete)
completeDeadlineHard deadline for complete (init + 24h); later → 4103
files[].fileIdFile ID (used by refresh and the 4102 missing list)
files[].uploadUrlPresigned PUT URL, valid for 60 minutes

Step 2: PUT uploadUrl — upload each file straight to SC

For each file, send a PUT to its uploadUrl with the raw file bytes as body. Do not add custom headers (the signature covers only the path and query string):

curl -sS -X PUT "<uploadUrl>" \
  -H 'Content-Type: application/pdf' \
  --data-binary @report.pdf
  • HTTP 200 means success; 403 means the URL expired (>60 min) — re-sign via step 2.5.
  • For large files in Python, stream the body (see the skill's http.client implementation) instead of reading the whole file into memory.

Step 2.5 (if needed): POST /api/public/shares/refresh — re-sign expired upload URLs

Call this when a PUT returns 403. Idempotent:

curl -sS -X POST https://fileshare.litelake.com/api/public/shares/refresh \
  -H 'Content-Type: application/json' \
  -d '{"shareId": "b1c2d3e4f5a6", "fileIds": ["f1e2d3c4b5a7"]}'

Response data: {"files": [{"fileId": "...", "uploadUrl": "..."}]} — retry the PUTs with the fresh uploadUrl values.

Step 3: POST /api/public/shares/complete — finish and get the pickup code

Call after every PUT succeeded:

curl -sS -X POST https://fileshare.litelake.com/api/public/shares/complete \
  -H 'Content-Type: application/json' \
  -d '{"shareId": "b1c2d3e4f5a6"}'

Response (data):

{
  "pickupCode": "K7M2XQ",
  "expiresAt": "2026-09-14T04:00:00Z",
  "fileCount": 2,
  "totalSize": 1050624
}
  • code=4102: data.missingFileIds lists files that did not land — re-upload them and call complete again.
  • code=4103: the session deadline passed — start over from init.
  • The pickup code is 6 characters from 0-9A-Z (minus I/L/O/U); it expires 48h after complete.

Download flow (2 steps + optional delete)

verify (check code + list files) → download per file (get a presigned GET URL) → (optional) claim (claim & delete)

POST /api/public/pickup/verify — check a code and list files

curl -sS -X POST https://fileshare.litelake.com/api/public/pickup/verify \
  -H 'Content-Type: application/json' \
  -H "X-Device-Id: $DEVICE_ID" \
  -d '{"code": "K7M2XQ"}'

Pickup codes are tolerantly normalized: paste as-is — the server strips spaces/hyphens, upper-cases, maps O→0 and I/L→1.

Response (data):

{
  "expiresAt": "2026-09-14T04:00:00Z",
  "files": [
    {"fileId": "f1e2d3c4b5a7", "filename": "report.pdf", "size": 1048576},
    {"fileId": "a9b8c7d6e5f4", "filename": "data.csv", "size": 2048}
  ]
}

code=4101 means the code is invalid or expired (not distinguished, anti-enumeration). code=4104 means the pickup code has been claimed and deleted (the terminal state entered after the recipient deleted it; the cloud files are destroyed and no longer downloadable).

POST /api/public/pickup/download — sign a download URL

curl -sS -X POST https://fileshare.litelake.com/api/public/pickup/download \
  -H 'Content-Type: application/json' \
  -H "X-Device-Id: $DEVICE_ID" \
  -d '{"code": "K7M2XQ", "fileId": "f1e2d3c4b5a7"}'

Response (data): {"url": "https://sc...?...response-content-disposition=...", "filename": "report.pdf"}

The URL is valid for 5 minutes and the response carries Content-Disposition: attachment (non-ASCII filenames RFC2231-encoded). GET it to download:

curl -sS -o "report.pdf" "<url>"

POST /api/public/pickup/claim — claim & delete (idempotent)

After downloading, the recipient can destroy the share with the code: the pickup code is invalidated immediately and the SC cloud objects are deleted right away (like a parcel locker that destroys the compartment after pickup):

curl -sS -X POST https://fileshare.litelake.com/api/public/pickup/claim \
  -H 'Content-Type: application/json' \
  -H "X-Device-Id: $DEVICE_ID" \
  -d '{"code": "K7M2XQ"}'

Response (data):

{
  "claimedAt": "2026-09-14T08:30:00Z",
  "alreadyClaimed": false
}
FieldMeaning
claimedAtWhen the claim happened (RFC3339 UTC); on idempotent re-entry this is the first claim time
alreadyClaimedtrue means it was already claimed and deleted before (repeat calls return 200, not an error)
  • Idempotent: repeating the call on a claimed code returns 200 + alreadyClaimed: true — friendly for flaky-network retries.
  • Codes are normalized like verify (spaces/hyphens stripped, upper-cased, O→0, I/L→1).
  • code=4101: invalid or expired code (counts toward the wrong-code failure limit — 5 failures trigger a 10-minute ban; claim destroys data with just a code, so the anti-brute-force rules are not waived).
  • After a claim: verify/download on that code return 4104 ("This pickup code has been claimed and deleted"); the claimed row is kept for a 7-day troubleshooting window, then physically deleted — after that the code reads as 4101 again.

Usage notes

  • init/verify are the most abuse-sensitive endpoints: batch files into a single init (up to 20 files) instead of calling per file.
  • 5 consecutive wrong codes trigger a 10-minute ban (per IP + device, shared across verify/download/claim); never brute-force codes.
  • On 429, wait for the Retry-After interval before retrying.
  • No delete API for the uploader: expired files (48h) and stalled sessions (24h) are cleaned up server-side. Recipient-side deletion goes through POST /api/public/pickup/claim (idempotent, code-based).