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 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).

# 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/<id>?<parents>&<children>&<filter..>

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/<id>/userdata

Returns only NodeUserData for that node.

GET* /search?<query>&<page>

Returns ApiSearchResponse.

GET* /items?<filter..>&<page>

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/<token>, 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/<token>?<width>

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/<id>/poster?<width>

GET* /n/<id>/backdrop?<width>

GET* /n/<id>/thumbnail?<t>&<width>

Returns a single frame from some track video of the media at a given time t.

GET* /n/<id>/person/<index>/asset?<group>&<width>

Returns headshot of a person from that node.

Stream

GET* /n/<id>/stream?<params..>

Responds with the stream directly or a redirect to the actual source in case of federation.

  • ?whep&<track...>&<seek>
    • WHEP Endpoint for streaming that set of tracks. The format used is decided by the server.
  • ?whepcontrol&<token>
    • WebSocket endpoint for controlling WHEP playback. TODO schema
  • ?remux&<track...>&<container>
  • ?hlssupermultivariant&<container>
    • Returns m3u8/HLS playlist of all known multi-variant playlists, one for each segment. The plylist is updated for live media.
  • ?hlsmultivariant&<segment>&<container>
    • Returns m3u8/HLS playlist of all track formats' variant playlists.
  • ?hlsvariant&<segment>&<track>&<container>&<format>
    • Returns m3u8/HLS playlist of all known fragments of this track format. The playlist is updated for live media.
  • ?info
    • Returns JSON StreamInfo.
  • ?fragmentindex&<segment>&<track>
    • Returns time ranges for every fragment of this track.
  • ?fragment&<segment>&<track>&<index>&<container>&<format>
export type FragmentIndex = TimeRange[];
export interface TimeRange {
  start: number;
  end: number;
}
export interface SubtitleCue extends TimeRange {
  content: string;
}
export interface StreamInfo {
  name?: string;
  segments: SegmentInfo[];
}
export interface SegmentInfo {
  name?: string;
  duration: number;
  tracks: TrackInfo[];
}
export type TrackKind = "video" | "audio" | "subtitles";
export interface TrackInfo {
  name?: string;
  language?: string;
  kind: TrackKind;
  formats: FormatInfo[];
}
export type StreamContainer = "webm" | "matroska" | "mpeg4" | "jvtt" | "webvtt";
export interface FormatInfo {
  codec: string;
  bitrate: number;
  remux: boolean;
  containers: StreamContainer[];

  width?: number;
  height?: number;
  channels?: number;
  samplerate?: number;
  bit_depth?: number;
}