Back to blog
Industries13 min read

How to Import Hundreds of Prompts in Bulk

How bulk import prompts into Prompt Architects: the exact JSON shape it accepts, why CSV needs a conversion step first, and the real dedupe, tagging, and category rules on import.

NH
Nafiul Hasan

TL;DR: To bulk import prompts into Prompt Architects, upload a .json file shaped exactly like our own export format, under 5 MB. The importer skips exact duplicates, folds any custom category back to "All Categories," drops folder assignments entirely, and stops filling once your plan's library limit is full. If your prompts live in a spreadsheet, convert them to that JSON shape first; there's a short script below that does it.

Everything below is read directly from the shipped app source (actions/library.ts, lib/library-export.ts, and components/library/ImportLibraryModal.tsx), verified against the running code on September 5, 2026, not inferred from how the button behaves in a quick test. Where a behavior surprised us while reading the source, that's called out explicitly rather than smoothed over into a tidier story than the code actually tells.

What File Format Does Bulk Import Actually Accept?

One shape, and it's stricter than "any JSON array of prompts." The import button's file picker only accepts .json, and the parser rejects anything that isn't wrapped in our own export envelope: an object carrying a format field that must read exactly prompt-architects/personal-library, plus a version number and an items array. A bare array of prompt objects, with no wrapper, gets rejected before it ever reaches the server, with the message "Unrecognized file format — not a personal-library export."

{
  "format": "prompt-architects/personal-library",
  "version": 1,
  "exported_at": "2026-09-05T00:00:00.000Z",
  "count": 2,
  "items": [
    {
      "title": "Cold Outreach Opener for Series A CTOs",
      "description": "Three variants, 90 words each",
      "content": "Write three 90-word cold email openers...",
      "negative_prompt": "no generic flattery",
      "category": "sales-outreach",
      "tags": ["cold-email", "tested-2026-08"]
    },
    {
      "title": "Support Reply - Refund Request",
      "description": "",
      "content": "Draft a support reply that...",
      "negative_prompt": "",
      "category": "customer-support",
      "tags": []
    }
  ]
}

Only title and content are checked for presence before an item makes it into the batch the app will actually try to save; everything else is optional and defaults sensibly if you leave it out. category needs to be one of the built-in category ids (sales-outreach, customer-support, and so on) rather than a display name, which is worth knowing before you hand-build a file: guessing at a title-cased label instead of the id string will fall back to the default category rather than error out, so you won't necessarily notice the mismatch.

How Do You Bulk Import Prompts from a CSV File?

You convert it first, because the importer genuinely does not read CSV. That's a real limitation worth stating plainly rather than working around with a vague "should work" — the upload input is restricted to .json and application/json at the browser level, so a .csv file never even reaches the parser.

The fix is a short, one-time conversion, and it's mechanical enough that it doesn't need a tool: read your spreadsheet, write out the required JSON wrapper, and upload the result. In Python, assuming a CSV with title, content, category, and a tags column of comma-separated values:

import csv, json

rows = list(csv.DictReader(open("prompts.csv", encoding="utf-8")))

items = [{
    "title": r["title"].strip(),
    "description": r.get("description", "").strip(),
    "content": r["content"],
    "negative_prompt": r.get("negative_prompt", "").strip(),
    "category": r.get("category", "").strip(),
    "tags": [t.strip() for t in r.get("tags", "").split(",") if t.strip()],
} for r in rows if r.get("title") and r.get("content")]

json.dump({
    "format": "prompt-architects/personal-library",
    "version": 1,
    "exported_at": "2026-09-05T00:00:00.000Z",
    "count": len(items),
    "items": items,
}, open("import.json", "w", encoding="utf-8"), indent=2)

That last filter, if r.get("title") and r.get("content"), matters more than it looks: rows missing either field get silently counted as invalid by the importer anyway, so filtering them out yourself first means the count you see in the file matches the count you actually expect to land in your library. If the spreadsheet you're converting has genuinely outgrown itself, our piece on why a prompt library spreadsheet breaks covers exactly the point where a CSV stops being the right home for this even as a one-time export format.

