L3D API Docs Uplynk-compatible emulator API console

Uplynk API, emulated

This site documents an emulator of the Uplynk video platform's developer APIs, running on Cloudflare at services.l3ddash.com and content.l3ddash.com. It answers the same signed calls, in the same shapes, as services.uplynk.com and content.uplynk.com, and serves real HLS for a small sandbox catalog.

It exists so that applications can be built against Uplynk before having an Uplynk account. Code written against it should move to the real service by changing two base URLs, an owner ID and an API key. The video portals on this domain already work that way: every catalog read they make is a signed api2 call.

An independent project, built from Uplynk's public developer documentation. Not affiliated with or endorsed by Uplynk.

Quick start

This is the api2 client from the Uplynk Developer Center, unchanged except for the root URL and the credentials, which are this site's public sandbox account:

The same code with https://services.uplynk.com and your own user ID and API key talks to Uplynk. The repository's uplynk/smoke_test.py runs 19 checks this way, covering assets, libraries, signatures, signed playback, AssetInfo, Preplay and hosted players.

The Uplynk model

Asset
A piece of on-demand content. Its ID is 32 hexadecimal characters (the CMS calls it the GUID). desc is the asset's name; there is no separate description field.
External ID
Your own identifier for an asset, unique only by convention: letters, digits, - and _. Playback and API calls can use it in place of the asset ID, qualified by the owner's user ID.
Slices and rays
Uplynk cuts content into roughly 4-second slices (4.096 s on the real service) and encodes each at several bitrates, called rays and named by letter from the lowest. AssetInfo reports slice_dur, max_slice and the ray bitrates as rates.
Library
A flat, shareable group of assets. There are no nested folders, and libraries don't order their assets.
Metadata
meta is a free-form dictionary on each asset. It carries what other platforms model as fields: descriptions, tags, ratings, sort order.
Owner
Each account has a 32-character user ID. Signed API messages carry it as _owner, external-ID URLs include it, and tokens for external IDs carry it as oid.
Playback token
Assets require a signed playback URL by default (require_drm: 1). The signature is an HMAC of the query string with your API key, so it has to be made on a server.

Coming from Vimeo

VimeoUplynk
videoasset
folder / projectlibrary (flat)
name, descriptiondesc, plus meta for anything else
tags, custom fieldsmeta
player_embed_urlembed_player_url (/player5/<token>.html)
pictures.sizesposter_url, thumb_url, AssetInfo thumbs and thumb_prefix
text trackscaptions inside the HLS/DASH stream, and ttml_url
Bearer token per requestHMAC-signed message per request

Hosts

UplynkEmulatorServes
services.uplynk.com/api2/…services.l3ddash.com/api2/…The original management API
services.uplynk.com/api/v4/…services.l3ddash.com/api/v4/…The versioned API
content.uplynk.comcontent.l3ddash.comManifests, AssetInfo, Preplay, hosted players
cf.cdn.uplynk.com, content-<zone>.uplynk.comcontent.l3ddash.com/slices/…, /session/…Segments, posters, MP4s, per-session playlists. These URLs only ever arrive inside responses and manifests.

Both emulator hosts send CORS headers, so the console on this page calls them directly from your browser.

Authentication

There are no bearer tokens or sessions. Every call carries a message and its signature:

  1. Put the call's parameters in a JSON object and add _owner (your user ID) and _timestamp (Unix seconds).
  2. msg = base64( zlib-compress( JSON ) ). The reference client compresses at level 9; any zlib stream is accepted.
  3. sig = hex( HMAC-SHA256( API key, msg ) ). The signature covers the base64 text exactly as sent.
  4. api2: POST msg and sig as a form body. Uplynk's reference pages write these calls as GET, and the emulator accepts the pair in the query string too, but the reference client POSTs.
    v4: msg and sig go in the query string and sign only _owner and _timestamp; the call's parameters are a JSON body.

The emulator rejects a message whose _timestamp is more than 300 seconds from its clock, as a replay guard. Uplynk's docs don't state their window.

Signature inspector

Type parameters and watch the message being built, using the sandbox credentials. Everything runs in your browser.

Node.js

Responses and errors

Every response has an error field: 0 for success, 1 for failure with a msg explaining why. api2 gives msg as a string; v4 gives a list of strings, as in Uplynk's versioned-API examples.

{"error": 1, "msg": "Asset not found"}
{"error": 1, "msg": ["desc: This field is required."]}

