Sticker import API
Who this is for: developers publishing sticker packs that users can Add to Buzzio.
Canonical contract (in-repo): docs/stickers/IMPORT_API.md
Human site: sticker-api.buzzio.dev
This is not a messaging SDK and not an upload host. You keep the files. Buzzio copies WebP onto the user’s phone after they confirm.
Pack files never go to Buzzio servers. There is no POST /pack.
| Constant | Value |
|---|---|
| App id | com.ve.ghost |
| Display name | Buzzio |
| Store keyword for sticker apps | BuzzioStickerApps |
Do not use WhatsApp action names, permissions, or URL schemes.
Two publish paths
| Path | You ship | Buzzio reads |
|---|---|---|
| App | Android ContentProvider / iOS pasteboard | Sticker app on the same phone |
| Website | HTTPS contents.json + WebP on your origin |
Your URLs, then copies locally |
Sending a sticker in a chat is a separate step inside Buzzio. Import does not send messages.
Guides: Android · iOS · Web · Spec
Art rules
Portable with WhatsApp sticker packs so existing art can be reused.
| Rule | Value |
|---|---|
| Format | Stickers: WebP. Tray icon: PNG or WebP |
| Sticker size | Exactly 512 × 512 px, transparent background |
| Pack size | 3–30 stickers |
| Mix | Static or animated in one pack — never both |
| Static file | ≤ 100 KB |
| Animated file | ≤ 500 KB, frame duration ≥ 8 ms, total duration ≤ 10 s |
| Tray icon | 96 × 96 px, static, ≤ 50 KB |
| Emoji tags | Up to 3 per sticker |
| Accessibility | Optional. Static ≤ 125 chars, animated ≤ 255 chars |
| Pack name / publisher / identifier | ≤ 128 characters |
| Identifier | a-zA-Z0-9_-. only |
Recommended: 8 px white stroke around art so it reads on light and dark chat backgrounds.
Android
Permission
Buzzio defines com.ve.ghost.sticker.READ. Do not re-declare this permission in your sticker app (two apps defining the same custom permission can fail to install).
Your ContentProvider must be exported, enabled, and use:
android:readPermission="com.ve.ghost.sticker.READ"
Authority must start with your application id. Example: dev.buzzio.samplesticker.stickercontentprovider
Package visibility
<queries>
<package android:name="com.ve.ghost" />
</queries>
Open Buzzio
val intent = Intent("com.ve.ghost.intent.action.ENABLE_STICKER_PACK").apply {
putExtra("sticker_pack_id", packId)
putExtra("sticker_pack_authority", authority)
putExtra("sticker_pack_name", packName)
}
startActivityForResult(intent, 200)
| Extra | Meaning |
|---|---|
sticker_pack_id |
Pack identifier from contents.json |
sticker_pack_authority |
Your ContentProvider authority |
sticker_pack_name |
Display name |
Result: RESULT_OK if the user added the pack, otherwise RESULT_CANCELED.ActivityNotFoundException means Buzzio is not installed.
Each pack needs its own Add button. Do not add every pack in one tap.
ContentProvider paths
content://{authority}/metadata— all packscontent://{authority}/metadata/{pack_id}— one packcontent://{authority}/stickers/{pack_id}— sticker listcontent://{authority}/stickers_asset/{pack_id}/{file}—openAssetFile, WebP/PNG bytes
Column names match WhatsApp so existing sticker apps can reuse query code. Full column tables: sticker-api.buzzio.dev/android or docs/stickers/IMPORT_API.md.
Already added?
content://com.ve.ghost.provider.sticker_whitelist_check/is_whitelisted?authority={your_authority}&identifier={pack_id}
Column result: 1 added, 0 not added, null if Buzzio is too old or the query is invalid. You can only check packs your app provides. Treat a missing provider as “not added”.
iOS
- Put one pack JSON (UTF-8
Data) on the pasteboard under typedev.buzzio.third-party.sticker-pack. - Open
buzzio://stickerPack.
let data = try JSONSerialization.data(withJSONObject: pack, options: [])
UIPasteboard.general.setItems(
[["dev.buzzio.third-party.sticker-pack": data]],
options: [.expirationDate: Date().addingTimeInterval(60)]
)
UIApplication.shared.open(URL(string: "buzzio://stickerPack")!)
Declare LSApplicationQueriesSchemes → buzzio.
Pasteboard JSON
One pack per open. tray_image is PNG base64. Sticker image_data is WebP base64.
{
"identifier": "cuppy",
"name": "Cuppy",
"publisher": "Example",
"tray_image": "<base64 PNG>",
"stickers": [
{
"image_data": "<base64 WebP>",
"emojis": ["🙂"],
"accessibility_text": "A round smiling face"
}
]
}
Apple typically rejects apps whose only purpose is exporting stickers. Ship real app functionality, or use a sticker-maker flow.
Website (you host the pack)
Use this when you have a sticker site and no native sticker app. Same art spec.
Host these files
https://stickers.example.com/packs/cuppy/contents.json
https://stickers.example.com/packs/cuppy/tray.png
https://stickers.example.com/packs/cuppy/01.webp
contents.json may be either:
- One pack object (recommended — one Add button, one folder).
- Android-style wrapper with
sticker_packs. If more than one pack, pass&pack={identifier}on the Add link.
Relative tray_image_file / image_file names resolve against the directory of the manifest URL. Absolute image URLs must be https:// and the same origin as the manifest. No .. segments. Buzzio refuses http://, cross-origin redirects, and private / link-local addresses.
Serve Content-Type: application/json for the manifest and image/webp or image/png for files. CORS is not required: the Buzzio app fetches, not the browser.
Bump image_data_version when art changes so Buzzio can refresh. Pack identity on the phone: origin of the manifest + identifier.
Add to Buzzio button
<a href="https://sticker-api.buzzio.dev/import?manifest=https%3A%2F%2Fstickers.example.com%2Fpacks%2Fcuppy%2Fcontents.json">
Add to Buzzio
</a>
| Param | Required | Meaning |
|---|---|---|
manifest |
yes | https:// URL of your contents.json |
pack |
if JSON lists several packs | identifier to import |
Equivalent app URL:
buzzio://stickerPack?manifest=https://stickers.example.com/packs/cuppy/contents.json
If Buzzio is not installed, send people to the store. A website cannot query the Android whitelist provider — always show Add to Buzzio; Buzzio shows “already added” on confirm when applicable.
One-pack contents.json example:
{
"identifier": "cuppy",
"name": "Cuppy",
"publisher": "Example",
"publisher_website": "https://stickers.example.com",
"tray_image_file": "tray.png",
"image_data_version": "1",
"animated_sticker_pack": false,
"stickers": [
{
"image_file": "01.webp",
"emojis": ["🙂", "👋"],
"accessibility_text": "A round smiling face waving"
}
]
}
Sample app
Android sample: examples/sticker-app/ in the Buzzio chat repo — one placeholder pack and an Add to Buzzio button.