Page:
Floatplane API
Clone
1
Floatplane API
claude edited this page 2026-10-25 09:38:51 +01:00
Floatplane API (unofficial) — what the plugin uses
Condensed from doc/floatplane-api-notes.md and doc/research/floatplane-api-research.md in the main repo. Verified with plain curl on 2026-10-25 (custom User-Agent, no cookie unless stated). Base URL https://www.floatplane.com.
Public (no cookie)
| Endpoint | Notes |
|---|---|
GET /api/v3/creator/named?creatorURL[0]=<urlname> |
→ [Creator] incl. channels[], liveStream, subscriptionPlans |
GET /api/v3/creator/channels/list?ids[0]=<creatorId> |
→ [Channel] (id, creator, title, urlname, order, icon, cover, card) |
GET /api/v3/content/creator?id=<creatorId>&limit=20&fetchAfter=<offset> |
post listing, newest first. Filters: channel=<channelId>, search=<text> (title/body), hasVideo=true (also hasAudio/hasPicture/hasText, mutually exclusive), tags[0]=…, fromDate/toDate (ISO 8601), fromDuration/toDuration (seconds), `sort=ASC |
GET /api/v3/content/tags?creatorIds[0]=<creatorId> |
→ { "<tag>": count, … } |
https://pbs.floatplane.com/... |
thumbnails / icons / covers / timeline sprites; childImages[] carry _WxH variants |
Login required (cookie sails.sid)
| Endpoint | Notes |
|---|---|
GET /api/v3/user/self |
cookie probe → {id, username, email, profileImage} |
GET /api/v3/user/subscriptions?active=true |
→ [{plan{id,title,price}, creator:<creatorId>, startDate, endDate}] |
GET /api/v3/creator/info?id= · GET /api/v3/creator/list?ids[0]= |
creator details by id |
POST /api/v3/content/creator/list {ids:[…], limit} |
multi-creator feed with lastElements cursors |
GET /api/v3/content/post?id=<postId> |
full post with videoAttachments[] objects (id, title, duration, levels[], textTracks[]) and attachmentOrder |
GET /api/v3/content/video?id=<videoId> |
video details, progress (resume seconds), timelineSprite |
GET /api/v3/delivery/info?scenario=onDemand|download|live&entityId=<videoId> |
groups[].origins[].url + variants[]{name:"1080-avc1", label, url (+JWT token, 6 h), enabled, hidden, meta{video{codec,width,height,fps,bitrate}, audio{…}, common.access.deniedReason}}. Rate-limited ≈2/min. |
GET /api/video/watchKey?token=… |
HLS AES-128 key (16 bytes) — the only playback request that needs the cookie |
GET /api/v3/content/progress?ids[0]=&contentType=blogPost · POST /api/v3/content/progress {id, contentType:"video", progress:<s>} |
watch progress (read = percent, write = seconds) |
Auth facts
POST /api/v3/auth/login {username,password,captchaToken}→invalidCaptchaTokenErrorwithout a Cloudflare Turnstile token, for every User-Agent tested (browser, Hydravion, Wasserflug/CFNetwork, Android, okhttp).- OAuth2/OIDC:
https://auth.floatplane.com/realms/floatplane/.well-known/openid-configuration(device-code grant, DPoP supported). Third-party clients (Hydravion, Wasserflug, floatplane-downloader, Floaty, FloatNative) have Floatplane-registered client ids; an unregistered id getsinvalid_client. Access token 30 min, refresh token 90 days sliding (measured by the community canary). - Session cookie lifetime: not documented; the plugin reports
invalidand logs a warning when Floatplane rejects it.
Playback (VOD)
origin = groups[0].origins[0].url e.g. https://cdn-vod-drm2.floatplane.com
playlist = origin + variant.url /Videos/<videoId>/1080.mp4/chunk.m3u8?token=<JWT>
chunk.m3u8: #EXT-X-KEY:METHOD=AES-128,URI="https://www.floatplane.com/api/video/watchKey?token=…" ← needs cookie
<base64json>.ts?token=<JWT> ← token only, CORS *
Variants above the account's tier come back enabled:false, url:"" with meta.common.access.deniedReason = isMissingPermission. Subtitles: video.textTracks[].src is an S3-presigned VTT URL valid 15 minutes.
Etiquette
Unique User-Agent (Jellyfin-Floatplane/<version> (+repo url)), honour 429/Retry-After, cache delivery/info per video for the token lifetime, personal use with your own subscription.