Archived. This is the first version of the API docs, kept for reference. The current docs live at /docs/api.

API v1 (archived)

Read every app, its files, and recent news without authentication. Submit files to apps with a personal token.

Quick start

All endpoints live under https://black.wiki/api. Responses are JSON, CORS is open (Access-Control-Allow-Origin: *), and read endpoints are cached for ~60s.

# list apps curl https://black.wiki/api/apps # fetch a single file curl https://black.wiki/api/apps/dubzly/data/some-file.json

Authentication

Only the submission endpoint requires authentication. Generate a personal token at /account/tokens (sign in first), then send it as a bearer token:

Authorization: Bearer bwk_xxxxxxxxxxxxxxxxxxxxxxxx

Tokens are shown once at creation — copy and store immediately. They can be revoked at any time from the same page.

Read endpoints

GET/api/apps

List all published apps with the public API enabled.

Query params: q (filter by name), limit (default 50, max 100), offset.

curl https://black.wiki/api/apps?limit=10 # response { "total": 12, "limit": 10, "offset": 0, "apps": [ { "slug": "dubzly", "name": "Dubzly", "summary": "Anime Sub to Sub Chrome Extension", "homepage_url": "...", "repo_url": "...", "updated_at": "...", "url": "https://black.wiki/api/apps/dubzly", "page_url": "https://black.wiki/directory/apps/dubzly" } ] }

GET/api/apps/<slug>

Single app metadata + owner + cross-links.

curl https://black.wiki/api/apps/dubzly { "slug": "dubzly", "name": "Dubzly", "summary": "...", "description": "...", "homepage_url": "...", "repo_url": "...", "owner": { "username": "techish", "display_name": null, "profile_url": "https://black.wiki/u/techish" }, "created_at": "...", "updated_at": "...", "files_url": "https://black.wiki/api/apps/dubzly/files", "page_url": "https://black.wiki/directory/apps/dubzly" }

GET/api/apps/<slug>/files

Paged list of all files for an app.