Like api2, the emulator reports invalid parameters with HTTP 200 and error: 1. A bad signature, unknown owner or stale timestamp gets HTTP 403. A call to an Uplynk endpoint the emulator doesn't implement gets 404 and says so.

Sandbox account

These credentials are public. Calls made with the sandbox key run in full, including validation, but save nothing: updates, deletes and new libraries return what the result would be, and the response carries X-Uplynk-Emulator-Mode: sandbox.

User ID (_owner)…
Sandbox API key…
Services root…
Content root…

Catalog

Seven assets in three libraries. Six require a token for playback; EntPEP Explainer doesn't, so you can compare.

Loading…

API reference

Each call below is documented by Uplynk and implemented here. Try it loads the call into the console.

Playback URLs

PlaysURL
An asset/<asset_id>.m3u8
An asset by external ID/ext/<owner_id>/<external_id>.m3u8
Several assets back to back/<id1>,<id2>/multiple.m3u8
Several by external ID/ext/<owner_id>/<e1>,<e2>/multiple.m3u8

On the content host. Uplynk also serves .mpd (DASH), playlists, live channels and live events; the emulator serves HLS for assets only.

Query parameters

start, stopPlay only part of an asset, in seconds. The manifest keeps every slice that overlaps the window.
rates=lo-hiKeep rays whose average bitrate is in the range, in kbps (e.g. rates=150-500).
resolutions=lo-hiKeep rays whose height is in the range (e.g. resolutions=0-720).
tc, exp, rn, ct, cid / eid + oid, sigThe playback token, described next.

Signed URLs and token builder

When an asset has require_drm: 1, its playback URL must carry a token. Append these parameters, then sign:

tc=1Token algorithm version.
expExpiry in Unix seconds. Keep it short, but at least 10 seconds ahead to allow for clock drift.
rnA random number, so signatures don't repeat.
ctContent type: a asset, c channel, e event, p playlist.
cidThe content's ID; or instead eid (external ID) plus oid (your user ID).
sigLast: hex( HMAC-SHA256( API key, everything after ? up to &sig ) ).

Sign on a server: anyone holding the API key can sign any URL. Uplynk's hosted embed and test players sign for you, which is why they are convenient for demos and risky to share.

Manifests

A master playlist lists one variant per ray, plus a WebVTT subtitle group when the asset has captions. As on Uplynk, a mid-quality ray comes first, which is where players start, and each variant is preceded by a private #UPLYNK-MEDIA0 tag (WIDTHxHEIGHTxFPS,profile-level,audio).

#EXTM3U
#EXT-X-VERSION:4
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="English",LANGUAGE="en",AUTOSELECT=YES,DEFAULT=NO,URI="…/session/subs.m3u8?…"
#UPLYNK-MEDIA0:1280x720x30,high-31,0x0
#EXT-X-STREAM-INF:RESOLUTION=1280x720,BANDWIDTH=557580,AVERAGE-BANDWIDTH=395303,CODECS="avc1.64001f",FRAME-RATE=30.000,SUBTITLES="subs"
…/session/c.m3u8?…

Variant playlists start with #UPLYNK-SEGMENT: <asset_id>,<first slice>,segment, as Uplynk's do, and address slices by byte range inside one MPEG-TS file per ray. Several assets are joined with #EXT-X-DISCONTINUITY.

The variant and subtitle playlist URLs are signed by the emulator and expire after 24 hours, so a token check on the master playlist can't be skipped by requesting a variant directly. Uplynk does the same job with playback sessions (pbs) and AES-128 segment keys; the emulator doesn't encrypt segments.

AssetInfo

GET content/player/assetinfo/<asset_id>.json: the public metadata a player shows. No token is needed. Fields follow the real service: asset, external_id, owner, desc, duration, slice_dur, max_slice, rates (kbps), aspect_ratio, meta, poster_url, default_poster_url, thumbs and thumb_prefix, storage_partitions, tv_rating, movie_rating, rating_flags, boundary_details, ad_data, audio_only, is_ad.

Preplay

GET content/preplay/<asset_id>.json (or /preplay/ext/<owner>/<external_id>.json) starts a playback session. It takes the same token as the playback URL and returns:

{
  "ads": {"breakOffsets": [], "breaks": [], "placeholderOffsets": []},
  "playURL": "https://content.l3ddash.com/preplay2/<asset_id>/<sid>.m3u8?…",
  "prefix": "https://content.l3ddash.com",
  "sid": "<session id>",
  "drm": {"required": false}
}

