Last February I lost an entire evening to a single line of text. I had 40 JPGs ready to go up on Adobe Stock, a CSV I was proud of, and I hit submit. Rejected in under a minute. The reason: my header row said Filename and Adobe wants Filename in position one but with five columns exactly, in their order, no extras. I had six columns because I added a "notes" field for myself. One extra column, forty assets, zero uploads.
That night I opened three browser tabs, one per platform, and wrote down the exact headers each uploader demands. This post is what I learned, and why I stopped hand-typing CSVs forever.
Adobe: five columns, no more, no less
Adobe Stock's CSV upload is the strictest of the three. The header row is five columns, and the reviewer-side checks reject a file that does not match. The columns are:
Filename,Title,Keywords,Category,Releases
That is the whole thing. What I got wrong, and what I see other makers get wrong:
- Column count is checked, not just column names. My sixth "notes" column was the actual rejection reason. The header check happens before any human sees your file.
-
Keywords are space-separated inside one quoted cell, not comma-separated. I had been writing
"sunset, beach, ocean"and every asset came through with one giant keyword containing commas. - Category is a number, not a name. If you leave it blank Adobe will try to guess, and its guesses are mediocre. For sticker-adjacent flat art I mostly land in the 8 to 15 range (objects, backgrounds, education).
- Releases can be empty if you have no people or property in the frame. For pure AI-generated vectors and stickers, mine is blank on every row.
The practical rule: five columns, exact names, keywords space-separated, done. Nothing creative goes in this file.
Vecteezy: four columns, and keywords are the whole job
Vecteezy's contributor CSV is shorter:
Filename,Title,Keywords,Category
Four columns. No releases column at all, which tells you something about where their review effort goes. Two things worth knowing:
- Keywords here are comma-separated, unlike Adobe. This is the trap. If you reuse your Adobe CSV and just delete a column, your keywords arrive as one blob and your search ranking suffers for it. I learned this by uploading 20 files and then searching for my own work and finding nothing.
- The title matters more than on Adobe because Vecteezy's search leans harder on title matches. Filename-as-title is fine for a first pass but you are leaving discovery on the table.
Dreamstime: fifteen columns, mostly empty
Dreamstime is the opposite extreme. Their CSV template has fifteen columns, and the honest truth is that most of them stay blank for a solo maker doing AI-assisted work:
Filename,Image Name,Description,Keywords (comma separated),Category 1,Category 2,
Category 3,Extra Keywords,Is Free,Is Editorially Reviewed,Sex,Age,Model Release,
Property Release,Country
The ones that matter:
- Description is a real sentence, not a keyword list. Dreamstime indexes it.
- Is Free and Is Editorially Reviewed are literal yes/no fields. Leave them alone unless you know why you are touching them.
- Model and Property Release stay empty for my work, same as Adobe.
- The three category slots accept their category names, and one is enough.
Fifteen sounds scary. In practice I fill four columns and leave eleven blank on every row, which is exactly why it should be a script and not a spreadsheet session.
Why I stopped maintaining three spreadsheets
Once I had the three header rows written down, the problem reduced itself. Every platform wants the same underlying data: filename, title, keywords, category. They just differ in column count (5, 4, 15), keyword separator (space vs comma), and category format (number vs name vs both).
So I wrote make_metadata.py. You point it at a folder of files and name the platform:
python make_metadata.py ./my-assets --platform adobe --out adobe.csv --ext .jpg
python make_metadata.py ./my-assets --platform vecteezy --out vecteezy.csv --ext .jpg
It writes the header each platform demands and nothing else. Internally it holds one canonical record per asset and renders it three ways. Keywords get space-joined for Adobe, comma-joined for Vecteezy and Dreamstime. It uses only the Python standard library, so there is nothing to install. If I do not pass a titles file, it title-cases the filename, which is fine for a first pass and something I replace before submitting anything that matters.
The other half of the lesson from that February night: after fixing the CSV, I almost uploaded the same batch twice, because my upload had failed but my memory of it had not. Double-posting is the fastest way to get a contributor account flagged. So the second script, upload_tracker.py, is a plain ledger of what is done, and a re-run only ever processes the pending list. Both scripts together are maybe 200 lines. They replaced the single most error-prone hour of my week.
The boring takeaway
The platform CSVs are not hard. They are brittle. Adobe checks column count, Vecteezy wants comma-separated keywords, Dreamstime wants a fifteen-column template where you fill four. Get any one of those wrong and the rejection is instant and silent. Write the headers down once, encode them once, and never hand-edit an upload CSV again.
This whole system, the metadata generator, the upload ledger, the Markdown-to-PDF tool, and the packager that zips products with a 1280x720 cover and a 600x600 thumbnail, is part of what I built while packaging 39 products and 856 MB of output on a 1 vCPU, 2 GB server with no GPU. I put the working scripts and the reasoning behind the rules into the ai sticker factory playbook, along with the pipeline context around them. If you are about to hand-type your fourth platform's CSV, it will save you the evening I lost.
Get ai sticker factory playbook
Building digital products? Free guides & kits for digital product sellers.
Top comments (0)