Invite only Telegram @whiteboxapi to get your key Group @realchromecdm

ChromeCDM 4.10.3112.0 · security level 3

Widevine keys.
One HTTP call.

cdmapi.com is a hosted Widevine CDM. Post a PSSH and a licence URL, get back every kid:key pair with the MPD, the licence endpoint and the headers that produced them — in milliseconds once the content is known.

Cached lookup
~4ms
New challenge
~25s
Cache TTL
24–48h
Compat
pywidevineserve
POST /api/v1/keys
curl -sS -X POST https://cdmapi.com/api/v1/keys \
  -H 'X-API-Key: wb_live_…' \
  -d '{"pssh":"AAAAOnBzc2g…",
       "license_url":"https://…/license"}'

// 200 OK · 4 ms · cached
{
  "ok": true,
  "cached": true,
  "keys": [
    { "kid": "86cd972ae6101ee98a5b257978ee9992",
      "key": "c6cc025018ca244bbd9fa19b2936d7a9" },
    { "kid": "95cb79b362359ae025612b0a169a294e",
      "key": "4ce15066d5eacda65e6a339d7d72f148" }
  ],
  "mpd_url": "https://…/SSPORFHD_HD_SU_SKYUK_3939.mpd",
  "service_url": "https://global-mds.cs.xcal.tv/license",
  "engine": "whitebox"
}
ZEE5JioHotstarSky SportsFreelyVodafone PTTele2 PlayDStvNOW TVMaxLiTVChannel 5Tata Play

Platform

Everything a key pipeline needs

A real CDM in software — plus the boring parts that make it usable in production: caching, quotas, audit and search.

Cache-first by design

Every successful licence round trip is stored — PSSH, all keys, MPD, licence endpoint, headers, page. The next request for the same content never touches the CDM: ~2–5 ms, and the client is told cached: true.

  • Lookup by PSSH or KID, on every path
  • Grouped rows: one playback, many PSSHs, one entry
  • Configurable TTL per deployment

pywidevine serve compatible

Drop-in for RemoteCdm and devine tooling: open, get_license_challenge, parse_license, get_keys, close — with the X-Secret-Key header.

Per-user API keys

One key per client, with expiry, enabled flag, Telegram ID and notes. Rotate or revoke without touching the others.

Concurrency you can reason about

Per-user semaphores return 429 instead of queueing forever; a global cap protects the CDM pool, and a stale session is evicted rather than failing the request.

Full capture, not just keys

A response carries the whole context: the PSSH in every form it was seen, the MPD, the licence URL, the page it came from and the request headers — so you can replay or debug a capture months later.

psshpssh_listkid:keympd_urlservice_urlpage_urlheaderslatency_ms

Key vault search

Query the whole cache by PSSH or by a single KID and get every key from that request back — scriptable over HTTP or with the bundled Python client.

Self-finishing round trip

Hand over the challenge you already hold and the licence endpoint; the API completes the exchange itself — keys exist even when the player gives up waiting.

How it works

Three steps, one endpoint

  1. 01

    Create a key

    Issue an API key in the dashboard — expiry, concurrency and Telegram ID included.

  2. 02

    Send the PSSH

    Post the PSSH and the licence URL, or just the PSSH to ask what the cache already knows.

  3. 03

    Get kid:key

    Keys come back with the MPD, the licence endpoint and a cache flag. The same content is instant next time.

Integrations

Providers we already speak

Anything that issues a standard Widevine licence works. These are the services our provider modules and captures cover today.

Provider names and marks belong to their owners and are listed only to describe interoperability. Only stream content you are entitled to access.

API

Small surface. Sharp edges handled.

Five public endpoints. Everything is JSON with a consistent { ok, error: { code, message } } shape.

Resolve keys for a PSSH

Send a PSSH alone to ask the cache, or add a license_url to perform a real licence round trip. Optional mpd_url, service_url, headers and service_certificate.

  • Cache hit → cached: true, no engine work
  • Miss with no licence URL → 404 cache_miss
  • Auth: X-API-Key, Bearer, or X-Secret-Key
POST /api/v1/keys
{
  "pssh": "AAAAOnBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABo…",
  "license_url": "https://global-mds.cs.xcal.tv/license",
  "mpd_url": "https://…/index.mpd",
  "headers": { "User-Agent": "Mozilla/5.0 …" },
  "use_cache": true
}

Clients

Works with the tools you already run

pywidevine

RemoteCdm points straight at us — no patched forks.

dev = RemoteCdm(
  device_type="CHROME", system_id=40379,
  security_level=3, host="https://cdmapi.com",
  secret="wb_live_…", device_name="ChromeCDM")

HTTP

Any language with a request library. One POST, one JSON body.