How Many Prompts Can You Actually Import at Once?

More than the file-size limit alone would suggest, but your plan's saved-prompt cap is almost always the real ceiling. The file itself is capped at 5 MB, checked before the browser even reads it; for plain text prompts that's comfortably several thousand items; a typical 150-word prompt with a short description and a handful of tags runs somewhere around 1 to 2 KB once it's wrapped in JSON, so a 5 MB file holds low thousands of items before size becomes the actual constraint. Size rarely blocks a real migration on its own.

What does block it is personal_library, the same per-plan cap that governs how many prompts you can save one at a time. Verified on our own pricing page today: Pro is capped at 50 saved prompts, and Advanced and Team are unlimited. Free's exact number isn't published on the pricing page as of this writing, so don't assume a figure for it. Import respects whichever cap applies exactly the way manual saving does: it fills your library up to whatever room remains, then reports the overflow as skipped for being over the limit rather than importing everything and leaving you to discover the cap later, or silently discarding items with no explanation at all.

If you're migrating a genuinely large personal collection onto a capped plan, the arithmetic is worth doing before you upload rather than after: a 300-item export against a 50-item Pro cap doesn't fail, it succeeds at exactly 50 and reports 250 skipped for being over the limit. The useful part of that behavior is what happens if you then upgrade and re-upload the same file: the 50 that already landed are recognized as duplicates and skipped again, while the previously-skipped 250 now have room and import cleanly. You don't need to curate the file down or split it by hand; re-running the identical export after upgrading is the correct way to pick up the remainder.

Does Bulk Import Detect Duplicate Prompts?

Yes, and the rule is specific enough to be worth stating exactly rather than "roughly": two items are duplicates only when their title (compared case-insensitively), content, and negative prompt all match at once. Change any single one of those three and the importer treats it as a genuinely different prompt, even with an identical title.

That check runs twice: against everything already in your private library, and against the rest of the same import batch, so uploading a file that itself contains the same prompt twice only keeps the first copy. The practical upshot for a big migration: importing the same export file a second time by accident is safe. It won't double your library, because everything in it will already read as a duplicate of what made it in the first time.

What Happens to Tags, Categories, and Negative Prompts on Import?

Each field is handled a little differently, and the differences are exactly the kind of thing that surprises someone the first time they migrate a real library rather than a test file.

  • Title is trimmed and capped at 100 characters. Anything longer gets cut, not rejected.
  • Content is required and checked against your plan's character limit (8,000 characters on most plans, up to 25,000 on the highest tiers); an item that exceeds it is skipped entirely rather than truncated, so you don't end up with a prompt silently cut off mid-instruction.
  • Description is capped at 500 characters, truncated rather than rejected.
  • Tags are capped at 10 per item; anything past the tenth tag on a single item is simply dropped, not queued or truncated onto the item some other way.
  • Negative prompt is capped at 2,000 characters, truncated rather than rejected.
  • Category must exactly match one of the built-in category ids. This is the one genuine gotcha: a custom category label you created for yourself does not survive export-and-reimport. It silently falls back to "All Categories," with no error and nothing in the import summary calling it out by name.

None of these caps are arbitrary inconveniences; they're the same limits the manual add-a-prompt form enforces, applied consistently so an imported item can't end up in a state the UI would never let you create by hand. The category behavior is the exception worth planning around specifically: if your export has custom categories you care about, budget time to re-tag those items after import rather than assuming the label traveled with the file.

What Happens to Folders and Team Sharing?

They don't travel. The export format carries exactly six fields, title, description, content, negative prompt, category, and tags, and folder membership isn't one of them. Every imported item lands in Unfiled, regardless of which folder it sat in when it was exported, and regardless of whether the original was shared with a team; import always creates the new copy as a private item under your own account.