On Uplynk, Preplay is where server-side ad insertion, VAST/VPAID data and Studio DRM license URLs come in. The emulator returns no ad breaks; playURL plays the content directly.

Hosted players

Each asset has an embed_player_url and one or more test_players at content/player5/<token>.html. Hosted players sign their own playback URL, so they play assets that require tokens. asset/update with embed_player_url or test_player_url set mints new ones. The emulator's player is hls.js (native HLS on Safari); append #t=30s to start 30 seconds in and ?autoplay=1 to start playing.

Captions

Uplynk carries captions inside the stream: CEA-608/708 is preserved and can be converted to WebVTT, embedded subtitle text becomes WebVTT, and a sidecar TTML file becomes both. The emulator serves captions the same way, as a segmented WebVTT subtitle rendition aligned to the video with X-TIMESTAMP-MAP, and as the TTML file at the asset's ttml_url. The portal's transcript search reads that TTML.

API console

Signs a call in your browser and sends it to the emulator. Each step of the signature is shown. The sandbox key is filled in; if you have the full key, paste it to make changes that persist. Keys never leave your browser except as signatures.

What is emulated

AreaStatusNotes
api2 signing (msg/sig)Emulatedzlib + base64 + HMAC-SHA256, form body or query string
v4 signingEmulatedQuery-string signature, JSON body
Asset APIEmulatedget, list, update, delete, changes. Not: getframe, getthumbs
Library APIEmulatedget, list, update, assets, assets/add, assets/remove; v4 create
Token APIEmulatedtoken/checkurl, with Uplynk-style notes
Signed playback URLsEmulatedtc, exp, rn, ct, cid, eid+oid, sig. iph (IP hash) is accepted but not checked
HLS playbackEmulatedFour rays, 4.1 s slices, WebVTT captions, start/stop, rates, resolutions, multiple
AssetInfo, Preplay, hosted playersEmulatedNo ads, no DRM; no per-slice thumbnails yet
DASHNot yet.mpd returns 404
Ads and SSAI, PingNot yetPreplay returns empty ad data
Studio DRM, segment encryptionNot yetrequire_studio_drm is stored only
Live channels, events, slicers, schedules, blackoutsNot yetCalls return 404 naming the endpoint
Cloud Slicer (ingest), clips, VLP, syndication, statisticsNot yetThe catalog is seeded from encoded files

Field notes

Details from the Uplynk Developer Center that are easy to miss, and that shaped the emulator.

  • The reference pages and the reference client disagree on the method. Endpoint pages say GET /api2/asset/get; the Call() helper POSTs a form body. Clients should POST.
  • The two API generations sign differently. api2 puts every parameter inside the signed msg. v4 signs only _owner and _timestamp and sends the parameters as JSON, unsigned. A v4 client that signs its body the api2 way gets a signature error.
  • Error shapes differ too: api2 msg is a string, v4 msg is a list.
  • desc means name. Asset and library desc is the display name; descriptions and tags belong in meta.
  • Times are milliseconds in API responses (created, lastmod, asset/changes) and seconds in tokens (exp) and signed messages (_timestamp).
  • External IDs aren't checked for uniqueness. When two assets share one, Uplynk plays an arbitrary match. The _replace: prefix at slicing time reuses an external ID for a re-encode.
  • asset/changes keeps deletions for a short window, about six hours, so a sync job has to poll at least that often to see every delete. The response includes the change at start, so the next call repeats the last change.
  • search on asset/list reached end of life on 2023-03-31; query replaced it and matches any keyword.
  • Tokens are content-bound. cid must match the URL's content, ct its type, and for external IDs oid is always your own user ID, even for content in a library someone shared with you, while the URL path names the sharing account.
  • Signed URLs should expire quickly but not too quickly: at least 10 seconds ahead, because viewers' clocks drift.
  • token/checkurl is a development tool. Uplynk warns that calling it for every token in production can lead to charges or termination.
  • Several assets in one URL (/multiple.m3u8) must total under 16 hours, belong to one account, appear once each and be finished encoding. Uplynk suggests a virtual linear playlist instead, for faster starts and better ad fill.
  • Preplay's playURL is opaque. Uplynk reserves the right to change its format; players use it as given.
  • A real master manifest (public demo asset 42cada5a…) lists a 960x540 ray first, then 720p, 144p, 234p and 360p, all H.264 at 30 fps with AAC audio, plus an I-frame trick-play playlist. Its variants use 4.096 s TS slices on cf.cdn.uplynk.com, each AES-128 encrypted, with key URLs on the session's zone host.