curl -sS -X POST \
  https://cdmapi.com/api/v1/keys \
  -H "X-API-Key: wb_live_…" \
  -d '{"pssh":"…"}'

Key vault CLI

Search the cache from a shell or a cron job.

python3 vault.py --kid 86cd97…
python3 vault.py --pssh AAAAOnBz…
python3 vault.py 86cd97… --keys-only

cdmapi.com vs decryptlabs

They resell an Android L3 dump. We emulate the real Chrome CDM.

decryptlabs and the handful of services that copy it are a queue of cheap Android L3 device dumps behind a JSON wrapper: an extracted blob running on an emulator, replayed until the provider notices. It works on low-value content, quietly dies everywhere else, and you paid a subscription for the privilege of finding out.

decryptlabs & L3 dump resellers

  • Extracted libwvcdm blob driven by an emulator
  • One device identity shared across thousands of customers
  • Providers fingerprint and blacklist it within days
  • No service certificate, no privacy mode, no HW-backed path
  • Serial queue: 30 s+ per request, then a timeout
  • Sold per seat at a premium while the backend costs them pennies
  • Nothing cached: same PSSH, same fee, every single time

cdmapi.com

  • Chrome CDM 4.10.3112.0 emulated instruction-by-instruction in software
  • Real client_id.bin identity, security level 3, correct 0804 challenge
  • Service certificate support and privacy-mode challenges
  • Every capture cached with its MPD, licence endpoint, page and headers
  • Warm lookups in 2–5 ms, deterministic output
  • One flat price, no per-seat markup, no resold keys

We are not reselling somebody else's device farm. This is a cracked, fully software-emulated Chrome CDM — the same challenge a real Chrome browser produces, without the browser. Compare the challenge blobs yourself and the difference is not a matter of opinion.

Comparison based on publicly observable behaviour of the services named. Corrections welcome — message @whiteboxapi.

Signal

People who stopped guessing

Handles shared with permission. No logo walls, no rented quotes.

★★★★★
Moved a whole VOD pipeline over in one afternoon. Same PSSH that used to fail on an L3 dump returns three keys instantly now.
DK@devkestrelstreaming integrator
★★★★★
The vault search alone paid for itself. I paste a kid and get the MPD, the licence URL and every other key from that request.
MR@mara_rresearch engineer
★★★★★
Was paying triple for an “Android farm” API that broke every other week. Twelve days here, zero failed challenges.
TN@tunnelnullIPTV operator
★★★★★
RemoteCdm worked without touching a line of code. That never happens with these services.
SV@sve.pytooling dev
★★★★★
First key in maybe four minutes, including the Telegram onboarding. The status line telling me “resolved · 3 keys” is weirdly satisfying.
AO@alex_orQA automation
★★★★★
Cached responses come back in single-digit milliseconds. Our player starts faster on cached content than on the origin manifest.
HB@hb_labplayer team lead

Pricing

Pay for the CDM, not for the waiting

One flat monthly price. Cached lookups are unmetered — fresh CDM challenges are what the plan covers.

Starter

$30/mo

Everything you need to build and ship against the API.

  • 1 API key, per-user quota
  • 2 concurrent requests
  • 24 h cache TTL
  • Vault search by PSSH or KID
  • Telegram support
Buy Starter — $30

FAQ

Straight answers

What exactly does the API return?

A JSON object with the request's PSSH, every content key as kid:key pairs, the MPD URL, the licence endpoint, latency and whether the answer came from the cache.

Is it compatible with pywidevine RemoteCdm?

Yes. We implement the pywidevine serve surface — /open, /get_license_challenge/STREAMING, /parse_license, /get_keys/CONTENT, /close — authenticated with X-Secret-Key, so RemoteCdm and devine-style tooling work unchanged.

How fast are cached lookups?

About 2–5 ms with no CDM work. A brand new PSSH needs a fresh challenge, which takes roughly 25 seconds because the CDM is emulated fully in software — that is why the cache exists.

Which providers are supported?

Any service issuing a standard Widevine licence. Documented integrations include ZEE5, JioHotstar, Sky and Sky Sports, Freely, Vodafone Portugal, Tele2 Play, DStv, NOW TV, Max, LiTV, Channel 5, Tata Play and YouTube.

Do you store the keys I capture?

Yes — that is the design. Every successful request is cached with its PSSH, keys, MPD, licence endpoint, page URL and headers, so the next call is instant and the key vault can find it again.

What happens when I hit my concurrency limit?

You get 429 concurrency_limit immediately rather than a request that hangs. A global cap is separate and answers 503 global_busy.

Get a key in under a minute

Keys are issued by hand on Telegram. Say what you are building and you get an API key plus the client config for your dashboard.

Or leave an email and we will send the invite link to the same Telegram bot.