That's a deliberate scope limit in the export format, not a bug you're hitting by accident, and it means the practical workflow for a large migration has an extra step baked in: import first, then refile into folders afterward, rather than expecting the structure to arrive intact. If you haven't built a folder habit yet, our guide to organizing 1,000+ ChatGPT prompts covers the recency tiers and folder-plus-tag approach worth setting up right after a big import lands.

Once everything is refiled, this is also the moment to fix names rather than leave whatever your old tool called things. Naming Conventions for a Team Prompt Library covers what actually belongs in a name versus a tag, which is easiest to apply while you're already touching every freshly-imported item to refile it anyway.

What Does the Import Summary Actually Tell You?

Four numbers, and reading all four matters more than glancing at the first one. After an import finishes, the confirmation reports counts across four buckets at once: imported, duplicates skipped, over-limit skipped, and invalid skipped. Each is a genuinely different outcome with a different fix, and they're easy to conflate if you only skim for the headline "Imported N" figure.

  • Imported means exactly what it says: the item is now a private prompt in your library.
  • Duplicate skipped means an item with the same title, content, and negative prompt already existed, either in your library or earlier in the same file. Nothing was lost; the existing copy is what you already have.
  • Over-limit skipped means the item was valid but your plan ran out of room before reaching it. Upgrading and re-importing the same file, as covered above, recovers these.
  • Invalid skipped is the bucket worth investigating rather than dismissing: it means the item was missing a title or content, or its content exceeded your plan's character limit. Unlike the other three, this one usually means something is actually wrong with that specific row in your source data, not just a plan constraint doing its job.

Running a small batch first is the whole reason these four numbers exist as a visible report rather than a single silent success message. Ten or twenty items from your real export tells you immediately which buckets your data is going to land in before you commit the full file, and a batch that comes back with a surprising number of invalid items is a much cheaper problem to find at twenty items than at three hundred.

What If You're Migrating a Team's Prompts, Not Just Your Own?

Plan for an extra step, because import has no concept of a team destination at all. Every imported item, regardless of what it looked like in the source file or which teammate originally wrote it, lands as a private item owned by whichever account ran the import. If the goal is a shared team library rather than one person's personal collection, importing is only step one; sharing each item to the team afterward, through the normal share control, is a separate, manual step two.

That has a real practical consequence for who should run a team migration. Whoever imports the file becomes the owner of every resulting item, at least until items are individually shared or reassigned, so a scattered "everyone imports their own prompts separately" approach produces a library that's fragmented across owners in exactly the way a real team library shouldn't be. The cleaner pattern is one person collecting everyone's prompts into a single export file first, then running one import, then working through the sharing step deliberately, rather than several people each running their own import and hoping the results converge into something coherent.

A Realistic Bulk Import Checklist

Most import surprises happen at the JSON-building step, not the upload itself.
FeatureBefore you exportBuilding the JSONAfter you import
What to checkSource has real title + content per rowformat string exact, category ids not labelsSkipped counts, then refile from Unfiled
What's lost in transitNothing yetAnything past 10 tags, over-length fieldsFolders, custom categories, team-share status
Common mistakeExporting rows with no contentUsing a display name instead of a category idAssuming a second import will update, not duplicate
Free Chrome Extension

Stop rewriting prompts. Start shipping.

Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 4.8★ on the Chrome Web Store.

Create An Account

Run a small batch first, ten or twenty items, before you commit a few hundred. The toast message after import reports imported, duplicate, over-limit, and invalid counts separately, so a small test run tells you exactly which of those four buckets your real file is going to hit before you find out the hard way on the full migration.

None of this is complicated once you've read the actual rules once. What makes bulk import feel riskier than it is tends to be the gap between what people assume ("it's just uploading a file") and what's actually true (a specific wrapper shape, a hard category-id match, folders that don't travel, an importer that only ever adds). Close that gap before you run the real migration, on a real few-hundred-item file, and the process is genuinely mechanical: build the JSON, test small, read all four numbers, refile and re-tag what needs it, and move on.

Frequently asked questions

Free Chrome Extension

Stop rewriting prompts. Start shipping.

Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 4.8★ on the Chrome Web Store.

Create An Account