Public Content API

Find and download public content for your application

Public Content API

Browse public cards, lorebooks, presets, personas, prompt guides, regex scripts, and series. Download supported content in portable formats without an SDK, account, API key, or RoleCall installation.

Base URL: https://plotlightstudios.com

Access: read-only, guest permissions. Requests do not use inference tokens.

Start here

Search any supported content type through one endpoint:

curl --fail-with-body --get \
  'https://plotlightstudios.com/api/v1/content' \
  --data-urlencode 'type=cards' \
  --data-urlencode 'q=wizard' \
  --data-urlencode 'limit=10'

Download a returned item by its UUID:

curl --fail-with-body \
  'https://plotlightstudios.com/api/v1/content/cards/CARD_UUID?format=json' \
  -o character.json

Replace CARD_UUID with an actual result. Every result includes ready-to-use downloads links. Resolve relative links against the base URL.

const downloadUrl = new URL(item.downloads.json, 'https://plotlightstudios.com');

Routes

RoutePurpose
/api/v1/content?type=cardsSearch a content pool
/api/v1/content/{type}The same search, with type in the path
/api/v1/content/{type}/{id}Download its default portable format
/api/v1/content/{type}/{id}?format=...Choose a download format
/api/v1/content/{type}/{id}/downloadEquivalent explicit download route
/api/v1/content/tagsPaginated native tag catalog

All routes support GET, HEAD, and CORS OPTIONS. Unsupported methods return 405. IDs must be UUIDs. Existing character and lorebook URLs remain supported.

Content types

typeWhat you getDownload formats
cards or charactersPublished, exportable character cardsjson, json3, backyard, png, png3
lorebooksPublished lorebooksst
presetsPublished preset editions from their public listinglegacy, nemo-wiki
personasPublished personasjson
guidesPublished, visible prompt guidesst, json
regex or regex-scriptsPublished regex scriptsst
seriesPublished collection metadataNo portable download

The first format listed is the default. type defaults to characters. Art galleries and image-generation records are excluded. Series exports currently require the signed-in application; the public API does not offer the ZIP bundle.

Native tag filtering

Clients can recreate discovery's category picker using the actual tag catalog. Each tag includes its id, slug, name, category, subcategory, description, and content applicability flags.

curl --fail-with-body \
  'https://plotlightstudios.com/api/v1/content/tags?type=cards&category=genre&limit=100'

Tag catalog arguments:

ArgumentMeaning
typecards, characters, personas, presets, or lorebooks; omit for all applicable types
categoryExact native category identifier, such as genre or species
include_after_darktrue includes adult tag labels; default false. This does not grant access to adult content
limit1-100; default 100
offset0-10000; default 0

Use the returned slugs verbatim. Slugs are not reliably derived from display names. The tag endpoint uses the same data and pagination envelope as content search.

Include and exclude together

tags requires all selected tags. exclude_tags rejects content carrying any excluded tag. Both accept up to 10 comma-separated slugs, each at most 50 characters, across native categories.

const url = new URL('/api/v1/content', 'https://plotlightstudios.com');
url.searchParams.set('type', 'cards');
url.searchParams.set('tags', selectedTags.map(tag => tag.slug).join(','));
url.searchParams.set('exclude_tags', excludedTags.map(tag => tag.slug).join(','));
url.searchParams.set('sort', 'popular');
url.searchParams.set('limit', '20');
const response = await fetch(url, { credentials: 'omit' });
if (!response.ok) throw new Error(`Search failed: ${response.status}`);
const page = await response.json();

Omit empty tag lists. Unknown included slugs return no matches; unknown excluded slugs exclude nothing. Selecting and excluding the same tag produces no matches.

Guides and regex scripts currently have no native tag assignments, so their catalogs reject tags and exclude_tags. Their search modes still work. Series supports included tags; its current discovery owner does not support tag exclusions, so that argument is rejected for series.

Search arguments

Common arguments:

ArgumentDefaultMeaning
qOmittedSearch text, up to 200 characters
modenamesField to search; supported values depend on content type below
tagsOmittedRequire all selected native tag slugs
exclude_tagsOmittedExclude any selected native tag slug, where supported
sortrecentrecent, popular, rating; uses native discovery's ordering
limit30Integer 1-100
offset0Integer 0-10000

Search modes:

ContentSupported mode values
Cardsnames, creators, tags, fandoms, genres
Lorebooksnames, creators, genres, types
Presetsnames, creators, styles, models
Personas, regex, seriesnames, creators
Guidesnames, genres (category), types (guide type)

Additional native filters:

