Title Casing and Ranked Keywords in a Stock Metadata CSV Without the Guesswork
Description and use
Scripts generate CSVs with exact headers, correctly title‑case filenames, rank keywords, and prevent duplicate uploads, enabling successful batch submissions to Adobe Stock, Vecteezy, and Dreamstime.
Problem
Uploading 60 vector files to Adobe Stock failed because the CSV header row was incorrect, causing instant rejection.
Outcome
The scripts produce correctly formatted CSVs, ranked keywords, and prevent duplicate uploads, enabling successful batch submissions to Adobe Stock, Vecteezy, and Dreamstime.
Workflow
- 1. Define platform‑specific header rows (Adobe Stock: 5 columns, Vecteezy: 4 columns, Dreamstime: 15 columns).
- 2. Generate titles from filenames using hyphen/underscore split, capitalize first/last words, keep short connectives lowercase, force uppercase for acronyms, preserve mixed‑case words.
- 3. Create a titles.json file for manual corrections and provide it via --titles option.
- 4. Rank keywords: keyword 1 is the primary noun; keywords 2‑10 are buyer‑search terms; keywords 11+ are long‑tail descriptors.
- 5. Write keywords comma‑separated into the Keywords column in the defined order.
- 6. Use upload_tracker.py to record completed uploads and skip already‑done assets.
- 7. Run the entire pipeline on a minimal environment (1 vCPU, 2 GB RAM).
Evidence
I once uploaded 60 vector files to Adobe Stock and got every single one bounced back in under a minute. The CSV was fine to my eyes. The problem was the header row: I had written the columns in an order I thought made sense, and Adobe's ingest checks the header before it checks anything else.
The rejection is instant and dumb. It does not read your beautiful titles if column two is where column three should be.
My rule is simple and mechanical: Keyword 1 is the single most important noun. For a cat sticker, it is "cat", not "cute".
After I did it once, I built upload_tracker.py, a plain-text ledger using nothing but the standard library.
- Record date: 2026-10-18T03:41:06.272Z