Start
Auth
API keys, OAuth 2.1, and which calls work with neither.
Two ways in, for two kinds of caller: an API key for scripts and agents you run yourself, OAuth for MCP clients that sign a user in.
Sign-in exists to unlock keys, MCP authorization and the watermark toggle. It is never needed to browse, to use the on-site editor, or to download what the editor draws.
API keys
Create one at /settings/api-keys. Keys start with mw_, are shown in full exactly once, and are listed afterwards by their first characters only.
Send it as either header:
curl -X POST https://memeworld.afterlume.workers.dev/api/v1/render \
-H 'x-api-key: mw_...' \
-H 'content-type: application/json' \
-d '{"templateId": 42, "captions": ["before", "after"]}'Authorization: Bearer mw_...The same key authenticates MCP. Clients that take custom headers can send x-api-key and skip the OAuth flow entirely.
A key is capped at 600 requests an hour on top of the per-endpoint limits. Delete a leaked key from the same page; it stops working immediately.
OAuth 2.1
MCP clients discover authorization from the protected-resource metadata:
https://memeworld.afterlume.workers.dev/.well-known/oauth-protected-resourcememeworld is its own authorization server. Clients register through client metadata documents (CIMD, as pinned by MCP spec 2026-07-28), send the user to /sign-in, then to /consent, and receive a token scoped to https://memeworld.afterlume.workers.dev/api/mcp.
A request carrying a bad or expired token gets an RFC 9728 challenge back — the WWW-Authenticate header is how a client learns to start the flow rather than give up.
What needs a caller
- Open:
search_templates,get_template,list_tags,get_editor_url,open_meme_editor, everyGET /api/v1/*, andPOST /api/v1/suggest. - Authorized:
suggest_memes,caption_meme,face_swap_meme,POST /api/v1/render,POST /api/v1/face-swapandGET /api/v1/credits.
An MCP request with no credentials is served anonymously rather than rejected: the open tools answer, and the two that cost money return an error explaining how to connect.
The 401
{
"code": "UNAUTHORIZED",
"message": "Send an API key as `x-api-key` or `Authorization: Bearer`. Create one at /settings/api-keys."
}