Query params: q (search filename), letter (single a-z or #), sort = name | size | updated, dir = asc | desc, limit (default 100, max 500), offset.

curl 'https://black.wiki/api/apps/dubzly/files?letter=a&limit=20' { "app": { "slug": "dubzly" }, "total": 1, "limit": 20, "offset": 0, "files": [ { "filename": "anime-dub-preset-a-replica-...json", "size_bytes": 814, "content_type": "application/json", "created_at": "...", "updated_at": "...", "url": "https://black.wiki/api/apps/dubzly/data/anime-dub-preset-a-replica-...json" } ] }

GET/api/apps/<slug>/data/<filename>

The raw contents of a single uploaded JSON file. Served with Content-Type: application/json.

curl https://black.wiki/api/apps/dubzly/data/anime-dub-preset-a-replica-never-dreams-2026-05-20.json { "format": "anime-dub-preset", "version": 1, "name": "a-replica-never-dreams", ... }

GET/api/news

Recent black.wiki news posts.

curl https://black.wiki/api/news?limit=5 { "total": N, "limit": 5, "offset": 0, "posts": [ { "slug": "...", "title": "...", "excerpt": "...", "body": "...", "published_at": "...", "updated_at": "...", "url": "https://black.wiki/news/<slug>" } ] }

GET/api/homage

Verified registry ("Paying Homage") of people behind work on the platform. Featured-pinned, then verified, then alphabetical. Supports q, category, letter, limit, offset.

curl 'https://black.wiki/api/homage?limit=10&category=musicians' { "total": N, "entries": [ { "slug": "...", "name": "...", "summary": "...", "category": "musicians", "profile_image_url": "...", "verified": true, "member_number": 1001, "member_since": "2026-06-01", "featured": false, "url": "https://black.wiki/homage/<slug>" } ] }

GET/api/homage/<slug>

Full homage entry, including links and verification info.

curl https://black.wiki/api/homage/jane-doe

GET/api/homage/categories

List of categories used to filter homage entries.

curl https://black.wiki/api/homage/categories

Jobs

Roles posted at black.wiki. Both open and filledare publicly readable; archived are admin-only.

GET/api/jobs

List jobs. Optional status=open|filled.

curl https://black.wiki/api/jobs { "jobs": [ { "slug": "...", "title": "...", "summary": "...", "compensation": "$250 / month", "time_commitment": "~4 hours per week", "location": "Remote", "employment_type": "contract-1099", "status": "open", "url": "https://black.wiki/jobs/<slug>" } ] }

GET/api/jobs/<slug>

Full job posting with description and apply details.

curl https://black.wiki/api/jobs/community-content-moderator

Polls

Daily community polls — open to anyone, no login required. Vote submissions go through a moderation pipeline (wordlist + heuristics + Claude on borderline cases); confirmed abuse auto-blocks the IP. A signed cookie is set on the first request to dedupe future votes.

GET/api/polls

Open and closed polls, most recent first.

curl https://black.wiki/api/polls?status=open { "polls": [ { "slug": "...", "question": "...", "status": "open", "daily_for": "2026-06-02", "url": "https://black.wiki/polls/<slug>", "api_url": "https://black.wiki/api/polls/<slug>" } ] }

GET/api/polls/<slug>

Poll detail with options and aggregate results. Results are safe to show before voting (no per-voter info exposed).

curl https://black.wiki/api/polls/which-app { "slug": "which-app", "question": "...", "options": [{ "id": "...", "label": "...", "sort_order": 0 }], "results": [{ "option_id": "...", "label": "...", "votes": 7, "pct": 0.41 }], "total_votes": 17, "vote_url": "https://black.wiki/api/polls/which-app/vote" }

POST/api/polls/<slug>/vote

Cast a vote. Dedup'd per browser (signed cookie + IP). Optional comment is moderated; the vote still records even if the comment is dropped.

curl -X POST https://black.wiki/api/polls/which-app/vote \ -H 'content-type: application/json' \ -d '{"option_id":"...","comment":"Optional reasoning"}' { "ok": true, "duplicate": false, "comment_status": "approved" | "pending" | "rejected" | "none" }

Black Sayings

Community-curated cultural phrases. Submissions go through the same moderation pipeline as poll comments — abusive content is auto-rejected and the IP is blocked.

GET/api/sayings

Published sayings. Supports q, category, region, limit, offset.

curl https://black.wiki/api/sayings?category=kitchen { "total": N, "sayings": [ { "slug": "...", "text": "Shut the door and stop letting all the air outside", "meaning": "...", "attribution": "Grandma Pearl", "region": "South", "category": "kitchen", "image_url": "...", "url": "https://black.wiki/sayings/<slug>" } ] }

GET/api/sayings/<slug>

Full saying detail, including meaning and attribution.

curl https://black.wiki/api/sayings/shut-the-door

GET/api/sayings/categories

List of categories used to filter sayings.

curl https://black.wiki/api/sayings/categories

GET/api/sayings/random

One random published saying — handy for widgets / embeds.

curl https://black.wiki/api/sayings/random

POST/api/sayings/submit

Submit a saying for admin review. Required: text. Optional: meaning, attribution, region, category, submitter_name, submitter_email. Returns {"status":"pending"|"spam"}.

curl -X POST https://black.wiki/api/sayings/submit \ -H 'content-type: application/json' \ -d '{"text":"You gon stop going in and out of this house","meaning":"...","region":"South"}'

Submit a file (write)

Submitted files land in the app owner's pending queue. The owner approves or rejects from their manage page. Approved files become public at /api/apps/<slug>/data/<filename>.

POST/api/apps/<slug>/submit

Requires Authorization: Bearer bwk_.... Body must be JSON with filename (must end in .json), content (object or JSON-encoded string), and optional message. Max 1MB.

curl -X POST https://black.wiki/api/apps/dubzly/submit \ -H "Authorization: Bearer bwk_XXXXXXXXXXXXXXXXXXXX" \ -H "Content-Type: application/json" \ -d '{ "filename": "dub-preset-my-anime-2026.json", "content": { "format": "anime-dub-preset", "version": 1, "name": "..." }, "message": "Generated by Dubzly" }' # response { "ok": true, "submission_id": "...", "message": "Submitted for review..." }

Browser extension example

For a chrome/firefox extension that posts on behalf of the user (e.g. a “Share to community” button):

// background.js or popup.js const TOKEN = (await chrome.storage.local.get("blackwikiToken")).blackwikiToken; async function shareToCommunity(filename, content, message) { const res = await fetch( "https://black.wiki/api/apps/dubzly/submit", { method: "POST", headers: { "Authorization": `Bearer ${TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ filename, content, message }), }, ); const data = await res.json(); if (!data.ok) throw new Error(data.error); return data.submission_id; }

Tell users to grab a token from https://black.wiki/account/tokens and paste it into your extension's settings.

Status codes

Notes