DEV Community

Cover image for Adobe Vecteezy And Dreamstime CSV Headers That Pass Review The First Time

Adobe Vecteezy And Dreamstime CSV Headers That Pass Review The First Time

I still have the rejection email open in a browser tab from last March. Forty-one vectors, a full weekend of work, submitted to Adobe Stock in one batch. Rejected in under an hour, and not for the art. The CSV header was wrong. I had guessed the column order from a forum post from 2019. Adobe's ingest checks the header before it even looks at a single thumbnail, so all forty-one files came back with the same generic error and I had to resubmit the whole batch.

That was the moment I stopped guessing and started writing the headers down. This post is what I learned, and at the end I'll point to the scripts I built so I never have to think about this again.

Adobe wants five columns, in that order

Adobe Stock's contributor upload CSV is the simplest of the three, which is why it stings the most when it fails. Five columns:

Filename,Title,Keywords,Category,Releases
Enter fullscreen mode Exit fullscreen mode

The rules that actually matter, learned the hard way:

  • Filename must match the uploaded file exactly, extension included. A case mismatch counts as a mismatch.
  • Title maxes out around 200 characters. Going over does not truncate, it fails.
  • Keywords are comma separated inside the one cell, up to 49 of them. The first ten carry the most weight in search, so stop padding with synonyms and put your real terms first.
  • Category is a number from 1 to 21, not a name. Writing "Nature" in that column is an instant fail. I keep the numbered list taped to my monitor.
  • Releases is almost always empty for generated or owned work. Leave it blank, do not write "N/A".

One more Adobe-specific thing: if you are submitting AI generated content, you must check the "Created using generative AI" box during submission. The CSV cannot carry that flag, so the metadata script gets the file ready but the checkbox is on you. Skipping it is the fastest route to an account review.

Vecteezy is four columns and stricter on titles

Vecteezy's CSV is:

Filename,Title,Keywords,Category
Enter fullscreen mode Exit fullscreen mode

Same shape as Adobe minus Releases, but the review culture is different. Vecteezy reviewers actually read titles. A title that is a keyword dump like "flower floral spring bloom nature petal" reads as spam and gets the whole batch flagged. Write it as a short descriptive phrase, seven words or fewer, and let the keywords column do the searching work. Vecteezy also asks that AI generated submissions be marked as such on their submission form, same caveat as Adobe.

Dreamstime is fifteen columns and most of them stay empty

Dreamstime is the one that broke my parser twice. Fifteen columns:

Filename,Image Name,Description,Category 1,Category 2,Category 3,Keywords,
Free,Warranty,Model Release,Property Release,Image Type,Extra Instructions,
Editorial,Adult Content
Enter fullscreen mode Exit fullscreen mode

The traps:

  • The header row itself has to be present, which sounds obvious until you export a template that starts with a comment line.
  • Categories here are also numeric, and only Category 1 is required.
  • Free, Warranty, and the release columns take yes/no or blank. Blank means no, which is what you want most of the time.
  • Image Type is where you say illustration versus photo, and getting it wrong sends your vector into the photo review queue where it will sit for weeks.

Because so many columns are optional, my script fills only Filename, Image Name, Description, Category 1, Keywords, and Image Type, and writes empty strings for the rest. That passes. Filling in everything "just in case" is how you get adult-content or editorial flags you did not ask for.

The mistake that almost ended the whole project

After I fixed the headers, I ran my upload batch twice on the same day. Same files, same CSV, because I forgot the first run had gone through. Double-posting identical assets is one of the fastest ways to get a contributor account flagged on every one of these platforms. Adobe caught it. I got a warning, not a ban, but a warning on a fresh account is not a place you want to be.

So I wrote upload_tracker.py, which is about sixty lines of standard library Python. It keeps a ledger file of what has been marked done, pending shows what is left, and a re-run simply cannot re-post a finished asset. Boring code. It has saved me from myself at least three times since.

The other habit: keep the machine small and honest

None of this needs a beefy box. The whole pipeline, prompt engine through packaging, ran on 1 vCPU and 2 GB RAM with no GPU. The habits that made that work: one image job at a time, never in parallel, gc.collect() after each asset, and measuring peak RSS with resource.getrusage(RUSAGE_SELF).ru_maxrss instead of guessing. On a 2 GB box the difference between average and peak memory is the difference between a finished batch and an OOM kill at file 300.

Where this lives now

After the rejection, the double-post scare, and the Dreamstime parser failures, I stopped editing CSVs by hand. The result is the Pipeline Starter Kit: four standalone Python scripts, two of which (make_metadata.py and upload_tracker.py) need nothing but the standard library. make_metadata.py writes the exact Adobe 5-column, Vecteezy 4-column, and Dreamstime 15-column headers from a folder of files, and upload_tracker.py keeps the ledger. The kit is the same tooling that packaged 39 products and 856 MB of output on that 2 GB server, plus a PDF renderer and a product packager. If you just want the metadata part, the install is optional. That is deliberate.

See the kit


Building digital products? Free guides & kits for digital product sellers.

Top comments (1)

Collapse
 
launchgatecheck profile image
Launch Gate •

A useful regression fixture for make_metadata.py: a title containing both a comma and a quote, several comma-separated keywords, and an empty final Releases cell. Write it, read it back with csv.reader, then assert the original title/keywords and exactly five fields survived. For the Dreamstime export, assert fifteen fields even when the last optional cells are empty. That separates "the header is right" from "every row still lines up after quoting." Do you ship a tiny round-trip fixture with the scripts? It would let buyers check their local edits without risking a real submission.