1. Create your first paint
- Open Paint studio and choose a preset. You can edit and preview without signing in.
- Set a preview name. Add colors, gradients, or an image you own.
- Use Effects to adjust glow, outline, weight, shadows, and depth. Check the actual chat-size preview, not just the zoomed view.
- Open Finish, name the cosmetic, confirm artwork rights, and submit while signed in.
- Track the decision in My collection. After approval, equip it there or in Discover.
Approval publishes a design; equipping assigns it to your linked identities. Neither step modifies your Twitch, Kick, or YouTube display name.
2. Layers, gradients, and GIFs
Use up to six layers. The first layer is on top. New layers are added underneath. A fully opaque solid or image layer can cover everything below it; lower its opacity or move it down to blend.
- Linear: color along an angle. Radial: color outward from a center. Conic: color around a center. Solid: a single RGBA color.
- Each gradient accepts 2–12 stops. Set positions from 0–100%, and use #RRGGBBAA or the alpha slider for transparency.
- Scale changes the fill canvas, not the name's font size. Position aligns that canvas. Gradient repeat and canvas tiling are separate controls.
- Image: choose a GIF, WebP, or PNG up to 2 MB with a canvas no larger than 2048 × 2048. Preview is local; upload happens when you submit.
Attached-file buttons show images across all layers. Moving, duplicating, or temporarily changing a layer's type keeps its attached image in this editing session. Switch back to Image to restore it. Removing a layer removes it from the recipe; Undo restores it. Image animation is independent of the gradient animation selector.
Save draft and Export JSON preserve recipe settings, not local image bytes. Reattach files after a reload or import. Presets replace the design; use Undo if you changed one accidentally. A 7TV import converts supported settings only: remote images must be reattached, and entitlements, flairs, and artwork rights do not transfer.
3. Preview at the size your chat uses
Set Chat font size to your overlay's font size (the built-in OBS overlay uses 18px). Inspection zoom magnifies that same render, including its shadows and outline, rather than making a different large-font paint. The lower preview is shown at actual size.
Glow, outline, and shadow offsets are pixel values. Increasing them can overwhelm small text. Check readability on both light and dark backdrops. A different client font, letter spacing, or font size can still change the result; integrations must match the renderer and typography.
Up to eight extra shadows can be stacked. Depth is a lightweight text extrusion, not a 3D scene. Pause motion stops CSS animation and replaces animated image fills with the fallback palette; it does not freeze a GIF frame. Reduced-motion visitors get static fallback fills automatically.
4. Sign in and link accounts
Sign in with an enabled provider, then link the others from Connected accounts while still signed in. Twitch and Kick use numeric account IDs; YouTube uses a channel ID. Renaming a platform account does not change the identity key.
OAuth verifies identity on the provider's own page. Nameflare does not ask for passwords and does not retain provider access tokens. Kick requests user:read; YouTube requests read-only channel access, so a YouTube channel is required. Twitch does not request chat-posting permissions.
One identity per provider can be linked to an account. An identity already linked elsewhere cannot be silently merged. Sign out to access that account. Unlinking, merging, account deletion, and data export are not implemented yet. Local demo accounts are isolated samples, not real OAuth logins.
If a provider says “setup required,” the operator has not supplied its client credentials. Register exact callbacks under the canonical HTTPS origin: /auth/twitch/callback
/auth/kick/callback
/auth/youtube/callback
5. Publication and moderation
Pending designs and their images are private to the creator and reviewers. Reviewers check artwork permission, harmful content, readability, and flashing motion. A reviewer cannot approve their own submission. Rejection includes feedback; edit a copy to make a new submission.
Approved designs appear in the public API. Revocation removes them and clears equipped assignments. Clients must revalidate within the 15-second cache window. Editing a copy does not inherit approval.
The owner role is bootstrapped by a configured numeric Twitch ID—not a username or the first signup. Only the owner can assign moderators, by numeric Twitch ID after that account signs in. Nameflare reviewer roles are separate from a channel's Twitch moderator status. Decisions and role changes are audited.
6. Add chat to OBS
- Open Integrations & API, enter a public Twitch channel login, and copy the OBS source URL.
- In OBS, add a Browser Source, paste that URL, and choose your canvas dimensions (for example 700 × 900).
- The overlay joins public Twitch chat anonymously. No streamer password or OAuth token belongs in the source URL.
- Send a chat message from an account with an approved, equipped paint. The overlay resolves its immutable Twitch user ID.
Sample overlay uses labeled test messages. The direct Twitch overlay handles reconnects and message deletion. Kick and YouTube need authorized server-side chat connectors; these are not supplied. The Node host has a private relay, but the Cloudflare port does not yet implement relay streaming. Keep relay ingest tokens server-side and room URLs private.
Banechat's existing site is a separate project. Direct Nameflare integration and its redesign require that project's source; links alone do not install cosmetics into it. Stock Chatterino also requires a native adapter, which is not shipped.
7. Integrate the public API
Approved reads require no key and allow CORS. Discover the canonical API at /api/config. Do not key cosmetics by display names, and never render imported recipe data as HTML or arbitrary CSS.
GET /api/v1/cosmetics?limit=60&offset=0
GET /api/v1/cosmetics/:id
GET /api/v1/users/twitch/:numeric_id
GET /api/v1/users/kick/:numeric_id
GET /api/v1/users/youtube/:channel_id
POST /api/v1/resolve
{"provider":"twitch","ids":["123","456"]}Batch resolve accepts at most 100 string IDs. Unknown identities are omitted from the batch result; a single unknown identity returns 404. A linked user without an equipped paint has cosmetic: null. Fall back to the platform's normal name when resolution fails.
Browser clients can use the shared renderer and effect stylesheet. Apply a returned cosmetic to a text-only name element and pass the canonical service origin for textures. Keep authoritative text intact, respect reduced motion, and revalidate instead of retaining a revoked paint indefinitely. Native clients need their own safe implementation of the bounded recipe format.
Never put a session cookie, OAuth secret, CSRF token, or relay ingest token in public client code. Private creator/moderation writes require a signed-in same-origin session and CSRF token.
8. Operator setup: Cloudflare and OAuth
The Cloudflare target uses Workers for API/OAuth, D1 for accounts and recipes, R2 for private image objects, and Workers assets for this site. The local Node/SQLite app remains available for development. Configuration alone is not a public deployment.
- Choose the Cloudflare account and canonical HTTPS hostname you control. Create a dedicated D1 database and private R2 bucket; never expose the bucket directly.
- Apply the database migration and configure the resource bindings, canonical origin, numeric owner Twitch ID, and actual public source repository.
- Register Twitch, Kick, and Google OAuth apps. Enable YouTube Data API v3, configure the consent screen/test users, and complete any verification required by Google.
- Enter client secrets using Cloudflare's secret store. Never put them in this site, a repository, or a screenshot.
- Deploy only after reviewing costs and domain ownership. Test new login, account linking, cancellation, expired state, owner bootstrap, moderation, and revoked textures on the live HTTPS origin.
The deployment runbook is in the corresponding source bundle. Public launch still needs upload decoding/frame limits, abuse reporting, privacy procedures, backups, and monitoring. Header validation is not malware scanning. No live login or internet deployment is implied by local test results.
9. Troubleshooting
My GIF disappeared
Check attached-file buttons. Select its layer, switch the type back to Image, and check opacity/order. An opaque upper layer can hide it without deleting the file. After a reload or JSON import, reattach the original file. Pause or reduced-motion mode intentionally uses a static gradient fallback.
My preview looks different in chat
Match the chat font size and font family. Inspection zoom is not the export size. Check that the client supports all recipe fields and has loaded the shared effect stylesheet. Missing/pending images are private; only approved assets are public.
My equipped paint does not appear
Verify the correct platform account is linked, the paint is approved and equipped, and the integration uses the official API and immutable IDs. Wait up to 15 seconds for revalidation. Banechat and stock Chatterino do not automatically gain support merely because a paint is equipped.
OAuth returns an error
Check the exact callback hostname/path and client credentials. Restart after cancellation, expiry, switching accounts during login, or clearing cookies. YouTube needs a channel and any required test-user access. Do not share callback URLs containing authorization codes.
Submission was blocked
Sign in, confirm artwork rights, fill every image slot, and fix invalid numeric/hex fields. Limits are 10 pending submissions, 50 uploaded textures per account, six layers, eight extra shadows, and 12 gradient stops per layer.