amazon-photos-album-download
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
Download every original file from a public Amazon Photos shared album —
the kind of link you get from "Share → Copy link", e.g.
https://www.amazon.ca/photos/share/qGAyl…. No Amazon login is needed for a
public share; the album authorizes anonymously via its shareId.
When to use
- You shared an album with someone and need the originals back locally to
re-process them (the #1 case: convert iPhone HEIC originals to JPEG for a
recipient who can't open HEIC — then see the
heic-to-jpeg-bundle skill).
- You want to re-host an album's photos yourself (a static gallery, a ZIP).
- You need a verified, complete local backup of a share you (or someone) sent.
How it works
Amazon Photos is a React app over Amazon Drive's /drive/v1/ JSON API. A
public share exposes, with just the shareId as auth:
GET /drive/v1/shares/<shareId> → the root SHARED_COLLECTION node id.
GET /drive/v1/nodes/<root>/children?limit=1… → the album folder node id.
GET /drive/v1/nodes/<album>/children?filters=…image*+OR+video*…&limit=200…
→ the list of asset nodes (name, contentProperties.contentType, size).
- per node:
GET /drive/v1/nodes/<id>/contentRedirection?download=true&shareId=…
→ the original bytes.
The script runs the JSON calls inside a headless Chrome page (via Playwright)
so they carry the exact cookies/headers the web app uses, then writes each file
under its real name and verifies the byte size against contentProperties.size.
A manifest.json records every node id, name, type, and size.
Prerequisites
bun, playwright-core, and Google Chrome installed.
- The album link must be public (open it once in a logged-out browser to
confirm it doesn't redirect to a sign-in wall).
# one-time, in the dir you'll run from (or any scratch dir):
mkdir -p ~/scratch/amazon-album && cd ~/scratch/amazon-album
bun add playwright-core
Quick start
SKILL_DIR="$(dirname "$(find ~/.claude ~/eon -path '*/amazon-photos-album-download/scripts/download-album.ts' 2>/dev/null | head -1)")"
ALBUM_URL="https://www.amazon.ca/photos/share/REPLACE_WITH_SHARE_ID" \
ALBUM_OUT="$HOME/Pictures/my-album-originals" \
bun "$SKILL_DIR/download-album.ts"
Then convert + bundle for sharing:
BUNDLE="$(dirname "$(find ~/.claude ~/eon -path '*/heic-to-jpeg-bundle/scripts/make-bundle.sh' 2>/dev/null | head -1)")"
bash "$BUNDLE/make-bundle.sh" --src "$HOME/Pictures/my-album-originals" --zip --zip-cap-mib 25
Options (env vars)
| Env |
Default |
Meaning |
ALBUM_URL |
(required) |
The /photos/share/<id> URL |
ALBUM_OUT |
./album-originals |
Output directory |
ALBUM_INCLUDE |
image |
image, image,video, or all |
ALBUM_PROFILE_DIR |
~/.cache/amazon-album/chrome |
Persistent Chrome profile dir |
ALBUM_CHROME_CHANNEL |
chrome |
Playwright Chrome channel |
ALBUM_PAUSE_MS |
800 |
Delay between downloads (be gentle) |
Key facts and gotchas
- The album may hold more than you think. A "~40 photo" album can list 100+
asset nodes once you count Live-Photo stills and videos. The default
ALBUM_INCLUDE=image keeps just still images; widen it if you want videos.
contentRedirection?download=true returns the original, not a thumbnail.
The album-listing tempLinks can be downsized (the app requests
lowResThumbnail=true); always pull originals via contentRedirection.
- Run the JSON calls in-page. Calling
/drive/v1/ from plain curl fails —
the share auth rides on the browser context. The script uses page.evaluate
(JSON) + context.request (binaries), both inside the loaded album context.
- Size-verify. Each file is checked against
contentProperties.size (±2%);
the manifest.json verified count should equal selected.
- Undocumented API. This is Amazon's internal Drive API. It works today; if
it breaks, load the album in a headed browser and re-watch the
/drive/v1/
requests to re-derive the endpoints.
- Privacy. Originals often carry GPS EXIF, license plates, VIN/odometer, and
home surroundings. Store them outside any git repo and don't re-host them
publicly without thought (an unlisted host + the
heic-to-jpeg-bundle password
ZIP is the cautious default).
Post-Execution Reflection
After running, before closing:
- Did
verified < selected? Investigate the failed nodes (rate limiting,
a node type without contentRedirection); note the fix.
- Did an API call 4xx/5xx? Amazon may have changed an endpoint — re-derive
from a headed browser and update
download-album.ts + the steps above.
- Only update this SKILL.md for real, reproduced changes.
1---2name: amazon-photos-album-download3description: Download the original photo and video files from a public Amazon Photos shared album (an amazon.com/amazon.ca /photos/share/<id> link) via Amazon Drive's own JSON API, no login required. Drives headless Chrome with Playwright, lists the album nodes, and pulls size-verified originals. Use when you need a local copy of every file in a shared Amazon Photos album, to re-process or re-host them (e.g. convert HEIC to JPEG, build a gallery). TRIGGERS - amazon photos download, download shared album, amazon photos share link, pull amazon album, amazon drive share, save amazon photos.4---5
6# amazon-photos-album-download
7
8> **Self-Evolving Skill**: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
9
10Download every **original** file from a **public Amazon Photos shared album** —
11the kind of link you get from "Share → Copy link", e.g.
12`https://www.amazon.ca/photos/share/qGAyl…`. No Amazon login is needed for a
13public share; the album authorizes anonymously via its `shareId`.
14
15## When to use
16
17- You shared an album with someone and need the originals back locally to
18 re-process them (the #1 case: **convert iPhone HEIC originals to JPEG** for a
19 recipient who can't open HEIC — then see the `heic-to-jpeg-bundle` skill).
20- You want to re-host an album's photos yourself (a static gallery, a ZIP).
21- You need a verified, complete local backup of a share you (or someone) sent.
22
23## How it works
24
25Amazon Photos is a React app over **Amazon Drive's `/drive/v1/` JSON API**. A
26public share exposes, with just the `shareId` as auth:
27
281. `GET /drive/v1/shares/<shareId>` → the root `SHARED_COLLECTION` node id.
292. `GET /drive/v1/nodes/<root>/children?limit=1…` → the album **folder** node id.
303. `GET /drive/v1/nodes/<album>/children?filters=…image*+OR+video*…&limit=200…`
31 → the list of asset nodes (name, `contentProperties.contentType`, `size`).
324. per node: `GET /drive/v1/nodes/<id>/contentRedirection?download=true&shareId=…`
33 → the original bytes.
34
35The script runs the JSON calls **inside a headless Chrome page** (via Playwright)
36so they carry the exact cookies/headers the web app uses, then writes each file
37under its real name and **verifies the byte size** against `contentProperties.size`.
38A `manifest.json` records every node id, name, type, and size.
39
40## Prerequisites
41
42- `bun`, `playwright-core`, and **Google Chrome** installed.
43- The album link must be **public** (open it once in a logged-out browser to
44 confirm it doesn't redirect to a sign-in wall).
45
46```bash
47# one-time, in the dir you'll run from (or any scratch dir):
48mkdir -p ~/scratch/amazon-album && cd ~/scratch/amazon-album
49bun add playwright-core
50```
51
52## Quick start
53
54```bash
55SKILL_DIR="$(dirname "$(find ~/.claude ~/eon -path '*/amazon-photos-album-download/scripts/download-album.ts' 2>/dev/null | head -1)")"
56
57ALBUM_URL="https://www.amazon.ca/photos/share/REPLACE_WITH_SHARE_ID" \
58ALBUM_OUT="$HOME/Pictures/my-album-originals" \
59bun "$SKILL_DIR/download-album.ts"
60```
61
62Then convert + bundle for sharing:
63
64```bash
65BUNDLE="$(dirname "$(find ~/.claude ~/eon -path '*/heic-to-jpeg-bundle/scripts/make-bundle.sh' 2>/dev/null | head -1)")"
66bash "$BUNDLE/make-bundle.sh" --src "$HOME/Pictures/my-album-originals" --zip --zip-cap-mib 25
67```
68
69## Options (env vars)
70
71| Env | Default | Meaning |
72| ---------------------- | ------------------------------ | ----------------------------------- |
73| `ALBUM_URL` | (required) | The `/photos/share/<id>` URL |
74| `ALBUM_OUT` | `./album-originals` | Output directory |
75| `ALBUM_INCLUDE` | `image` | `image`, `image,video`, or `all` |
76| `ALBUM_PROFILE_DIR` | `~/.cache/amazon-album/chrome` | Persistent Chrome profile dir |
77| `ALBUM_CHROME_CHANNEL` | `chrome` | Playwright Chrome channel |
78| `ALBUM_PAUSE_MS` | `800` | Delay between downloads (be gentle) |
79
80## Key facts and gotchas
81
82- **The album may hold more than you think.** A "~40 photo" album can list 100+
83 asset nodes once you count Live-Photo stills and videos. The default
84 `ALBUM_INCLUDE=image` keeps just still images; widen it if you want videos.
85- **`contentRedirection?download=true` returns the original**, not a thumbnail.
86 The album-listing `tempLink`s can be downsized (the app requests
87 `lowResThumbnail=true`); always pull originals via `contentRedirection`.
88- **Run the JSON calls in-page.** Calling `/drive/v1/` from plain `curl` fails —
89 the share auth rides on the browser context. The script uses `page.evaluate`
90 (JSON) + `context.request` (binaries), both inside the loaded album context.
91- **Size-verify.** Each file is checked against `contentProperties.size` (±2%);
92 the `manifest.json` `verified` count should equal `selected`.
93- **Undocumented API.** This is Amazon's internal Drive API. It works today; if
94 it breaks, load the album in a **headed** browser and re-watch the `/drive/v1/`
95 requests to re-derive the endpoints.
96- **Privacy.** Originals often carry GPS EXIF, license plates, VIN/odometer, and
97 home surroundings. Store them outside any git repo and don't re-host them
98 publicly without thought (an unlisted host + the `heic-to-jpeg-bundle` password
99 ZIP is the cautious default).
100
101## Post-Execution Reflection
102
103After running, before closing:
104
1051. **Did `verified` < `selected`?** Investigate the failed nodes (rate limiting,
106 a node type without `contentRedirection`); note the fix.
1072. **Did an API call 4xx/5xx?** Amazon may have changed an endpoint — re-derive
108 from a headed browser and update `download-album.ts` + the steps above.
1093. Only update this SKILL.md for real, reproduced changes.