# Jellything Rust API For making your own applications that implement client functionality, use the `jellyclient` crate. The `jellycommon` crate exposes commonly used structs like those used in the library and for jhls. ## Generated Documentation - [jellything](/doc/jellything/) - [jellycommon](/doc/jellycommon/) - [jellyremuxer](/doc/jellyremuxer/) - [jellytranscode](/doc/jellytranscode/) - [jellyimport](/doc/jellyimport/) - [jellymatroska](/doc/jellymatroska/) - [ebml_derive](/doc/ebml_derive/) - [jellybase](/doc/jellybase/) - [jellystream](/doc/jellystream/) - [jellytool](/doc/jellytool/) # Jellything HTTP API Most endpoints require the `Accept` header to be present and set to `application/json` and `image/avif` respectively. Any endpoint returning JSON, will report errors with an object containing error string in the `error` key. Routes marked with `*` require authentification. The `jellyclient` crate already implements most API functionality. The `jellycommon` crate provides useful structs for deserializing data (also reexported in jellyclient). ```toml # Cargo.toml [depedencies] jellyclient = { git = "https://codeberg.org/metamuffin/jellything.git" } ``` ## General ### GET `/api/version` Returns API version number. ### POST `/api/create_session` Request body contains JSON with keys `username`, `password`, `expire` (in seconds) and `drop_permissions` (a list of permissions, that this session cannot use). The Response contains the session cookie as a string in JSON. ### GET* `/n/?&&` Request a library node with userdata attached. If `parents` or `children` flag is set, all parents/children will be returned too, otherwise those lists are empty. Returns `ApiNodeResponse`. ### GET* `/n//userdata` Returns only `NodeUserData` for that node. ### GET* `/search?&` Returns `ApiSearchResponse`. ### GET* `/items?&` Returns `ApiItemsResponse`. ### GET* `/home` Returns `ApiHomeResponse`. ## Assets Endpoints like `.../poster` redirect to the asset that you need and automatically choose fallbacks. Alternatively you can directly request assets with `/asset/`, but there you need to implement the fallback behaviour yourself. Returned images are coded with AVIF. The `width` parameter is the width of the resolution you want to image to be. > [!WARNING] The actual returned resolution must not be exactly what you > requested. Currently it is rounded up to the next power of two. ### GET* `/asset/?` This is the final asset endpoint where images are returned from. Other endpoints redirect here. The `token` part is an opaque string that you obtain from somewhere else like a redirect or from within the `Node` struct. ### GET* `/n//poster?` ### GET* `/n//backdrop?` ### GET* `/n//thumbnail?&` Returns a single frame from some track video of the media at a given time `t`. ### GET* `/n//person//asset?&` Returns headshot of a person from that node. ## Stream ### GET* `/stream/?&&&&&` Responds with the stream directly or a redirect to the actual source in case of federation. # Planned stream api - `?whep&&` - WHEP Endpoint for streaming that set of tracks. The format used is decided by the server. - `?whepcontrol&` - WebSocket endpoint for controlling WHEP playback. TODO schema - `?remux&&` - `?hlssupermultivariant&` - Returns m3u8/HLS playlist of all known multi-variant playlists, one for each segment. The plylist is updated for live media. - `?hlsmultivariant&&` - Returns m3u8/HLS playlist of all track formats' variant playlists. - `?hlsvariant&&&&` - Returns m3u8/HLS playlist of all known fragments of this track format. The playlist is updated for live media. - `?info&` - Returns JSON `SegmentInfo` if a segment index is provided, else `MediaInfo` - `?fragmentindex&&` - `?fragment&&&&&` ```ts interface MediaInfo { title: string; live: bool; segments: SegmentInfo[]; } interface SegmentInfo { title?: string; duration?: number; tracks: Track[]; } interface Track { title?: string; language?: string; kind: "video" | "audio" | "text"; formats: TrackFormat[]; } interface TrackFormat { codec: string; bandwidth: number; remux: bool; title?: string; containers: StreamContainer[]; a_sampling_frequency?: number; a_channels?: number; v_resolution_width?: number; av_bit_depth?: number; } type FragmentIndex = number[]; type StreamContainer = "webm" | "matroska" | "webvtt" | "jvtt"; ```