ArgumentContentMeaning
min_ratingCardsMinimum rating, 0-5; decimals allowed
has_vnCardstrue or 1 requires visual-novel data
min_rosesLorebooks, presetsMinimum native download/rose count
min_favoritesLorebooks, presets, personas, regex, seriesMinimum favorite count
has_compendiumLorebookstrue or 1 requires compendium data
model_familiesPresetsUp to 10 comma-separated native model-family identifiers, each at most 20 characters
min_promptsPresetsMinimum prompt count, integer 0-1000
min_forksPresetsMinimum fork count

Count minimums are integers from 0 to 1000000. Boolean feature filters also accept false or 0 to remove that requirement; they do not mean 'only items without the feature'.

Combine arguments freely within a content type:

curl --fail-with-body --get \
  'https://plotlightstudios.com/api/v1/content/presets' \
  --data-urlencode 'q=roleplay' \
  --data-urlencode 'mode=names' \
  --data-urlencode 'min_prompts=5' \
  --data-urlencode 'min_favorites=10' \
  --data-urlencode 'sort=popular'

Unknown arguments, repeated arguments, unsupported modes, filters for another content type, and invalid values return 400. Parameters are case-sensitive. This prevents a typo from silently broadening your search.

Results and pagination

{
  "data": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "type": "characters",
      "name": "Forest Mage",
      "description": "A mage who guards an ancient forest.",
      "image_url": null,
      "updated_at": null,
      "creator": { "name": "Example Creator", "username": "example" },
      "tags": [],
      "detail_url": "/discovery/characters/11111111-1111-4111-8111-111111111111",
      "downloads": {
        "json": "/api/v1/content/characters/11111111-1111-4111-8111-111111111111/download?format=json"
      }
    }
  ],
  "pagination": { "limit": 20, "offset": 0, "has_more": false, "next_offset": null }
}

This is illustrative data. Actual download maps include every supported format. Aliases return the canonical type (cards returns characters). Descriptions, preview images, timestamps, and creator fields may be null or absent. Public tag fields include id, name, slug, and category.

Preserve filters and limit when requesting pagination.next_offset. Stop when it is null, not when data is empty. Native discovery can remove items after fetching a page, leaving short pages even when more results exist. At offset 10000 there may be more matches but no further page is offered. Results are live, not a database snapshot; totals are not supplied.

Portable files

Downloads return the file itself with a suggested filename in Content-Disposition. They do not return a search envelope. format is the only download argument.

  • Cards: json is Character Card V2; json3 is V3. png embeds V2 metadata in the portrait; png3 embeds V3 plus V2 compatibility metadata. backyard is Backyard/Faraday JSON. Permitted export-enabled lorebooks are merged into character_book.
  • Lorebooks: st is SillyTavern worldbook JSON.
  • Presets: legacy and nemo-wiki use the existing SillyTavern-compatible serializers. Supported prompts, sampler settings, and portable regex rules are included.
  • Personas: json contains character-style persona fields, without RoleCall runtime extensions.
  • Guides: st and json contain a SillyTavern prompt list with one guide.
  • Regex: st contains SillyTavern regex rules: one object for a single rule, an array for multiple rules. Treat regex and replacement text as untrusted data in your importer.

RoleCall-only trackers, props, loadouts, private dependencies, and account settings are not portable API payloads. A download is not a complete artwork archive. Preview URLs are image references; PNG cards include the main portrait. V3 cards may include supported sprite references that need separate fetching.

Check HTTP status before saving a response so an error JSON is not saved as a content file.

Browser and extension access

CORS permits public reads. Send credentials: 'omit'; no Authorization header is needed. Login cookies never widen public API permissions. Use a returned download URL rather than constructing one when possible.

const response = await fetch(
  new URL(item.downloads.png, 'https://plotlightstudios.com'),
  { credentials: 'omit' },
);
if (!response.ok) throw new Error(`Download failed: ${response.status}`);
const file = await response.blob();

There is no private-library connection or write API. Native guest visibility rules apply, including After Dark restrictions. Listing adult tag labels does not change content access.

Errors and responsible use

StatusMeaning
400Invalid query, format, or UUID
401 / 403Content cannot be exported to this audience
404Unknown resource, missing content, or unavailable download
429Rate limited; slow down
500 / 503Temporary server or dependency failure

Errors have an error message. Downloads recheck current publication and access rules; a previous search result does not guarantee later availability. Responses are not cached by shared CDNs.

Use Retry-After when supplied and respect exposed X-RateLimit-* headers. Rate limits are enforced independently by the search and export owners. Debounce searches, avoid parallel bulk downloads, and back off on 429. Public availability does not grant permission to republish creators' work; preserve attribution and honor withdrawals.