API
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.jsonAuthentication
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_xxxxxxxxxxxxxxxxxxxxxxxxTokens 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>"
}
]
}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
200— success400— bad request (missing fields, invalid filename, invalid JSON, file too large)401— missing or invalid bearer token403— the app's public API is disabled404— app or file not found500— server / database error
Notes
- Read endpoints are cached:
public, max-age=60, s-maxage=300. Fresh uploads may take up to ~5 min to appear via the edge cache. - App owners can disable the public API per-app at any time. Disabled apps return
403on all/api/apps/<slug>/*endpoints. - App owners can also close community submissions independently of the API. When closed,
POST /api/apps/<slug>/submitreturns an error and only the owner can use the web upload. - Submission size cap is 1MB. Direct uploads via the owner's manage page allow up to 10MB.