BlogGuides

A Developer's Guide to the Wikiprompt /dataset Endpoint

A precise, reference-style walkthrough of the /dataset manifest and /dataset/prompts endpoints: response shapes, every field, keyset pagination, caching, and error handling.

A Developer's Guide to the Wikiprompt /dataset Endpoint

A Developer's Guide to the Wikiprompt /dataset Endpoint

Wikiprompt is a public, curated catalog of AI prompts, covering ChatGPT, Claude, Gemini, GPT Image, Midjourney, Seedance, Veo, Kling, Nano Banana, Grok and more. Instead of scraping the live site to pull that catalog programmatically, there is now a dedicated bulk export: /dataset. This post documents it the way you'd want a third-party API documented: response shapes, field semantics, pagination mechanics, caching, and error handling, with runnable examples.

Two endpoints, one job

There are exactly two URLs you need:

  • https://www.wikiprompt.org/dataset (manifest)
  • https://www.wikiprompt.org/dataset/prompts (data)
  • The manifest is metadata about the export. The data endpoint is the export itself, paginated. Both return plain JSON, no API key, no auth header, nothing to register for.

    The manifest response

    A GET on the dataset manifest returns something shaped like this:

    {

    "total_prompts": 55000,

    "record_fields": [

    "slug", "url", "title", "description", "content",

    "category", "tags", "media", "model", "metadata",

    "author", "original_source", "created_at", "updated_at"

    ],

    "pagination": {

    "endpoint": "https://www.wikiprompt.org/dataset/prompts",

    "cursor_param": "after",

    "limit_param": "limit",

    "default_limit": 200,

    "max_limit": 500

    }

    }

    Treat total_prompts as a live, approximate count, not a fixed constant. The catalog grows daily, so pin your integration to record_fields and the pagination block rather than hardcoding the count anywhere in your code.

    The data response

    A GET on /dataset/prompts returns a page of records plus a cursor for the next page:

    {

    "count": 500,

    "records": [

    {

    "slug": "one-brick-monumental-shadow-architectural-photo",

    "url": "https://www.wikiprompt.org/one-brick-monumental-shadow-architectural-photo",

    "title": "One Brick: Monumental Shadow Architectural Photo",

    "description": "A single brick photographed to cast a monumental architectural shadow.",

    "content": "the actual prompt text goes here, verbatim",

    "category": "creative",

    "tags": ["photography", "architecture", "shadow-play"],

    "media": ["https://www.wikiprompt.org/media/tw/..."],

    "model": "Midjourney",

    "metadata": {

    "media_type": "image",

    "aspect_ratio": "16:9",

    "style": ["minimalist", "high-contrast"],

    "assessment": { "creativity": 4, "usefulness": 3 }

    },

    "author": "some_handle",

    "original_source": "https://twitter.com/some_handle/status/...",

    "created_at": "2026-03-11T00:00:00Z",

    "updated_at": "2026-03-11T00:00:00Z"

    }

    ],

    "next": "https://www.wikiprompt.org/dataset/prompts?after=<cursor>&limit=500"

    }

    Field reference

    Every record carries the same fourteen fields. The ones worth calling out:

  • `slug` / `url`: slug is the stable identifier; url is the canonical page, useful if you want to link back or re-crawl a single record later.
  • `content`: the actual prompt text. This is the field most integrations care about; everything else is metadata around it.
  • `category`: one of creative, marketing, personal, productivity, coding, education, business, research, other.
  • `media`: an array of image/video URLs when the prompt produced visual output. Empty for text-only prompts.
  • `model`: the AI model the prompt targets or was generated with, as a free-text string ("Midjourney", "GPT-4o", "Veo", etc).
  • `metadata`: a structured object with media_type, aspect_ratio, style, and an assessment block scoring quality dimensions like creativity and usefulness. This is null for plain text prompts that never carried image/video assessment.
  • `original_source`: the link to the original post the prompt came from. See the attribution note below, this field matters if you reuse the data downstream.
  • `created_at` / `updated_at`: ISO 8601 timestamps. updated_at moves if a record gets edited or re-enriched after the fact.
  • Pagination mechanics

    The endpoint uses keyset pagination, not page numbers. Two params control it:

  • limit: how many records per page, default 200, max 500.
  • after: an opaque cursor, echoed back to you in each response's next URL.
  • The contract is simple: call the endpoint, read next, call next verbatim, repeat until next is null. Do not construct the after value yourself; treat it as an opaque token.

    curl "https://www.wikiprompt.org/dataset/prompts?limit=500"

    A full crawl in Python looks like this:

    import requests

    url = "https://www.wikiprompt.org/dataset/prompts?limit=500"

    records = []

    while url:

    resp = requests.get(url, timeout=30)

    resp.raise_for_status()

    payload = resp.json()

    records.extend(payload["records"])

    url = payload["next"]

    print(f"pulled {len(records)} prompts")

    At 500 per page and 55,000+ records, that is roughly 110 requests for a full sync, or far fewer for an incremental one if you additionally filter client-side on updated_at.

    Caching and CORS

    Both endpoints are edge-cached, so repeated requests for the same page (same after value) are cheap and fast on our side, and fast for you. Access-Control-Allow-Origin: * is set on every response, so you can call this directly from browser JavaScript with fetch(), no proxy needed. There is no rate limit tied to an API key because there is no API key; be a reasonable citizen and cache the manifest locally instead of polling it on every request.

    Error handling

    Under load, the endpoint can return 503 with a Retry-After header (seconds to wait before trying again). Respect it:

    import time, requests

    def get_with_retry(url):

    while True:

    resp = requests.get(url, timeout=30)

    if resp.status_code == 503:

    wait = int(resp.headers.get("Retry-After", "5"))

    time.sleep(wait)

    continue

    resp.raise_for_status()

    return resp.json()

    Any other non-200 is worth logging and stopping on rather than retrying blindly, a malformed after cursor should not happen if you're only ever following next, but defensive code should not assume that forever.

    Attribution

    The prompts in this dataset are aggregated from public posts by their original authors. Wikiprompt is the aggregator, not the rights holder. If you build something with this data, cite wikiprompt.org and, per record, the original_source field pointing back to the original post. There's no formal license attached beyond that: attribute the site and attribute the author.

    Worth trying

    Three records to sanity-check your parser against once you've got a page pulled: a data physicalization image prompt, a monumental shadow architectural photo, and a nomadic traveler character design. All three round-trip cleanly through content, media, and metadata.

    If a bulk export is more than you need, right now, two lighter-weight options exist: the search API for single queries, and the MCP server if you're wiring this into an agent rather than a script. Both sit on top of the same underlying catalog as /dataset, so nothing here is a dead end if you start smaller and grow into the bulk export later.

    Tags
    dataset·api·developer-guide·pagination·open-data·reference