API Endpoint(s) and/or Zoom API Event(s)
-
List All Recordings —
GET /users/{userId}/recordings -
Get Meeting Recordings —
GET /meetings/{meetingId}/recordings -
File download via the
download_urlreturned for each recording file (302-redirects tohttps://ssrweb.zoom.us/``...)
Description
We run a user-managed OAuth app that archives cloud recordings (RecordFlow, Zoom marketplace reviewed). For each meeting we call the recordings endpoint above, then download every file from its download_url with Authorization: Bearer <user token>, following redirects. Granted scopes include cloud_recording:read:list_recording_files and cloud_recording:read:recording.
Files with recording_type: "timeline" (the timeline.json artifact) consistently fail with HTTP 403, while every other file in the same recording downloads successfully via the identical code path and token.
This is type-specific and at scale:
-
Only
timelinefails. In the same meetings these all succeed:shared_screen_with_speaker_view.mp4,gallery_view.mp4,active_speaker.mp4,audio_only.m4a,audio_transcript.vtt,summary.json,chat_file.txt. -
~2,160 failed timeline-download attempts over the last 7 days, 100% the same error (no mixed failure modes).
-
Affected recordings span 2024-08 through 2026-05, and timeline files from those same older dates succeed elsewhere — so there’s no date cutoff; failures cluster by meeting/account.
What I’ve already ruled out:
-
Not our auth header — re-requesting the redirected
ssrweb.zoom.usURL with noAuthorizationheader at all returns the same 403, so the signed URL’s own credentials are rejected at the CDN, independent of our token. -
Not URL expiry — minting a fresh
download_urland downloading immediately still 403s; ~1,180 fresh-URL retries over 7 days, 0% success. -
Not a missing artifact — the recordings response reports these files with a non-zero
file_size(0.2–5.2 MB) and a validdownload_url. -
Not scopes — a scope issue would be an API-level 401 before the redirect; we get a clean 302 and fail only at the CDN.
Questions:
-
Why would a
timelinefile’s signeddownload_urlreturnAccessDeniedatssrweb.zoom.uswhen every sibling file in the same recording downloads? -
Is there a different/required way to fetch
timelinefiles (a distinct token, header,download_access_token, orinclude_fieldsparameter)? -
If the timeline object is genuinely unavailable for certain recordings, is there a field in the recordings response we can read to detect that up front and skip it?
I can share affected meeting UUIDs and the account ID privately via DM to any Zoom staff who can look them up.
Error?
HTTP/1.1 403 Forbidden
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message></Error>
How To Reproduce
Steps to reproduce the behavior:
-
Request URL / Headers / Body
-
GET https://api.zoom.us/v2/meetings/{meetingId}/recordingsHeader:Authorization: Bearer <redacted user token> -
In the response, locate the file object with
"recording_type": "timeline"(non-zerofile_size, validdownload_url). -
GET <download_url>withAuthorization: Bearer <redacted>and follow redirects →302tohttps://ssrweb.zoom.us/...→ 403 AccessDenied. -
Repeat the redirected
ssrweb.zoom.usGET with no Authorization header → still 403 AccessDenied.
-
-
Authentication method / app type — User-managed OAuth app; user-level access token with
cloud_recording:read:*scopes. -
Any errors —
403 AccessDenied(XML body above). Every otherrecording_typein the same response downloads with200.